1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-17 13:15:44 +02:00

Bug 103857: Content assist for fields declared below point of completion.

This commit is contained in:
Markus Schorn 2010-05-28 08:53:04 +00:00
parent 599285f0c3
commit b73f4d0539
8 changed files with 84 additions and 11 deletions

View file

@ -894,7 +894,14 @@ public class TranslationUnit extends Openable implements ITranslationUnit {
fLanguageOfContext= language; fLanguageOfContext= language;
if (language != null) { if (language != null) {
IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID()); IncludeFileContentProvider crf= getIncludeFileContentProvider(style, index, language.getLinkageID());
return language.getCompletionNode(fileContent, scanInfo, crf, index, ParserUtil.getParserLogService(), offset); IASTCompletionNode result = language.getCompletionNode(fileContent, scanInfo, crf, index, ParserUtil.getParserLogService(), offset);
if (result != null) {
final IASTTranslationUnit ast = result.getTranslationUnit();
if (ast != null) {
ast.setIsHeaderUnit(!isSourceUnit());
}
}
return result;
} }
return null; return null;
} }

View file

@ -62,6 +62,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
private boolean fIsHeader= true; private boolean fIsHeader= true;
private IIndexFileSet fIndexFileSet; private IIndexFileSet fIndexFileSet;
private INodeFactory fNodeFactory; private INodeFactory fNodeFactory;
private boolean fForContentAssist;
@Override @Override
@ -339,6 +340,14 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
fIsHeader= headerUnit; fIsHeader= headerUnit;
} }
public boolean isForContentAssist() {
return fForContentAssist;
}
public final void setIsForContentAssist(boolean forContentAssist) {
fForContentAssist= forContentAssist;
}
/* (non-Javadoc) /* (non-Javadoc)
* @see org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener#skippedFile(org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent) * @see org.eclipse.cdt.internal.core.parser.scanner.ISkippedIndexedFilesListener#skippedFile(org.eclipse.cdt.internal.core.parser.scanner.IncludeFileContent)
*/ */
@ -378,6 +387,7 @@ public abstract class ASTTranslationUnit extends ASTNode implements IASTTranslat
copy.setIsHeaderUnit(fIsHeader); copy.setIsHeaderUnit(fIsHeader);
copy.setASTNodeFactory(fNodeFactory); copy.setASTNodeFactory(fNodeFactory);
copy.setLocationResolver(fLocationResolver); copy.setLocationResolver(fLocationResolver);
copy.setIsForContentAssist(fForContentAssist);
for(IASTDeclaration declaration : getDeclarations()) for(IASTDeclaration declaration : getDeclarations())
copy.addDeclaration(declaration == null ? null : declaration.copy()); copy.addDeclaration(declaration == null ? null : declaration.copy());

View file

