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:
parent
59b8242268
commit
80ca2e52aa
4 changed files with 34 additions and 58 deletions
|
@ -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.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -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];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue