1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-01 21:35:40 +02:00

Bug 415702 - Invalid thread access in IncludeCreator.findContribution

method
This commit is contained in:
Sergey Prigogin 2013-08-22 09:43:51 -07:00
parent 59b8242268
commit 80ca2e52aa
4 changed files with 34 additions and 58 deletions

View file

@ -10,9 +10,7 @@
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.ui.editor; package org.eclipse.cdt.internal.ui.editor;
import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.List;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.IStatus;
@ -28,7 +26,6 @@ import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Shell;
import org.eclipse.text.edits.MalformedTreeException; import org.eclipse.text.edits.MalformedTreeException;
import org.eclipse.text.edits.MultiTextEdit; import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.text.edits.TextEdit;
import org.eclipse.text.undo.DocumentUndoManagerRegistry; import org.eclipse.text.undo.DocumentUndoManagerRegistry;
import org.eclipse.text.undo.IDocumentUndoManager; import org.eclipse.text.undo.IDocumentUndoManager;
import org.eclipse.ui.IEditorInput; import org.eclipse.ui.IEditorInput;
@ -102,7 +99,7 @@ public class AddIncludeAction extends TextEditorAction {
} }
final String lineDelimiter = getLineDelimiter(editor); final String lineDelimiter = getLineDelimiter(editor);
final List<TextEdit> edits = new ArrayList<TextEdit>(); final MultiTextEdit[] holder = new MultiTextEdit[1];
SharedASTJob job = new SharedASTJob(CEditorMessages.AddInclude_action, tu) { SharedASTJob job = new SharedASTJob(CEditorMessages.AddInclude_action, tu) {
@Override @Override
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException { public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
@ -111,7 +108,7 @@ public class AddIncludeAction extends TextEditorAction {
try { try {
index.acquireReadLock(); index.acquireReadLock();
IncludeCreator creator = new IncludeCreator(tu, index, lineDelimiter, fAmbiguityResolver); IncludeCreator creator = new IncludeCreator(tu, index, lineDelimiter, fAmbiguityResolver);
edits.addAll(creator.createInclude(ast, (ITextSelection) selection)); holder[0] = creator.createInclude(ast, (ITextSelection) selection);
return Status.OK_STATUS; return Status.OK_STATUS;
} catch (InterruptedException e) { } catch (InterruptedException e) {
return Status.CANCEL_STATUS; return Status.CANCEL_STATUS;
@ -122,10 +119,9 @@ public class AddIncludeAction extends TextEditorAction {
}; };
IStatus status = BusyCursorJobRunner.execute(job); IStatus status = BusyCursorJobRunner.execute(job);
if (status.isOK()) { if (status.isOK()) {
if (!edits.isEmpty()) { MultiTextEdit edit = holder[0];
if (edit.hasChildren()) {
// Apply text edits. // Apply text edits.
MultiTextEdit edit = new MultiTextEdit();
edit.addChildren(edits.toArray(new TextEdit[edits.size()]));
IEditorInput editorInput = editor.getEditorInput(); IEditorInput editorInput = editor.getEditorInput();
IDocument document = editor.getDocumentProvider().getDocument(editorInput); IDocument document = editor.getDocumentProvider().getDocument(editorInput);
IDocumentUndoManager manager= DocumentUndoManagerRegistry.getDocumentUndoManager(document); IDocumentUndoManager manager= DocumentUndoManagerRegistry.getDocumentUndoManager(document);
@ -175,6 +171,7 @@ public class AddIncludeAction extends TextEditorAction {
/** /**
* Returns the translation unit of the given editor. * Returns the translation unit of the given editor.
*
* @param editor The editor. * @param editor The editor.
* @return The translation unit. * @return The translation unit.
*/ */

View file

@ -16,7 +16,6 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
import static org.eclipse.cdt.core.index.IndexLocationFactory.getAbsolutePath; import static org.eclipse.cdt.core.index.IndexLocationFactory.getAbsolutePath;
import static org.eclipse.cdt.internal.ui.refactoring.includes.IncludeUtil.isContainedInRegion; import static org.eclipse.cdt.internal.ui.refactoring.includes.IncludeUtil.isContainedInRegion;
import java.lang.reflect.InvocationTargetException;
import java.net.URI; import java.net.URI;
import java.util.ArrayDeque; import java.util.ArrayDeque;
import java.util.ArrayList; import java.util.ArrayList;
@ -32,16 +31,13 @@ import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.content.IContentType; import org.eclipse.core.runtime.content.IContentType;
import org.eclipse.jface.operation.IRunnableWithProgress;
import org.eclipse.jface.text.IRegion; import org.eclipse.jface.text.IRegion;
import org.eclipse.jface.text.ITextSelection; import org.eclipse.jface.text.ITextSelection;
import org.eclipse.text.edits.InsertEdit; import org.eclipse.text.edits.InsertEdit;
import org.eclipse.text.edits.TextEdit; import org.eclipse.text.edits.MultiTextEdit;
import org.eclipse.ui.PlatformUI;
import com.ibm.icu.text.Collator; import com.ibm.icu.text.Collator;
@ -111,13 +107,14 @@ public class IncludeCreator {
fContext = new IncludeCreationContext(tu, index); fContext = new IncludeCreationContext(tu, index);
} }
public List<TextEdit> createInclude(IASTTranslationUnit ast, ITextSelection selection) public MultiTextEdit createInclude(IASTTranslationUnit ast, ITextSelection selection)
throws CoreException { throws CoreException {
MultiTextEdit rootEdit = new MultiTextEdit();
ITranslationUnit tu = fContext.getTranslationUnit(); ITranslationUnit tu = fContext.getTranslationUnit();
IASTNodeSelector selector = ast.getNodeSelector(tu.getLocation().toOSString()); IASTNodeSelector selector = ast.getNodeSelector(tu.getLocation().toOSString());
IASTName name = selector.findEnclosingName(selection.getOffset(), selection.getLength()); IASTName name = selector.findEnclosingName(selection.getOffset(), selection.getLength());
if (name == null) { if (name == null) {
return Collections.emptyList(); return rootEdit;
} }
char[] nameChars = name.toCharArray(); char[] nameChars = name.toCharArray();
String lookupName = new String(nameChars); String lookupName = new String(nameChars);
@ -132,7 +129,7 @@ public class IncludeCreator {
} }
} }
if (nameChars.length == 0) { if (nameChars.length == 0) {
return Collections.emptyList(); return rootEdit;
} }
final Map<String, IncludeCandidate> candidatesMap= new HashMap<String, IncludeCandidate>(); final Map<String, IncludeCandidate> candidatesMap= new HashMap<String, IncludeCandidate>();
@ -187,7 +184,7 @@ public class IncludeCreator {
if (candidates.size() > 1) { if (candidates.size() > 1) {
IncludeCandidate candidate = fAmbiguityResolver.selectElement(candidates); IncludeCandidate candidate = fAmbiguityResolver.selectElement(candidates);
if (candidate == null) if (candidate == null)
return Collections.emptyList(); return rootEdit;
candidates.clear(); candidates.clear();
candidates.add(candidate); candidates.add(candidate);
} }
@ -206,7 +203,7 @@ public class IncludeCreator {
} }
} catch (CoreException e) { } catch (CoreException e) {
CUIPlugin.log(e); CUIPlugin.log(e);
return Collections.emptyList(); return rootEdit;
} }
if (requiredIncludes.isEmpty() && !lookupName.isEmpty()) { if (requiredIncludes.isEmpty() && !lookupName.isEmpty()) {
@ -226,10 +223,10 @@ public class IncludeCreator {
} }
} }
return createEdits(requiredIncludes, usingDeclarations, ast, selection); return createEdit(requiredIncludes, usingDeclarations, ast, selection);
} }
private List<TextEdit> createEdits(List<IncludeInfo> includes, private MultiTextEdit createEdit(List<IncludeInfo> includes,
List<UsingDeclaration> usingDeclarations, IASTTranslationUnit ast, List<UsingDeclaration> usingDeclarations, IASTTranslationUnit ast,
ITextSelection selection) { ITextSelection selection) {
NodeCommentMap commentedNodeMap = ASTCommenter.getCommentedNodeMap(ast); NodeCommentMap commentedNodeMap = ASTCommenter.getCommentedNodeMap(ast);
@ -239,7 +236,7 @@ public class IncludeCreator {
IncludePreferences preferences = fContext.getPreferences(); IncludePreferences preferences = fContext.getPreferences();
List<TextEdit> edits = new ArrayList<TextEdit>(); MultiTextEdit rootEdit = new MultiTextEdit();
IASTPreprocessorIncludeStatement[] existingIncludes = ast.getIncludeDirectives(); IASTPreprocessorIncludeStatement[] existingIncludes = ast.getIncludeDirectives();
fContext.addHeadersIncludedPreviously(existingIncludes); fContext.addHeadersIncludedPreviously(existingIncludes);
@ -294,7 +291,7 @@ public class IncludeCreator {
IASTNode previousNode = previousInclude.getExistingInclude(); IASTNode previousNode = previousInclude.getExistingInclude();
if (previousNode != null) { if (previousNode != null) {
offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode); offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode);
flushEditBuffer(offset, text, edits); flushEditBuffer(offset, text, rootEdit);
if (contents[offset - 1] != '\n') if (contents[offset - 1] != '\n')
text.append(fLineDelimiter); text.append(fLineDelimiter);
} }
@ -308,11 +305,11 @@ public class IncludeCreator {
include.getStyle().isBlankLineNeededAfter(previousInclude.getStyle(), preferences.includeStyles)) { include.getStyle().isBlankLineNeededAfter(previousInclude.getStyle(), preferences.includeStyles)) {
text.append(fLineDelimiter); text.append(fLineDelimiter);
} }
flushEditBuffer(offset, text, edits); flushEditBuffer(offset, text, rootEdit);
} }
previousInclude = include; previousInclude = include;
} }
flushEditBuffer(offset, text, edits); flushEditBuffer(offset, text, rootEdit);
List<UsingDeclaration> mergedUsingDeclarations = getUsingDeclarations(ast); List<UsingDeclaration> mergedUsingDeclarations = getUsingDeclarations(ast);
for (UsingDeclaration usingDeclaration : mergedUsingDeclarations) { for (UsingDeclaration usingDeclaration : mergedUsingDeclarations) {
@ -324,7 +321,7 @@ public class IncludeCreator {
} }
if (usingDeclarations.isEmpty()) if (usingDeclarations.isEmpty())
return edits; return rootEdit;
List<UsingDeclaration> temp = null; List<UsingDeclaration> temp = null;
for (Iterator<UsingDeclaration> iter = mergedUsingDeclarations.iterator(); iter.hasNext();) { for (Iterator<UsingDeclaration> iter = mergedUsingDeclarations.iterator(); iter.hasNext();) {
@ -367,7 +364,7 @@ public class IncludeCreator {
IASTNode previousNode = previousUsing.existingDeclaration; IASTNode previousNode = previousUsing.existingDeclaration;
if (previousNode != null) { if (previousNode != null) {
offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode); offset = ASTNodes.skipToNextLineAfterNode(contents, previousNode);
flushEditBuffer(offset, text, edits); flushEditBuffer(offset, text, rootEdit);
if (contents[offset - 1] != '\n') if (contents[offset - 1] != '\n')
text.append(fLineDelimiter); text.append(fLineDelimiter);
} }
@ -375,13 +372,13 @@ public class IncludeCreator {
text.append(using.composeDirective()); text.append(using.composeDirective());
text.append(fLineDelimiter); text.append(fLineDelimiter);
} else { } else {
flushEditBuffer(offset, text, edits); flushEditBuffer(offset, text, rootEdit);
} }
previousUsing = using; previousUsing = using;
} }
flushEditBuffer(offset, text, edits); flushEditBuffer(offset, text, rootEdit);
return edits; return rootEdit;
} }
private List<UsingDeclaration> getUsingDeclarations(IASTTranslationUnit ast) { private List<UsingDeclaration> getUsingDeclarations(IASTTranslationUnit ast) {
@ -395,9 +392,9 @@ public class IncludeCreator {
return usingDeclarations; return usingDeclarations;
} }
private void flushEditBuffer(int offset, StringBuilder text, List<TextEdit> edits) { private void flushEditBuffer(int offset, StringBuilder text, MultiTextEdit edit) {
if (text.length() != 0) { if (text.length() != 0) {
edits.add(new InsertEdit(offset, text.toString())); edit.addChild(new InsertEdit(offset, text.toString()));
text.delete(0, text.length()); text.delete(0, text.length());
} }
} }
@ -570,33 +567,19 @@ public class IncludeCreator {
} }
private IFunctionSummary findContribution(final String name) throws CoreException { private IFunctionSummary findContribution(final String name) throws CoreException {
final IFunctionSummary[] fs = new IFunctionSummary[1]; ICHelpInvocationContext context = new ICHelpInvocationContext() {
IRunnableWithProgress op = new IRunnableWithProgress() {
@Override @Override
public void run(IProgressMonitor monitor) throws InvocationTargetException, InterruptedException { public IProject getProject() {
ICHelpInvocationContext context = new ICHelpInvocationContext() { return fContext.getProject();
@Override }
public IProject getProject() {
return fContext.getProject();
}
@Override @Override
public ITranslationUnit getTranslationUnit() { public ITranslationUnit getTranslationUnit() {
return fContext.getTranslationUnit(); return fContext.getTranslationUnit();
}
};
fs[0] = CHelpProviderManager.getDefault().getFunctionInfo(context, name);
} }
}; };
try {
PlatformUI.getWorkbench().getProgressService().busyCursorWhile(op); return CHelpProviderManager.getDefault().getFunctionInfo(context, name);
} catch (InvocationTargetException e) {
throw new CoreException(CUIPlugin.createErrorStatus(Messages.AddInclude_help_provider_error, e));
} catch (InterruptedException e) {
// Do nothing. Operation has been canceled.
}
return fs[0];
} }
/** /**

View file

@ -13,8 +13,6 @@ package org.eclipse.cdt.internal.ui.refactoring.includes;
import org.eclipse.osgi.util.NLS; import org.eclipse.osgi.util.NLS;
public final class Messages extends NLS { public final class Messages extends NLS {
public static String AddInclude_help_provider_error;
public static String GCCHeaderSubstitutionMaps_c_map; public static String GCCHeaderSubstitutionMaps_c_map;
public static String GCCHeaderSubstitutionMaps_cpp_map; public static String GCCHeaderSubstitutionMaps_cpp_map;

View file

@ -9,7 +9,5 @@
# Sergey Prigogin (Google) - initial API and implementation # Sergey Prigogin (Google) - initial API and implementation
############################################################################### ###############################################################################
AddInclude_help_provider_error=Help provider error
GCCHeaderSubstitutionMaps_c_map=GCC C Header Substitution GCCHeaderSubstitutionMaps_c_map=GCC C Header Substitution
GCCHeaderSubstitutionMaps_cpp_map=GCC C++ Header Substitution GCCHeaderSubstitutionMaps_cpp_map=GCC C++ Header Substitution