mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 402498 - Apply declaredBefore() filtering to index bindings
Change-Id: Ic0abe31c67c88fa6f17eed3a231ec9231cd93cb0
This commit is contained in:
parent
c3504af925
commit
8c74efdff4
10 changed files with 238 additions and 103 deletions
|
@ -9062,6 +9062,29 @@ public class AST2TemplateTests extends AST2TestBase {
|
|||
assertFalse(x.getType().isSameType(CommonCPPTypes.int_));
|
||||
}
|
||||
|
||||
// struct Cat { void meow(); };
|
||||
// struct Dog { void woof(); };
|
||||
//
|
||||
// template <typename T>
|
||||
// Dog bar(T);
|
||||
//
|
||||
// template <typename T>
|
||||
// auto foo(T t) -> decltype(bar(t));
|
||||
//
|
||||
// namespace N {
|
||||
// class A {};
|
||||
// }
|
||||
//
|
||||
// Cat bar(N::A);
|
||||
//
|
||||
// int main() {
|
||||
// auto x = foo(N::A());
|
||||
// x.woof();
|
||||
// }
|
||||
public void testUnqualifiedFunctionCallInTemplate_402498d() throws Exception {
|
||||
parseAndCheckBindings();
|
||||
}
|
||||
|
||||
// void bar();
|
||||
//
|
||||
// template <typename T>
|
||||
|
|
|
@ -3035,4 +3035,37 @@ public class IndexCPPTemplateResolutionTest extends IndexBindingResolutionTestBa
|
|||
public void testBracedInitList_490475() throws Exception {
|
||||
checkBindings();
|
||||
}
|
||||
|
||||
// struct Cat { void meow(); };
|
||||
// struct Dog { void woof(); };
|
||||
|
||||
// template <typename T>
|
||||
// Dog bar(T);
|
||||
//
|
||||
// template <typename T>
|
||||
// auto foo(T t) -> decltype(bar(t));
|
||||
//
|
||||
// Cat bar(int);
|
||||
//
|
||||
// int main() {
|
||||
// auto x = foo(0);
|
||||
// x.woof();
|
||||
// }
|
||||
public void testUnqualifiedFunctionCallInTemplate_402498() throws Exception {
|
||||
checkBindings();
|
||||
}
|
||||
|
||||
// template<typename T> struct traits;
|
||||
|
||||
// template <typename> struct M;
|
||||
//
|
||||
// template<typename T>
|
||||
// struct traits<M<T>> {
|
||||
// typedef T type;
|
||||
// };
|
||||
//
|
||||
// typedef traits<M<int>>::type waldo; // ERROR
|
||||
public void testRegression_402498() throws Exception {
|
||||
checkBindings();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -280,6 +280,17 @@ public class CPPSemantics {
|
|||
// "a" => { null, "a", null }
|
||||
// ":: i" => { "::", "i", null }
|
||||
private static final Pattern QUALNAME_REGEX = Pattern.compile("^\\s*(::)?\\s*([^\\s:]+)\\s*(?:::(.*))?$"); //$NON-NLS-1$
|
||||
|
||||
// This flag controls whether name lookup is allowed to find bindings in headers
|
||||
// that are not reachable via includes from the file containing the name.
|
||||
// Generally this is not allowed, but certain consumers, such as IncludeOrganizer,
|
||||
// need it (since the whole point of IncludeOrganizer is to find missing headers).
|
||||
private static final ThreadLocal<Boolean> fAllowPromiscuousBindingResolution = new ThreadLocal<Boolean>() {
|
||||
@Override
|
||||
protected Boolean initialValue() {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
static protected IBinding resolveBinding(IASTName name) {
|
||||
if (traceBindingResolution) {
|
||||
|
@ -1931,14 +1942,15 @@ public class CPPSemantics {
|
|||
if (node == null)
|
||||
return true;
|
||||
|
||||
final int pointOfRef= ((ASTNode) node).getOffset();
|
||||
// The pointOfRef and pointOfDecl variables contain node offsets scaled by a factor of two.
|
||||
// This is done to distinguish between left and right points for the same offset.
|
||||
final int pointOfRef= ((ASTNode) node).getOffset() * 2;
|
||||
ASTNode nd = null;
|
||||
if (obj instanceof ICPPSpecialization) {
|
||||
obj = ((ICPPSpecialization) obj).getSpecializedBinding();
|
||||
}
|
||||
|
||||
int pointOfDecl= -1;
|
||||
boolean pointOfDeclIsEndOffset = false;
|
||||
if (obj instanceof ICPPInternalBinding) {
|
||||
ICPPInternalBinding cpp = (ICPPInternalBinding) obj;
|
||||
IASTNode[] n = cpp.getDeclarations();
|
||||
|
@ -1962,72 +1974,84 @@ public class CPPSemantics {
|
|||
if (obj instanceof ASTNode) {
|
||||
nd = (ASTNode) obj;
|
||||
} else if (obj instanceof ICPPUsingDirective) {
|
||||
pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration();
|
||||
pointOfDecl= ((ICPPUsingDirective) obj).getPointOfDeclaration() * 2;
|
||||
}
|
||||
}
|
||||
|
||||
if (pointOfDecl < 0 && nd != null) {
|
||||
ASTNodeProperty prop = nd.getPropertyInParent();
|
||||
if (prop == IASTDeclarator.DECLARATOR_NAME || nd instanceof IASTDeclarator) {
|
||||
// Point of declaration for a name is immediately after its complete declarator
|
||||
// and before its initializer.
|
||||
IASTDeclarator dtor = (IASTDeclarator)((nd instanceof IASTDeclarator) ? nd : nd.getParent());
|
||||
while (dtor.getParent() instanceof IASTDeclarator) {
|
||||
dtor = (IASTDeclarator) dtor.getParent();
|
||||
if (pointOfDecl < 0) {
|
||||
if (nd != null) {
|
||||
pointOfDecl = getPointOfDeclaration(nd);
|
||||
} else if (obj instanceof IIndexBinding && !isUsingPromiscuousBindingResolution()) {
|
||||
IIndexBinding indexBinding = (IIndexBinding) obj;
|
||||
if (indexBinding instanceof ICPPMethod && ((ICPPMethod) indexBinding).isImplicit()) {
|
||||
return true;
|
||||
}
|
||||
IASTInitializer init = dtor.getInitializer();
|
||||
// [basic.scope.pdecl]/p9: The point of declaration for a template parameter
|
||||
// is immediately after its complete template-parameter.
|
||||
// Note: can't just check "dtor.getParent() instanceof ICPPASTTemplateParameter"
|
||||
// because function parameter declarations implement ICPPASTTemplateParameter too.
|
||||
boolean isTemplateParameter = dtor.getParent() instanceof ICPPASTTemplateParameter
|
||||
&& dtor.getParent().getPropertyInParent() == ICPPASTTemplateDeclaration.PARAMETER;
|
||||
if (init != null && !isTemplateParameter) {
|
||||
pointOfDecl = ((ASTNode) init).getOffset() - 1;
|
||||
} else {
|
||||
pointOfDecl = ((ASTNode) dtor).getOffset() + ((ASTNode) dtor).getLength();
|
||||
pointOfDeclIsEndOffset = true;
|
||||
}
|
||||
} else if (prop == IASTEnumerator.ENUMERATOR_NAME) {
|
||||
// Point of declaration for an enumerator is immediately after it
|
||||
// enumerator-definition
|
||||
IASTEnumerator enumtor = (IASTEnumerator) nd.getParent();
|
||||
if (enumtor.getValue() != null) {
|
||||
ASTNode exp = (ASTNode) enumtor.getValue();
|
||||
pointOfDecl = exp.getOffset() + exp.getLength();
|
||||
} else {
|
||||
pointOfDecl = nd.getOffset() + nd.getLength();
|
||||
}
|
||||
pointOfDeclIsEndOffset = true;
|
||||
} else if (prop == ICPPASTUsingDeclaration.NAME) {
|
||||
nd = (ASTNode) nd.getParent();
|
||||
pointOfDecl = nd.getOffset();
|
||||
} else if (prop == ICPPASTNamespaceAlias.ALIAS_NAME) {
|
||||
nd = (ASTNode) nd.getParent();
|
||||
pointOfDecl = nd.getOffset() + nd.getLength();
|
||||
pointOfDeclIsEndOffset = true;
|
||||
} else if (prop == ICPPASTAliasDeclaration.ALIAS_NAME) {
|
||||
// [basic.scope.pdecl]/p3: The point of declaration of an alias or alias template
|
||||
// immediately follows the type-id to which the alias refers.
|
||||
ASTNode targetType = (ASTNode) ((ICPPASTAliasDeclaration) nd.getParent()).getMappingTypeId();
|
||||
pointOfDecl = targetType.getOffset() + targetType.getLength();
|
||||
pointOfDeclIsEndOffset = true;
|
||||
} else if (prop == ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME
|
||||
|| prop == ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME) {
|
||||
// [basic.scope.pdecl]/p9: The point of declaration for a template parameter
|
||||
// is immediately after its complete template-parameter.
|
||||
// Type and template template parameters are handled here;
|
||||
// non-type template parameters are handled in the DECLARATOR_NAME
|
||||
// case above.
|
||||
nd = (ASTNode) nd.getParent();
|
||||
pointOfDecl = nd.getOffset() + nd.getLength();
|
||||
pointOfDeclIsEndOffset = true;
|
||||
} else {
|
||||
pointOfDecl = nd.getOffset() + nd.getLength();
|
||||
pointOfDeclIsEndOffset = true;
|
||||
IASTTranslationUnit tu = node.getTranslationUnit();
|
||||
IIndexFileSet indexFileSet = tu.getIndexFileSet();
|
||||
return (indexFileSet != null && indexFileSet.containsDeclaration(indexBinding));
|
||||
}
|
||||
}
|
||||
return pointOfDecl < pointOfRef || (pointOfDecl == pointOfRef && pointOfDeclIsEndOffset);
|
||||
return pointOfDecl < pointOfRef;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the point of declaration for the given AST node. The point of declaration is a node offset
|
||||
* scaled by a factor of two. This is done to distinguish between left and right points for the offset.
|
||||
*/
|
||||
private static int getPointOfDeclaration(ASTNode nd) {
|
||||
ASTNodeProperty prop = nd.getPropertyInParent();
|
||||
if (prop == IASTDeclarator.DECLARATOR_NAME || nd instanceof IASTDeclarator) {
|
||||
// Point of declaration for a name is immediately after its complete declarator
|
||||
// and before its initializer.
|
||||
IASTDeclarator dtor = (IASTDeclarator)((nd instanceof IASTDeclarator) ? nd : nd.getParent());
|
||||
while (dtor.getParent() instanceof IASTDeclarator) {
|
||||
dtor = (IASTDeclarator) dtor.getParent();
|
||||
}
|
||||
IASTInitializer init = dtor.getInitializer();
|
||||
// [basic.scope.pdecl]/p9: The point of declaration for a template parameter
|
||||
// is immediately after its complete template-parameter.
|
||||
// Note: can't just check "dtor.getParent() instanceof ICPPASTTemplateParameter"
|
||||
// because function parameter declarations implement ICPPASTTemplateParameter too.
|
||||
boolean isTemplateParameter = dtor.getParent() instanceof ICPPASTTemplateParameter
|
||||
&& dtor.getParent().getPropertyInParent() == ICPPASTTemplateDeclaration.PARAMETER;
|
||||
if (init != null && !isTemplateParameter) {
|
||||
return ((ASTNode) init).getOffset() * 2 - 1;
|
||||
} else {
|
||||
return (((ASTNode) dtor).getOffset() + ((ASTNode) dtor).getLength()) * 2 - 1;
|
||||
}
|
||||
} else if (prop == IASTEnumerator.ENUMERATOR_NAME) {
|
||||
// Point of declaration for an enumerator is immediately after it
|
||||
// enumerator-definition
|
||||
IASTEnumerator enumtor = (IASTEnumerator) nd.getParent();
|
||||
if (enumtor.getValue() != null) {
|
||||
ASTNode exp = (ASTNode) enumtor.getValue();
|
||||
return (exp.getOffset() + exp.getLength()) * 2 - 1;
|
||||
} else {
|
||||
return (nd.getOffset() + nd.getLength()) * 2 - 1;
|
||||
}
|
||||
} else if (prop == ICPPASTUsingDeclaration.NAME) {
|
||||
nd = (ASTNode) nd.getParent();
|
||||
return nd.getOffset() * 2;
|
||||
} else if (prop == ICPPASTNamespaceAlias.ALIAS_NAME) {
|
||||
nd = (ASTNode) nd.getParent();
|
||||
return (nd.getOffset() + nd.getLength()) * 2 - 1;
|
||||
} else if (prop == ICPPASTAliasDeclaration.ALIAS_NAME) {
|
||||
// [basic.scope.pdecl]/p3: The point of declaration of an alias or alias template
|
||||
// immediately follows the type-id to which the alias refers.
|
||||
ASTNode targetType = (ASTNode) ((ICPPASTAliasDeclaration) nd.getParent()).getMappingTypeId();
|
||||
return (targetType.getOffset() + targetType.getLength()) * 2 - 1;
|
||||
} else if (prop == ICPPASTSimpleTypeTemplateParameter.PARAMETER_NAME
|
||||
|| prop == ICPPASTTemplatedTypeTemplateParameter.PARAMETER_NAME) {
|
||||
// [basic.scope.pdecl]/p9: The point of declaration for a template parameter
|
||||
// is immediately after its complete template-parameter.
|
||||
// Type and template template parameters are handled here;
|
||||
// non-type template parameters are handled in the DECLARATOR_NAME
|
||||
// case above.
|
||||
nd = (ASTNode) nd.getParent();
|
||||
return (nd.getOffset() + nd.getLength()) * 2 - 1;
|
||||
} else {
|
||||
return (nd.getOffset() + nd.getLength()) * 2 - 1;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean acceptDeclaredAfter(ICPPInternalBinding cpp) {
|
||||
|
@ -4232,4 +4256,16 @@ public class CPPSemantics {
|
|||
|
||||
return binding;
|
||||
}
|
||||
|
||||
public static void enablePromiscuousBindingResolution() {
|
||||
fAllowPromiscuousBindingResolution.set(true);
|
||||
}
|
||||
|
||||
public static void disablePromiscuousBindingResolution() {
|
||||
fAllowPromiscuousBindingResolution.set(false);
|
||||
}
|
||||
|
||||
public static boolean isUsingPromiscuousBindingResolution() {
|
||||
return fAllowPromiscuousBindingResolution.get();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -279,6 +279,7 @@ public class BasicSearchTest extends SearchTestBase {
|
|||
|
||||
// void foo() {}
|
||||
|
||||
// #include "header.h"
|
||||
// void bar() {
|
||||
// foo();
|
||||
// }
|
||||
|
@ -297,6 +298,7 @@ public class BasicSearchTest extends SearchTestBase {
|
|||
|
||||
// void foo() {}
|
||||
|
||||
// #include "header.h"
|
||||
// void bar() {foo();foo();foo();}
|
||||
public void testNewResultsOnSearchAgainB() throws Exception {
|
||||
CSearchQuery query= makeProjectQuery("foo");
|
||||
|
@ -304,7 +306,7 @@ public class BasicSearchTest extends SearchTestBase {
|
|||
assertOccurrences(query, 4);
|
||||
|
||||
// whitespace s.t. new match offset is same as older
|
||||
String newContent= "void bar() { foo(); }";
|
||||
String newContent= "#include \"header.h\"\nvoid bar() { foo(); }";
|
||||
IFile file = fCProject.getProject().getFile(new Path("references.cpp"));
|
||||
file.setContents(new ByteArrayInputStream(newContent.getBytes()), IResource.FORCE, npm());
|
||||
runEventQueue(1000);
|
||||
|
@ -314,7 +316,7 @@ public class BasicSearchTest extends SearchTestBase {
|
|||
|
||||
assertOccurrences(query, 2);
|
||||
|
||||
String newContent2= "void bar() {foo(); foo();}";
|
||||
String newContent2= "#include \"header.h\"\nvoid bar() {foo(); foo();}";
|
||||
file.setContents(new ByteArrayInputStream(newContent2.getBytes()), IResource.FORCE, npm());
|
||||
waitForIndexer(fCProject);
|
||||
|
||||
|
@ -326,6 +328,7 @@ public class BasicSearchTest extends SearchTestBase {
|
|||
// template<typename T> void f(T) {};
|
||||
// template<typename T> void f(T*) {};
|
||||
|
||||
// #include "header.h"
|
||||
// void a() {
|
||||
// CT<int>* r1;
|
||||
// CT<char>* r2;
|
||||
|
|
|
@ -184,6 +184,7 @@ public class CPPSelectionTestsIndexer extends BaseSelectionTestsIndexer {
|
|||
// public: void assign(const T* s) {}
|
||||
// };
|
||||
|
||||
// #include "testTemplateClassMethod.h"
|
||||
// void main() {
|
||||
// C<char> a;
|
||||
// a.assign("aaa");
|
||||
|
@ -1175,6 +1176,7 @@ public class CPPSelectionTestsIndexer extends BaseSelectionTestsIndexer {
|
|||
// T operator+(int);
|
||||
// };
|
||||
|
||||
// #include "test.h"
|
||||
// void main() {
|
||||
// C<char> a;
|
||||
// a + 2;
|
||||
|
|
|
@ -13,8 +13,10 @@ package org.eclipse.cdt.internal.ui.editor;
|
|||
import java.util.Collection;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
|
@ -38,10 +40,10 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.SharedASTJob;
|
||||
|
||||
import org.eclipse.cdt.internal.core.model.ASTCache;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.BusyCursorJobRunner;
|
||||
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
||||
|
@ -100,25 +102,32 @@ public class AddIncludeAction extends TextEditorAction {
|
|||
}
|
||||
|
||||
final MultiTextEdit[] holder = new MultiTextEdit[1];
|
||||
SharedASTJob job = new SharedASTJob(CEditorMessages.AddInclude_action, tu) {
|
||||
// We can't use SharedASTJob because IncludeCreator needs to disable promiscuous
|
||||
// binding resolution, and you can't mix promiscuous and non-promiscuous binding
|
||||
// resolution in the same AST.
|
||||
Job job = new Job(CEditorMessages.AddInclude_action) {
|
||||
@Override
|
||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
|
||||
if (ast == null) {
|
||||
return CUIPlugin.createErrorStatus(
|
||||
NLS.bind(CEditorMessages.AddInclude_ast_not_available, tu.getPath().toOSString()));
|
||||
}
|
||||
|
||||
IIndex index= CCorePlugin.getIndexManager().getIndex(tu.getCProject(),
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT);
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
index.acquireReadLock();
|
||||
IncludeCreator creator = new IncludeCreator(tu, index, fAmbiguityResolver);
|
||||
holder[0] = creator.createInclude(ast, (ITextSelection) selection);
|
||||
return Status.OK_STATUS;
|
||||
} catch (InterruptedException e) {
|
||||
return Status.CANCEL_STATUS;
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
IIndex index= CCorePlugin.getIndexManager().getIndex(tu.getCProject(),
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT);
|
||||
try {
|
||||
index.acquireReadLock();
|
||||
IASTTranslationUnit ast = tu.getAST(index, ASTCache.PARSE_MODE);
|
||||
if (ast == null) {
|
||||
return CUIPlugin.createErrorStatus(
|
||||
NLS.bind(CEditorMessages.AddInclude_ast_not_available, tu.getPath().toOSString()));
|
||||
}
|
||||
IncludeCreator creator = new IncludeCreator(tu, index, fAmbiguityResolver);
|
||||
holder[0] = creator.createInclude(ast, (ITextSelection) selection);
|
||||
return Status.OK_STATUS;
|
||||
} catch (InterruptedException e) {
|
||||
return Status.CANCEL_STATUS;
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
return e.getStatus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -12,8 +12,10 @@
|
|||
package org.eclipse.cdt.internal.ui.editor;
|
||||
|
||||
import org.eclipse.core.runtime.CoreException;
|
||||
import org.eclipse.core.runtime.IProgressMonitor;
|
||||
import org.eclipse.core.runtime.IStatus;
|
||||
import org.eclipse.core.runtime.Status;
|
||||
import org.eclipse.core.runtime.jobs.Job;
|
||||
import org.eclipse.jface.dialogs.ErrorDialog;
|
||||
import org.eclipse.jface.text.BadLocationException;
|
||||
import org.eclipse.jface.text.IDocument;
|
||||
|
@ -30,10 +32,10 @@ import org.eclipse.cdt.core.CCorePlugin;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.index.IIndex;
|
||||
import org.eclipse.cdt.core.index.IIndexManager;
|
||||
import org.eclipse.cdt.core.model.ILanguage;
|
||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
import org.eclipse.cdt.ui.text.SharedASTJob;
|
||||
|
||||
import org.eclipse.cdt.internal.core.model.ASTCache;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.BusyCursorJobRunner;
|
||||
import org.eclipse.cdt.internal.ui.ICHelpContextIds;
|
||||
|
@ -67,25 +69,32 @@ public class OrganizeIncludesAction extends TextEditorAction {
|
|||
final IHeaderChooser headerChooser = new InteractiveHeaderChooser(
|
||||
CEditorMessages.OrganizeIncludes_label, editor.getSite().getShell());
|
||||
final MultiTextEdit[] holder = new MultiTextEdit[1];
|
||||
SharedASTJob job = new SharedASTJob(CEditorMessages.OrganizeIncludes_action, tu) {
|
||||
// We can't use SharedASTJob because IncludeOrganizer needs to disable promiscuous
|
||||
// binding resolution, and you can't mix promiscuous and non-promiscuous binding
|
||||
// resolution in the same AST.
|
||||
Job job = new Job(CEditorMessages.OrganizeIncludes_action) {
|
||||
@Override
|
||||
public IStatus runOnAST(ILanguage lang, IASTTranslationUnit ast) throws CoreException {
|
||||
if (ast == null) {
|
||||
return CUIPlugin.createErrorStatus(
|
||||
NLS.bind(CEditorMessages.OrganizeIncludes_ast_not_available, tu.getPath().toOSString()));
|
||||
}
|
||||
|
||||
IIndex index= CCorePlugin.getIndexManager().getIndex(tu.getCProject(),
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT);
|
||||
public IStatus run(IProgressMonitor monitor) {
|
||||
try {
|
||||
index.acquireReadLock();
|
||||
IncludeOrganizer organizer = new IncludeOrganizer(tu, index, headerChooser);
|
||||
holder[0] = organizer.organizeIncludes(ast);
|
||||
return Status.OK_STATUS;
|
||||
} catch (InterruptedException e) {
|
||||
return Status.CANCEL_STATUS;
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
IIndex index= CCorePlugin.getIndexManager().getIndex(tu.getCProject(),
|
||||
IIndexManager.ADD_DEPENDENCIES | IIndexManager.ADD_EXTENSION_FRAGMENTS_ADD_IMPORT);
|
||||
try {
|
||||
index.acquireReadLock();
|
||||
IASTTranslationUnit ast = tu.getAST(index, ASTCache.PARSE_MODE);
|
||||
if (ast == null) {
|
||||
return CUIPlugin.createErrorStatus(
|
||||
NLS.bind(CEditorMessages.OrganizeIncludes_ast_not_available, tu.getPath().toOSString()));
|
||||
}
|
||||
IncludeOrganizer organizer = new IncludeOrganizer(tu, index, headerChooser);
|
||||
holder[0] = organizer.organizeIncludes(ast);
|
||||
return Status.OK_STATUS;
|
||||
} catch (InterruptedException e) {
|
||||
return Status.CANCEL_STATUS;
|
||||
} finally {
|
||||
index.releaseReadLock();
|
||||
}
|
||||
} catch (CoreException e) {
|
||||
return e.getStatus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -977,7 +977,15 @@ public class BindingClassifier {
|
|||
if (fAst == null) {
|
||||
fAst = node.getTranslationUnit();
|
||||
}
|
||||
node.accept(fBindingCollector);
|
||||
try {
|
||||
// Enable promiscuous binding resolution for this AST traversal,
|
||||
// to allow names to be resolved even if the declarations of their
|
||||
// target bindings are in a header not reachable via includes.
|
||||
CPPSemantics.enablePromiscuousBindingResolution();
|
||||
node.accept(fBindingCollector);
|
||||
} finally {
|
||||
CPPSemantics.disablePromiscuousBindingResolution();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -77,6 +77,7 @@ import org.eclipse.cdt.ui.IRequiredInclude;
|
|||
import org.eclipse.cdt.ui.text.ICHelpInvocationContext;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.commenthandler.ASTCommenter;
|
||||
|
@ -106,6 +107,16 @@ public class IncludeCreator {
|
|||
|
||||
public MultiTextEdit createInclude(IASTTranslationUnit ast, ITextSelection selection)
|
||||
throws CoreException {
|
||||
try {
|
||||
CPPSemantics.enablePromiscuousBindingResolution();
|
||||
return createIncludeImpl(ast, selection);
|
||||
} finally {
|
||||
CPPSemantics.disablePromiscuousBindingResolution();
|
||||
}
|
||||
}
|
||||
|
||||
private MultiTextEdit createIncludeImpl(IASTTranslationUnit ast, ITextSelection selection)
|
||||
throws CoreException {
|
||||
MultiTextEdit rootEdit = new MultiTextEdit();
|
||||
ITranslationUnit tu = fContext.getTranslationUnit();
|
||||
IASTNodeSelector selector = ast.getNodeSelector(tu.getLocation().toOSString());
|
||||
|
|
|
@ -92,6 +92,7 @@ public class QmlRegistrationTests extends BaseQtTestCase {
|
|||
}
|
||||
}
|
||||
|
||||
// #include "junit-QObject.hh"
|
||||
// class T;
|
||||
//
|
||||
// static void func()
|
||||
|
|
Loading…
Add table
Reference in a new issue