mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-08-17 21:25:58 +02:00
Bug 103857: Content assist for fields declared below point of completion.
This commit is contained in:
parent
599285f0c3
commit
b73f4d0539
8 changed files with 84 additions and 11 deletions
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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());
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,15 +1033,35 @@ 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) {
|
||||||
final int length = bindings.length;
|
final int length = bindings.length;
|
||||||
int pos= 0;
|
int pos= 0;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Reference in a new issue