mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-09-10 12:03:16 +02:00
Content assist for class instance members without prefix, bug 267911.
This commit is contained in:
parent
fb35a1516f
commit
b00cc975fd
8 changed files with 95 additions and 27 deletions
|
@ -17,7 +17,8 @@ bin.includes = plugin.xml,\
|
||||||
parser/org/eclipse/cdt/internal/index/tests/,\
|
parser/org/eclipse/cdt/internal/index/tests/,\
|
||||||
parser/org/eclipse/cdt/internal/pdom/tests/,\
|
parser/org/eclipse/cdt/internal/pdom/tests/,\
|
||||||
parser/org/eclipse/cdt/core/parser/tests/ast2/,\
|
parser/org/eclipse/cdt/core/parser/tests/ast2/,\
|
||||||
parser/org/eclipse/cdt/core/parser/tests/scanner/
|
parser/org/eclipse/cdt/core/parser/tests/scanner/,\
|
||||||
|
parser/org/eclipse/cdt/core/parser/tests/prefix/
|
||||||
|
|
||||||
output.. = bin/
|
output.. = bin/
|
||||||
source.. = model/,\
|
source.. = model/,\
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 IBM Corporation 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
|
||||||
|
@ -11,6 +11,8 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.tests.prefix;
|
package org.eclipse.cdt.core.parser.tests.prefix;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
|
@ -124,4 +126,22 @@ public class BasicCompletionTest extends CompletionTestBase {
|
||||||
node = getGCCCompletionNode(code);
|
node = getGCCCompletionNode(code);
|
||||||
assertNotNull(node);
|
assertNotNull(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// template <typename T> class CT {};
|
||||||
|
// template <typename T> class B: public A<T> {
|
||||||
|
// public:
|
||||||
|
// void doit(){}
|
||||||
|
// };
|
||||||
|
// int main() {
|
||||||
|
// B<int> b;
|
||||||
|
// b.
|
||||||
|
public void testBug267911() throws Exception {
|
||||||
|
String code = getAboveComment();
|
||||||
|
IASTCompletionNode node = getGPPCompletionNode(code);
|
||||||
|
assertNotNull(node);
|
||||||
|
List<IBinding> bindings= proposeBindings(node);
|
||||||
|
String[] names= getSortedNames(bindings);
|
||||||
|
assertEquals("B", names[0]);
|
||||||
|
assertEquals("doit", names[1]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/**********************************************************************
|
/**********************************************************************
|
||||||
* Copyright (c) 2004, 2007 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 IBM Corporation 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
|
||||||
|
@ -7,15 +7,22 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* IBM Corporation - initial API and implementation
|
* IBM Corporation - initial API and implementation
|
||||||
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.tests.prefix;
|
package org.eclipse.cdt.core.parser.tests.prefix;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.Comparator;
|
import java.util.Comparator;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
import junit.framework.TestCase;
|
import junit.framework.AssertionFailedError;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTCompletionContext;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
import org.eclipse.cdt.core.dom.ast.IASTCompletionNode;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.parser.ISourceCodeParser;
|
import org.eclipse.cdt.core.dom.parser.ISourceCodeParser;
|
||||||
import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration;
|
import org.eclipse.cdt.core.dom.parser.c.ANSICParserExtensionConfiguration;
|
||||||
|
@ -32,11 +39,14 @@ import org.eclipse.cdt.core.parser.ParserLanguage;
|
||||||
import org.eclipse.cdt.core.parser.ParserMode;
|
import org.eclipse.cdt.core.parser.ParserMode;
|
||||||
import org.eclipse.cdt.core.parser.ScannerInfo;
|
import org.eclipse.cdt.core.parser.ScannerInfo;
|
||||||
import org.eclipse.cdt.core.parser.tests.ast2.AST2BaseTest;
|
import org.eclipse.cdt.core.parser.tests.ast2.AST2BaseTest;
|
||||||
|
import org.eclipse.cdt.core.testplugin.CTestPlugin;
|
||||||
|
import org.eclipse.cdt.core.testplugin.util.BaseTestCase;
|
||||||
|
import org.eclipse.cdt.core.testplugin.util.TestSourceReader;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
|
import org.eclipse.cdt.internal.core.dom.parser.c.GNUCSourceParser;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.GNUCPPSourceParser;
|
||||||
import org.eclipse.cdt.internal.core.parser.ParserException;
|
import org.eclipse.cdt.internal.core.parser.ParserException;
|
||||||
|
|
||||||
public class CompletionTestBase extends TestCase {
|
public class CompletionTestBase extends BaseTestCase {
|
||||||
|
|
||||||
private static final IParserLogService NULL_LOG = new NullLogService();
|
private static final IParserLogService NULL_LOG = new NullLogService();
|
||||||
|
|
||||||
|
@ -97,4 +107,47 @@ public class CompletionTestBase extends TestCase {
|
||||||
Arrays.sort(bindings, bindingsComparator);
|
Arrays.sort(bindings, bindingsComparator);
|
||||||
return bindings;
|
return bindings;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected String getAboveComment() throws IOException {
|
||||||
|
return getContents(1)[0].toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected StringBuffer[] getContents(int sections) throws IOException {
|
||||||
|
CTestPlugin plugin = CTestPlugin.getDefault();
|
||||||
|
if (plugin == null)
|
||||||
|
throw new AssertionFailedError("This test must be run as a JUnit plugin test");
|
||||||
|
return TestSourceReader.getContentsForTest(plugin.getBundle(), "parser", getClass(), getName(), sections);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected List<IBinding> proposeBindings(IASTCompletionNode completionNode) {
|
||||||
|
List<IBinding> proposals = new ArrayList<IBinding>();
|
||||||
|
boolean handleMacros= false;
|
||||||
|
IASTName[] names = completionNode.getNames();
|
||||||
|
|
||||||
|
for (int i = 0; i < names.length; ++i) {
|
||||||
|
if (names[i].getTranslationUnit() == null)
|
||||||
|
// The node isn't properly hooked up, must have backtracked out of this node
|
||||||
|
continue;
|
||||||
|
|
||||||
|
IASTCompletionContext astContext = names[i].getCompletionContext();
|
||||||
|
if (astContext == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
IBinding[] bindings = astContext.findBindings(names[i], true);
|
||||||
|
if (bindings != null)
|
||||||
|
for (int j = 0; j < bindings.length; ++j)
|
||||||
|
proposals.add(bindings[j]);
|
||||||
|
}
|
||||||
|
return proposals;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected String[] getSortedNames(List<IBinding> bindings) {
|
||||||
|
String[] result= new String[bindings.size()];
|
||||||
|
Iterator<IBinding> it= bindings.iterator();
|
||||||
|
for (int i = 0; i < result.length; i++) {
|
||||||
|
result[i]= it.next().getName();
|
||||||
|
}
|
||||||
|
Arrays.sort(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -89,22 +89,6 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
|
||||||
|
|
||||||
public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup,
|
public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup,
|
||||||
IIndexFileSet fileSet, boolean checkPointOfDecl) throws DOMException {
|
IIndexFileSet fileSet, boolean checkPointOfDecl) throws DOMException {
|
||||||
char[] c = name.getLookupKey();
|
|
||||||
|
|
||||||
if ((!prefixLookup && CharArrayUtils.equals(c, specialClass.getNameCharArray())) ||
|
|
||||||
(prefixLookup && CharArrayUtils.equals(specialClass.getNameCharArray(), 0, c.length, c, true))) {
|
|
||||||
IBinding[] result= new IBinding[] {specialClass};
|
|
||||||
if (CPPClassScope.isConstructorReference(name)) {
|
|
||||||
result = (IBinding[]) ArrayUtil.addAll(IBinding.class, result, specialClass.getConstructors());
|
|
||||||
}
|
|
||||||
result= (IBinding[]) ArrayUtil.trim(IBinding.class, result);
|
|
||||||
// specialize all but first
|
|
||||||
for (int i = 1; i < result.length; i++) {
|
|
||||||
result[i]= specialClass.specializeMember(result[i]);
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
ICPPClassType specialized = specialClass.getSpecializedBinding();
|
ICPPClassType specialized = specialClass.getSpecializedBinding();
|
||||||
IScope classScope = specialized.getCompositeScope();
|
IScope classScope = specialized.getCompositeScope();
|
||||||
if (classScope == null)
|
if (classScope == null)
|
||||||
|
@ -118,7 +102,11 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
|
||||||
}
|
}
|
||||||
IBinding[] result= null;
|
IBinding[] result= null;
|
||||||
for (IBinding binding : bindings) {
|
for (IBinding binding : bindings) {
|
||||||
binding= specialClass.specializeMember(binding);
|
if (binding == specialized) {
|
||||||
|
binding= specialClass;
|
||||||
|
} else {
|
||||||
|
binding= specialClass.specializeMember(binding);
|
||||||
|
}
|
||||||
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
|
result = (IBinding[]) ArrayUtil.append(IBinding.class, result, binding);
|
||||||
}
|
}
|
||||||
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
|
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2004, 2008 IBM Corporation and others.
|
* Copyright (c) 2004, 2009 IBM Corporation 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
|
||||||
|
@ -83,9 +83,9 @@ public class CPPBaseClause implements ICPPBase, ICPPInternalBase {
|
||||||
if (b instanceof ICPPClassType || b instanceof ICPPTemplateParameter) {
|
if (b instanceof ICPPClassType || b instanceof ICPPTemplateParameter) {
|
||||||
baseClass = b;
|
baseClass = b;
|
||||||
} else if (b instanceof IProblemBinding) {
|
} else if (b instanceof IProblemBinding) {
|
||||||
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ((IProblemBinding) b).getID(), base.getName().toCharArray());
|
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), ((IProblemBinding) b).getID());
|
||||||
} else {
|
} else {
|
||||||
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), IProblemBinding.SEMANTIC_NAME_NOT_FOUND, base.getName().toCharArray());
|
baseClass = new CPPClassType.CPPClassTypeProblem(base.getName(), IProblemBinding.SEMANTIC_NAME_NOT_FOUND);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return baseClass;
|
return baseClass;
|
||||||
|
|
|
@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.EScopeKind;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
@ -64,7 +65,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
* Base implementation for c++ scopes.
|
* Base implementation for c++ scopes.
|
||||||
*/
|
*/
|
||||||
public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
private static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
|
|
||||||
private ICPPMethod[] implicits = null;
|
private ICPPMethod[] implicits = null;
|
||||||
|
|
||||||
public CPPClassScope(ICPPASTCompositeTypeSpecifier physicalNode) {
|
public CPPClassScope(ICPPASTCompositeTypeSpecifier physicalNode) {
|
||||||
|
@ -349,6 +349,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
|
||||||
if (parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression)
|
if (parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression)
|
||||||
return true;
|
return true;
|
||||||
return false;
|
return false;
|
||||||
|
} else if (node instanceof IASTFieldReference) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -62,6 +62,9 @@ import org.eclipse.core.runtime.PlatformObject;
|
||||||
public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost {
|
public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost {
|
||||||
|
|
||||||
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType {
|
public static class CPPClassTypeProblem extends ProblemBinding implements ICPPClassType {
|
||||||
|
public CPPClassTypeProblem(IASTName name, int id) {
|
||||||
|
super(name, id);
|
||||||
|
}
|
||||||
public CPPClassTypeProblem(IASTNode node, int id, char[] arg) {
|
public CPPClassTypeProblem(IASTNode node, int id, char[] arg) {
|
||||||
super(node, id, arg);
|
super(node, id, arg);
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
|
||||||
* Base class for c++-scopes of the ast.
|
* Base class for c++-scopes of the ast.
|
||||||
*/
|
*/
|
||||||
abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
|
abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
|
||||||
|
protected static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
|
||||||
private static final IProgressMonitor NPM = new NullProgressMonitor();
|
private static final IProgressMonitor NPM = new NullProgressMonitor();
|
||||||
private IASTNode physicalNode;
|
private IASTNode physicalNode;
|
||||||
private boolean isCached = false;
|
private boolean isCached = false;
|
||||||
|
@ -240,7 +241,7 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
|
||||||
ObjectSet<Object> all= new ObjectSet<Object>(16);
|
ObjectSet<Object> all= new ObjectSet<Object>(16);
|
||||||
for (int i = 0; i < keys.length; i++) {
|
for (int i = 0; i < keys.length; i++) {
|
||||||
final char[] key = (char[]) keys[i];
|
final char[] key = (char[]) keys[i];
|
||||||
if (CharArrayUtils.equals(key, 0, c.length, c, true)) {
|
if (key != CONSTRUCTOR_KEY && CharArrayUtils.equals(key, 0, c.length, c, true)) {
|
||||||
obj= bindings.get(key);
|
obj= bindings.get(key);
|
||||||
if (obj instanceof ObjectSet<?>) {
|
if (obj instanceof ObjectSet<?>) {
|
||||||
all.addAll((ObjectSet<?>) obj);
|
all.addAll((ObjectSet<?>) obj);
|
||||||
|
|
Loading…
Add table
Reference in a new issue