1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-07-24 09:25:31 +02:00

Content assist for class instance members without prefix, bug 267911.

This commit is contained in:
Markus Schorn 2009-03-12 17:02:25 +00:00
parent fb35a1516f
commit b00cc975fd
8 changed files with 95 additions and 27 deletions

View file

@ -17,7 +17,8 @@ bin.includes = plugin.xml,\
parser/org/eclipse/cdt/internal/index/tests/,\
parser/org/eclipse/cdt/internal/pdom/tests/,\
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/
source.. = model/,\

View file

@ -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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -11,6 +11,8 @@
*******************************************************************************/
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.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
@ -124,4 +126,22 @@ public class BasicCompletionTest extends CompletionTestBase {
node = getGCCCompletionNode(code);
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]);
}
}

View file

@ -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
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@ -7,15 +7,22 @@
*
* Contributors:
* IBM Corporation - initial API and implementation
* Markus Schorn (Wind River Systems)
*******************************************************************************/
package org.eclipse.cdt.core.parser.tests.prefix;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
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.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.parser.ISourceCodeParser;
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.ScannerInfo;
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.cpp.GNUCPPSourceParser;
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();
@ -97,4 +107,47 @@ public class CompletionTestBase extends TestCase {
Arrays.sort(bindings, bindingsComparator);
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;
}
}

View file

@ -89,22 +89,6 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
public IBinding[] getBindings(IASTName name, boolean forceResolve, boolean prefixLookup,
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();
IScope classScope = specialized.getCompositeScope();
if (classScope == null)
@ -118,7 +102,11 @@ public class AbstractCPPClassSpecializationScope implements ICPPClassSpecializat
}
IBinding[] result= null;
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);
}
return (IBinding[]) ArrayUtil.trim(IBinding.class, result);

View file

@ -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
* are made available under the terms of the Eclipse Public License v1.0
* 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) {
baseClass = b;
} 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 {
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;

View file

@ -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.IASTDeclaration;
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.IASTName;
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.
*/
public class CPPClassScope extends CPPScope implements ICPPClassScope {
private static final char[] CONSTRUCTOR_KEY = "!!!CTOR!!!".toCharArray(); //$NON-NLS-1$
private ICPPMethod[] implicits = null;
public CPPClassScope(ICPPASTCompositeTypeSpecifier physicalNode) {
@ -349,6 +349,8 @@ public class CPPClassScope extends CPPScope implements ICPPClassScope {
if (parent instanceof IASTTypeId && parent.getParent() instanceof ICPPASTNewExpression)
return true;
return false;
} else if (node instanceof IASTFieldReference) {
return false;
}
return true;
}

View file

@ -62,6 +62,9 @@ import org.eclipse.core.runtime.PlatformObject;
public class CPPClassType extends PlatformObject implements ICPPInternalClassTypeMixinHost {
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) {
super(node, id, arg);
}

View file

@ -51,6 +51,7 @@ import org.eclipse.core.runtime.NullProgressMonitor;
* Base class for c++-scopes of the ast.
*/
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 IASTNode physicalNode;
private boolean isCached = false;
@ -240,7 +241,7 @@ abstract public class CPPScope implements ICPPScope, ICPPASTInternalScope {
ObjectSet<Object> all= new ObjectSet<Object>(16);
for (int i = 0; i < keys.length; 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);
if (obj instanceof ObjectSet<?>) {
all.addAll((ObjectSet<?>) obj);