@ -27,6 +27,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarationStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement; import org.eclipse.cdt.core.dom.ast.IASTDefaultStatement;
import org.eclipse.cdt.core.dom.ast.IASTDoStatement; import org.eclipse.cdt.core.dom.ast.IASTDoStatement;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer; import org.eclipse.cdt.core.dom.ast.IASTEqualsInitializer;
import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTExpressionList; import org.eclipse.cdt.core.dom.ast.IASTExpressionList;
@ -62,7 +63,6 @@ import org.eclipse.cdt.core.dom.ast.IASTTypeId;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression; import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression; import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTWhileStatement; import org.eclipse.cdt.core.dom.ast.IASTWhileStatement;
import org.eclipse.cdt.core.dom.ast.IASTEnumerationSpecifier.IASTEnumerator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator; import org.eclipse.cdt.core.dom.ast.c.ICASTArrayDesignator;
import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier; import org.eclipse.cdt.core.dom.ast.c.ICASTArrayModifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.c.ICASTCompositeTypeSpecifier;
@ -80,6 +80,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator; import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTArrayRangeDesignator;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.internal.core.dom.parser.NodeFactory; import org.eclipse.cdt.internal.core.dom.parser.NodeFactory;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
/** /**
* Abstract factory implementation that creates AST nodes for C99. * Abstract factory implementation that creates AST nodes for C99.
@ -344,6 +345,9 @@ public class CNodeFactory extends NodeFactory implements ICNodeFactory {
if (scanner != null) { if (scanner != null) {
tu.setLocationResolver(scanner.getLocationResolver()); tu.setLocationResolver(scanner.getLocationResolver());
if (scanner instanceof CPreprocessor) {
tu.setIsForContentAssist(((CPreprocessor) scanner).isContentAssistMode());
}
} }
tu.setASTNodeFactory(this); tu.setASTNodeFactory(this);
return tu; return tu;

View file

@ -109,6 +109,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember; import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointerToMember;
import org.eclipse.cdt.core.parser.IScanner; import org.eclipse.cdt.core.parser.IScanner;
import org.eclipse.cdt.internal.core.dom.parser.NodeFactory; import org.eclipse.cdt.internal.core.dom.parser.NodeFactory;
import org.eclipse.cdt.internal.core.parser.scanner.CPreprocessor;
/** /**
@ -535,6 +536,9 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
if (scanner != null) { if (scanner != null) {
tu.setLocationResolver(scanner.getLocationResolver()); tu.setLocationResolver(scanner.getLocationResolver());
if (scanner instanceof CPreprocessor) {
tu.setIsForContentAssist(((CPreprocessor) scanner).isContentAssistMode());
}
} }
tu.setASTNodeFactory(this); tu.setASTNodeFactory(this);
return tu; return tu;

View file

@ -141,6 +141,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective; import org.eclipse.cdt.core.dom.ast.cpp.ICPPUsingDirective;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable; import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexBinding;
import org.eclipse.cdt.core.index.IIndexFile; import org.eclipse.cdt.core.index.IIndexFile;
import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.index.IIndexFileSet;
@ -155,6 +156,7 @@ import org.eclipse.cdt.internal.core.dom.parser.ASTAmbiguousNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.ASTQueries; import org.eclipse.cdt.internal.core.dom.parser.ASTQueries;
import org.eclipse.cdt.internal.core.dom.parser.ASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguousDeclarator;
import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope; import org.eclipse.cdt.internal.core.dom.parser.IASTInternalScope;
import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding; import org.eclipse.cdt.internal.core.dom.parser.ProblemBinding;
@ -1031,13 +1033,33 @@ public class CPPSemantics {
} }
static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException { static IBinding[] getBindingsFromScope(ICPPScope scope, final IIndexFileSet fileSet, LookupData data) throws DOMException {
IBinding[] bindings; // For internal scopes we need to check the point of declaration
if (scope instanceof ICPPASTInternalScope) { if (scope instanceof ICPPASTInternalScope) {
bindings= ((ICPPASTInternalScope) scope).getBindings(data.astName, true, data.prefixLookup, fileSet, data.checkPointOfDecl); final IASTName astName = data.astName;
} else { final ICPPASTInternalScope internalScope = (ICPPASTInternalScope) scope;
bindings= scope.getBindings(data.astName, true, data.prefixLookup, fileSet); IBinding[] bindings= internalScope.getBindings(astName, true, data.prefixLookup, fileSet, data.checkPointOfDecl);
// Bug 103857: Members declared after the point of completion cannot be
// found in the partial AST, we look them up in the index
if (data.checkWholeClassScope && scope instanceof ICPPClassScope) {
final IASTTranslationUnit tu = astName.getTranslationUnit();
if (tu instanceof ASTTranslationUnit && ((ASTTranslationUnit) tu).isForContentAssist()) {
IIndex index = tu.getIndex();
IASTNode node = internalScope.getPhysicalNode();
if (index != null && node != null && node.contains(astName)) {
IBinding indexBinding= index.adaptBinding(((ICPPClassScope) scope).getClassType());
if (indexBinding instanceof ICPPClassType) {
IScope scopeInIndex= ((ICPPClassType) indexBinding).getCompositeScope();
bindings= ArrayUtil.addAll(bindings, scopeInIndex.getBindings(astName, true, data.prefixLookup, fileSet));
}
}
}
}
return bindings;
} }
return bindings;
// For index scopes the point of declaration is ignored.
return scope.getBindings(data.astName, true, data.prefixLookup, fileSet);
} }
static void removeObjects(final IBinding[] bindings) { static void removeObjects(final IBinding[] bindings) {

View file

@ -252,6 +252,10 @@ public class CPreprocessor implements ILexerLog, IScanner, IAdaptable {
fRootLexer.setContentAssistMode(offset); fRootLexer.setContentAssistMode(offset);
} }
public boolean isContentAssistMode() {
return fRootLexer.isContentAssistMode();
}
public void setProcessInactiveCode(boolean val) { public void setProcessInactiveCode(boolean val) {
fRootContext.setParseInactiveCode(val); fRootContext.setParseInactiveCode(val);
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2007, 2009 Wind River Systems, Inc. and others. * Copyright (c) 2007, 2010 Wind River Systems, Inc. and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -136,6 +136,10 @@ final public class Lexer implements ITokenSequence {
nextCharPhase3(); nextCharPhase3();
} }
public boolean isContentAssistMode() {
return fSupportContentAssist;
}
/** /**
* Call this before consuming the name-token in the include directive. It causes the header-file * Call this before consuming the name-token in the include directive. It causes the header-file
* tokens to be created. * tokens to be created.

View file

@ -789,14 +789,32 @@ public class CompletionTests extends AbstractContentAssistTest {
// void blah(const vector3& v) { x += v./*cursor*/; } // void blah(const vector3& v) { x += v./*cursor*/; }
// float x; // float x;
// }; // };
public void _testForwardMembersInInlineMethods_Bug185652() throws Exception { public void testForwardMembersInInlineMethods_Bug103857a() throws Exception {
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185652 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=103857
final String[] expected= { final String[] expected= {
"x" "x"
}; };
assertMinimumCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); assertMinimumCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
} }
// struct S {
// int mem;
// };
// class X {
// void test() {
// T t;
// t.m/*cursor*/;
// }
// typedef S T;
// };
public void testForwardMembersInInlineMethods_Bug103857b() throws Exception {
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=185652
final String[] expected= {
"mem"
};
assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS);
}
// void Pri/*cursor*/ // void Pri/*cursor*/
public void testMethodDefinitionClassName_Bug190296() throws Exception { public void testMethodDefinitionClassName_Bug190296() throws Exception {
// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=190296 // see https://bugs.eclipse.org/bugs/show_bug.cgi?id=190296