diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java index a814d15aa80..4af7a759751 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTName.java @@ -13,19 +13,24 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ILinkage; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; +import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.ICompositeType; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.Linkage; /** * @author jcamelon */ -public class CASTName extends CASTNode implements IASTName { +public class CASTName extends CASTNode implements IASTName, IASTCompletionContext { private final char[] name; @@ -63,7 +68,9 @@ public class CASTName extends CASTNode implements IASTName { } node = node.getParent(); } - + if (getLength() > 0) { + return this; + } return null; } @@ -155,4 +162,51 @@ public class CASTName extends CASTNode implements IASTName { public ILinkage getLinkage() { return Linkage.C_LINKAGE; } + + public IBinding[] findBindings(IASTName n, boolean isPrefix) { + IASTNode parent = getParent(); + if (parent instanceof IASTElaboratedTypeSpecifier) { + IASTElaboratedTypeSpecifier specifier = (IASTElaboratedTypeSpecifier) parent; + int kind = specifier.getKind(); + switch (kind) { + case IASTElaboratedTypeSpecifier.k_struct: + case IASTElaboratedTypeSpecifier.k_union: + break; + default: + return null; + } + IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix); + return filterByElaboratedTypeSpecifier(kind, bindings); + } + return null; + } + + private IBinding[] filterByElaboratedTypeSpecifier(int kind, IBinding[] bindings) { + for (int i = 0; i < bindings.length; i++) { + if (bindings[i] instanceof ICompositeType) { + ICompositeType type = (ICompositeType) bindings[i]; + + try { + switch (type.getKey()) { + case ICompositeType.k_struct: + if (kind != IASTElaboratedTypeSpecifier.k_struct) { + bindings[i] = null; + } + break; + case ICompositeType.k_union: + if (kind != IASTElaboratedTypeSpecifier.k_union) { + bindings[i] = null; + } + break; + } + } catch (DOMException e) { + bindings[i] = null; + CCorePlugin.log(e); + } + } else { + bindings[i]= null; + } + } + return (IBinding[])ArrayUtil.removeNulls(IBinding.class, bindings); + } } 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 1299665fcb3..705598926bd 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 @@ -1404,6 +1404,12 @@ public class CVisitor { char [] n = name.toCharArray(); if( declSpec instanceof ICASTElaboratedTypeSpecifier ){ tempName = ((ICASTElaboratedTypeSpecifier)declSpec).getName(); + + // Don't include the query name in the results + if (tempName == name) { + return null; + } + if( scope != null ) ASTInternal.addName( scope, tempName ); if( typesOnly ){ diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java index 7c8bef7eb36..43c353e7d69 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTName.java @@ -13,7 +13,9 @@ *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import org.eclipse.cdt.core.CCorePlugin; import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.DOMException; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTDeclarator; import org.eclipse.cdt.core.dom.ast.IASTName; @@ -21,6 +23,7 @@ import org.eclipse.cdt.core.dom.ast.IASTNameOwner; import org.eclipse.cdt.core.dom.ast.IASTNode; import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IProblemBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTElaboratedTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; import org.eclipse.cdt.core.parser.util.ArrayUtil; @@ -91,12 +94,27 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo } public IBinding[] findBindings(IASTName n, boolean isPrefix) { - if (getParent() instanceof IASTDeclarator) { + IASTNode parent = getParent(); + if (parent instanceof ICPPASTElaboratedTypeSpecifier) { + ICPPASTElaboratedTypeSpecifier specifier = (ICPPASTElaboratedTypeSpecifier) parent; + int kind = specifier.getKind(); + switch (kind) { + case ICPPASTElaboratedTypeSpecifier.k_struct: + case ICPPASTElaboratedTypeSpecifier.k_union: + case ICPPASTElaboratedTypeSpecifier.k_class: + break; + default: + return null; + } + IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix); + return filterByElaboratedTypeSpecifier(kind, bindings); + } + else if (parent instanceof IASTDeclarator) { IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix); for (int i = 0; i < bindings.length; i++) { if (bindings[i] instanceof ICPPNamespace || bindings[i] instanceof ICPPClassType) { } else { - bindings[i]= null; + bindings[i] = null; } } return (IBinding[])ArrayUtil.removeNulls(IBinding.class, bindings); @@ -104,7 +122,41 @@ public class CPPASTName extends CPPASTNode implements IASTName, IASTCompletionCo return null; } - public void setBinding(IBinding binding) { + private IBinding[] filterByElaboratedTypeSpecifier(int kind, IBinding[] bindings) { + for (int i = 0; i < bindings.length; i++) { + if (bindings[i] instanceof ICPPNamespace) { + } else if (bindings[i] instanceof ICPPClassType) { + ICPPClassType type = (ICPPClassType) bindings[i]; + try { + switch (type.getKey()) { + case ICPPClassType.k_struct: + if (kind != ICPPASTElaboratedTypeSpecifier.k_struct) { + bindings[i] = null; + } + break; + case ICPPClassType.k_union: + if (kind != ICPPASTElaboratedTypeSpecifier.k_union) { + bindings[i] = null; + } + break; + case ICPPClassType.k_class: + if (kind != ICPPASTElaboratedTypeSpecifier.k_class) { + bindings[i] = null; + } + break; + } + } catch (DOMException e) { + bindings[i] = null; + CCorePlugin.log(e); + } + } else { + bindings[i]= null; + } + } + return (IBinding[])ArrayUtil.removeNulls(IBinding.class, bindings); + } + + public void setBinding(IBinding binding) { this.binding = binding; fResolutionDepth= 0; } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java index 3a84ffdcfd4..fae9f90fc3e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests.java @@ -9,6 +9,7 @@ * Anton Leherbauer (Wind River Systems) - initial API and implementation * Bryan Wilkinson (QNX) * Markus Schorn (Wind River Systems) + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.contentassist2; @@ -141,6 +142,10 @@ public class CompletionTests extends AbstractContentAssistTest { // static unsigned char port; //protected: //}; +//struct Struct1; +//struct Struct2; +//union Union1; +//union Union2; public CompletionTests(String name) { super(name, true); @@ -830,4 +835,58 @@ public class CompletionTests extends AbstractContentAssistTest { assertTrue(CCorePlugin.getIndexManager().joinIndexer(8000, NPM)); assertCompletionResults(fCursorOffset, expected2, AbstractContentAssistTest.COMPARE_REP_STRINGS); } + + // struct Struct/*cursor*/ + public void testElaboratedTypeSpecifierStruct_bug208710() throws Exception { + final String[] expected= { "Struct1", "Struct2" }; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // struct Union/*cursor*/ + public void testElaboratedTypeSpecifierNotStruct_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // struct C/*cursor*/ + public void testElaboratedTypeSpecifierNotStruct2_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // union Union/*cursor*/ + public void testElaboratedTypeSpecifierUnion_bug208710() throws Exception { + final String[] expected= { "Union1", "Union2" }; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // union Struct/*cursor*/ + public void testElaboratedTypeSpecifierNotUnion_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // union C/*cursor*/ + public void testElaboratedTypeSpecifierNotUnion2_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // class C/*cursor*/ + public void testElaboratedTypeSpecifierClass_bug208710() throws Exception { + final String[] expected= { "C1", "C2", "C3" }; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // class Struct/*cursor*/ + public void testElaboratedTypeSpecifierNotClass_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } + + // class Union/*cursor*/ + public void testElaboratedTypeSpecifierNotClass2_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(fCursorOffset, expected, AbstractContentAssistTest.COMPARE_REP_STRINGS); + } } diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java index 5b86e5a72ac..11debb27e6c 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/CompletionTests_PlainC.java @@ -8,6 +8,7 @@ * Contributors: * Anton Leherbauer (Wind River Systems) - initial API and implementation * Markus Schorn (Wind River Systems) + * IBM Corporation *******************************************************************************/ package org.eclipse.cdt.ui.tests.text.contentassist2; @@ -38,6 +39,10 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { //{CompletionTest.h} //int gGlobalInt; + //struct Struct1; + //struct Struct2; + //union Union1; + //union Union2; //{DisturbWith.c} // int gTemp; @@ -153,4 +158,28 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { }; assertCompletionResults(expected); } + + // struct Struct/*cursor*/ + public void testElaboratedTypeSpecifierStruct_bug208710() throws Exception { + final String[] expected= { "Struct1", "Struct2" }; + assertCompletionResults(expected); + } + + // struct Union/*cursor*/ + public void testElaboratedTypeSpecifierNotStruct_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(expected); + } + + // union Union/*cursor*/ + public void testElaboratedTypeSpecifierUnion_bug208710() throws Exception { + final String[] expected= { "Union1", "Union2" }; + assertCompletionResults(expected); + } + + // union Struct/*cursor*/ + public void testElaboratedTypeSpecifierNotUnion_bug208710() throws Exception { + final String[] expected= new String[0]; + assertCompletionResults(expected); + } }