From ada1ba048ced90862c88ec97fc47e59dfb01ee85 Mon Sep 17 00:00:00 2001 From: Markus Schorn Date: Mon, 22 Jun 2009 13:41:49 +0000 Subject: [PATCH] Content assist for typedefs using same name as struct, bug 279931. --- .../tests/prefix/BasicCompletionTest.java | 34 ++++++++++++++----- .../tests/prefix/CompletionTestBase.java | 14 +++++++- .../parser/c/CASTElaboratedTypeSpecifier.java | 3 ++ .../internal/core/dom/parser/c/CVisitor.java | 20 ++++++----- 4 files changed, 53 insertions(+), 18 deletions(-) diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java index 1df2d70188f..31a60a41d7e 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/BasicCompletionTest.java @@ -11,8 +11,6 @@ *******************************************************************************/ 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; @@ -137,11 +135,31 @@ public class BasicCompletionTest extends CompletionTestBase { // b. public void testBug267911() throws Exception { String code = getAboveComment(); - IASTCompletionNode node = getGPPCompletionNode(code); - assertNotNull(node); - List bindings= proposeBindings(node); - String[] names= getSortedNames(bindings); - assertEquals("B", names[0]); - assertEquals("doit", names[1]); + String[] expected= {"B", "doit"}; + checkCompletion(code, true, expected); } + + // typedef struct MyType { + // int aField; + // } MyType; + // M + public void testBug279931() throws Exception { + String code = getAboveComment(); + String[] expected= {"MyType", "MyType"}; + checkCompletion(code, true, expected); + expected= new String[] {"MyType"}; + checkCompletion(code, false, expected); + } + + // typedef struct MyType { + // int aField; + // } MyType; + // struct M + public void testBug279931a() throws Exception { + String code = getAboveComment(); + String[] expected= {"MyType"}; + checkCompletion(code, true, expected); + checkCompletion(code, false, expected); + } + } diff --git a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java index 4705080a62a..1b3ef8152d4 100644 --- a/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java +++ b/core/org.eclipse.cdt.core.tests/parser/org/eclipse/cdt/core/parser/tests/prefix/CompletionTestBase.java @@ -51,7 +51,7 @@ public class CompletionTestBase extends BaseTestCase { private static final IParserLogService NULL_LOG = new NullLogService(); protected IASTCompletionNode getCompletionNode(String code, ParserLanguage lang, boolean useGNUExtensions) throws ParserException { - CodeReader codeReader = new CodeReader(code.toCharArray()); + CodeReader codeReader = new CodeReader(code.trim().toCharArray()); ScannerInfo scannerInfo = new ScannerInfo(); IScanner scanner= AST2BaseTest.createScanner(codeReader, lang, ParserMode.COMPLETE_PARSE, scannerInfo); @@ -93,6 +93,18 @@ public class CompletionTestBase extends BaseTestCase { return getCompletionNode(code, ParserLanguage.C, true); } + protected void checkCompletion(String code, boolean isCpp, String[] expected) throws ParserException { + IASTCompletionNode node = isCpp ? getGPPCompletionNode(code) : getGCCCompletionNode(code); + assertNotNull(node); + List bindings= proposeBindings(node); + String[] names= getSortedNames(bindings); + int len= Math.min(expected.length, names.length); + for (int i = 0; i < len; i++) { + assertEquals(expected[i], names[i]); + } + assertEquals(expected.length, names.length); + } + private static class BindingsComparator implements Comparator { public int compare(Object o1, Object o2) { IBinding b1 = (IBinding)o1; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTElaboratedTypeSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTElaboratedTypeSpecifier.java index 0604e5ad64b..73fe3792277 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTElaboratedTypeSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTElaboratedTypeSpecifier.java @@ -23,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.ICompositeType; import org.eclipse.cdt.core.dom.ast.IEnumeration; +import org.eclipse.cdt.core.dom.ast.ITypedef; import org.eclipse.cdt.core.dom.ast.c.ICASTElaboratedTypeSpecifier; /** @@ -138,6 +139,8 @@ public class CASTElaboratedTypeSpecifier extends CASTBaseDeclSpecifier implement } else if (b instanceof IEnumeration) { if (getKind() != k_enum) b= null; + } else if (b instanceof ITypedef) { + b= null; } if (b != null) { result[nextPos++]= b; diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java index f190305a1d1..9d69b3178c6 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CVisitor.java @@ -85,7 +85,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.IGCCASTSimpleDeclSpecifier; import org.eclipse.cdt.core.index.IIndexBinding; import org.eclipse.cdt.core.index.IIndexFileSet; import org.eclipse.cdt.core.parser.util.ArrayUtil; -import org.eclipse.cdt.core.parser.util.CharArrayObjectMap; +import org.eclipse.cdt.core.parser.util.CharArraySet; import org.eclipse.cdt.core.parser.util.CharArrayUtils; import org.eclipse.cdt.internal.core.dom.parser.ASTInternal; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; @@ -1123,28 +1123,30 @@ public class CVisitor extends ASTQueries { } } - CharArrayObjectMap prefixMap = new CharArrayObjectMap(2); + IBinding[] result = null; + CharArraySet handled= new CharArraySet(1); while (scope != null) { try { if (!(scope instanceof ICCompositeTypeScope)) { IBinding[] bindings= scope.getBindings(name, true, true, fileSet); for (IBinding b : bindings) { final char[] n= b.getNameCharArray(); - if (!prefixMap.containsKey(n)) { - prefixMap.put(n, b); + // consider binding only if no binding with the same name was found in another scope. + if (!handled.containsKey(n)) { + result= (IBinding[]) ArrayUtil.append(IBinding.class, result, b); } } + // store names of bindings + for (IBinding b : bindings) { + final char[] n= b.getNameCharArray(); + handled.put(n); + } } } catch (DOMException e) { } scope= scope.getParent(); } - IBinding[] result = null; - Object[] vals = prefixMap.valueArray(); - for (Object val : vals) { - result = (IBinding[]) ArrayUtil.append(IBinding.class, result, val); - } return (IBinding[]) ArrayUtil.trim(IBinding.class, result); }