diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java index ef4c2f48a4d..3e105d44313 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTIdExpression.java @@ -1,14 +1,15 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Rational Software - Initial API and implementation - * Yuan Zhang / Beth Tibbitts (IBM Research) - * Bryan Wilkinson (QNX) + * IBM Rational Software - Initial API and implementation + * Yuan Zhang / Beth Tibbitts (IBM Research) + * Bryan Wilkinson (QNX) + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; @@ -17,7 +18,10 @@ import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTIdExpression; import org.eclipse.cdt.core.dom.ast.IASTName; 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.IType; +import org.eclipse.cdt.core.parser.util.ArrayUtil; /** * @author jcamelon @@ -77,6 +81,14 @@ public class CASTIdExpression extends CASTNode implements IASTIdExpression, IAST } public IBinding[] findBindings(IASTName n, boolean isPrefix) { - return CVisitor.findBindingsForContentAssist(n, isPrefix); + IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix); + + for (int i = 0; i < bindings.length; i++) { + if (bindings[i] instanceof IEnumeration || bindings[i] instanceof ICompositeType) { + 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/CASTTypedefNameSpecifier.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java index 974eb8765f6..6c9651d11f2 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/c/CASTTypedefNameSpecifier.java @@ -1,28 +1,25 @@ /******************************************************************************* - * Copyright (c) 2005, 2007 IBM Corporation and others. + * Copyright (c) 2005, 2008 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM Rational Software - Initial API and implementation - * Yuan Zhang / Beth Tibbitts (IBM Research) - * Bryan Wilkinson (QNX) + * IBM Rational Software - Initial API and implementation + * Yuan Zhang / Beth Tibbitts (IBM Research) + * Bryan Wilkinson (QNX) + * Anton Leherbauer (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.c; -import java.util.ArrayList; -import java.util.List; - import org.eclipse.cdt.core.dom.ast.ASTVisitor; import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTName; 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.ICASTTypedefNameSpecifier; +import org.eclipse.cdt.core.parser.util.ArrayUtil; /** * @author jcamelon @@ -77,16 +74,13 @@ public class CASTTypedefNameSpecifier extends CASTBaseDeclSpecifier implements public IBinding[] findBindings(IASTName n, boolean isPrefix) { IBinding[] bindings = CVisitor.findBindingsForContentAssist(n, isPrefix); - List filtered = new ArrayList(); - + for (int i = 0; i < bindings.length; i++) { - if (bindings[i] instanceof ICompositeType - || bindings[i] instanceof IEnumeration - || bindings[i] instanceof ITypedef) { - filtered.add(bindings[i]); + if (!(bindings[i] instanceof ITypedef)) { + bindings[i]= null; } } - return (IBinding[]) filtered.toArray(new IBinding[filtered.size()]); + return (IBinding[]) ArrayUtil.removeNulls(IBinding.class, bindings); } } 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 588dc9e7013..414b09e6615 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 @@ -33,6 +33,7 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { private static final String HEADER_FILE_NAME = "CompletionTest.h"; private static final String SOURCE_FILE_NAME = "CompletionTest.c"; private static final String CURSOR_LOCATION_TAG = "/*cursor*/"; + private static final String INCLUDE_LOCATION_TAG = "/*include*/"; private static final String DISTURB_FILE_NAME= "DisturbWith.c"; protected int fCursorOffset; @@ -44,6 +45,79 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { //struct Struct2; //union Union1; //union Union2; + // + //#define DEBUG 1 + //#define AMacro(x) x+1 + //#define XMacro(x,y) x+y + // + //int aVariable; + //int xVariable; + // + //void aFunction(); + //void xFunction(); + // + //enum anEnumeration { + // aFirstEnum, + // aSecondEnum, + // aThirdEnum + //}; + //typedef enum anEnumeration anEnumerationType; + // + //enum xEnumeration { + // xFirstEnum, + // xSecondEnum, + // xThirdEnum + //}; + //typedef enum xEnumeration xEnumerationType; + // + //struct AStruct{ + // int aStructField; + // int xaStructField; + //}; + //typedef struct AStruct AStructType; + // + //struct XStruct{ + // int xStructField; + // int axStructField; + //}; + //typedef struct XStruct XStructType; + // + //void anotherFunction(){ + // int aLocalDeclaration = 1; + //} + // + //void xOtherFunction(){ + // int xLocalDeclaration = 1; + //} + //#ifdef ANONYMOUS + //enum { + // anonFirstEnum, + // anonSecondEnum, + // anonThirdEnum + //}; + // + //enum { + // xanonFirstEnum, + // xanonSecondEnum, + // xanonThirdEnum + //}; + // + //int notAnonymous; + //enum notAnonymousEnum {}; + //struct notAnonymousStruct {}; + // + //struct { + // int anonStructField; + //}; + // + //struct { + // int xanonStructField; + //}; + // + //union { + // int anonUnionMember1, anonUnionMember2; + //}; + //#endif /* ANONYMOUS */ //{DisturbWith.c} // int gTemp; @@ -70,7 +144,8 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { fProject= project; String headerContent= readTaggedComment(HEADER_FILE_NAME); StringBuffer sourceContent= getContentsForTest(1)[0]; - sourceContent.insert(0, "#include \""+HEADER_FILE_NAME+"\"\n"); + int includeOffset= Math.max(0, sourceContent.indexOf(INCLUDE_LOCATION_TAG)); + sourceContent.insert(includeOffset, "#include \""+HEADER_FILE_NAME+"\"\n"); fCursorOffset= sourceContent.indexOf(CURSOR_LOCATION_TAG); assertTrue("No cursor location specified", fCursorOffset >= 0); sourceContent.delete(fCursorOffset, fCursorOffset+CURSOR_LOCATION_TAG.length()); @@ -141,10 +216,6 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { int idx= doc.get().indexOf(replace); doc.replace(idx, replace.length(), globalVar); - // succeeds when buffer is saved -// fEditor.doSave(new NullProgressMonitor()); -// EditorTestHelper.joinBackgroundActivities((AbstractTextEditor)fEditor); - final String[] expected= { "aNewGlobalVar" }; @@ -203,7 +274,7 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { // #include "header191315.h" // void xxx() { c_lin/*cursor*/ - public void testExtenC_bug191315() throws Exception { + public void testExternC_bug191315() throws Exception { StringBuffer[] content= getContentsForTest(3); createFile(fProject, "header191315.h", content[0].toString()); createFile(fProject, "source191315.c", content[0].toString()); @@ -215,4 +286,250 @@ public class CompletionTests_PlainC extends AbstractContentAssistTest { }; assertCompletionResults(expected); } + + //#define ANONYMOUS + ///*include*/ + ///*cursor*/ + public void testAnonymousTypes() throws Exception { + final String[] expected = { "AStructType", "XStructType", "anEnumerationType", "xEnumerationType"}; + assertCompletionResults(expected); + } + + //void foo ( a/*cursor*/ + public void testArgumentTypes_Prefix() throws Exception { + final String[] expected = { "AMacro(x)", "AStructType", "anEnumerationType" }; + assertCompletionResults(expected); + } + + //struct aThirdStruct { + // int x; + // /*cursor*/ + //}; + public void testFieldType_NoPrefix() throws Exception { + final String[] expected = { "AStructType", "XStructType", "anEnumerationType", "xEnumerationType" }; + assertCompletionResults(expected); + } + + //struct aThirdStruct { + // int x; + // a/*cursor*/ + //}; + public void testFieldType_Prefix() throws Exception { + final String[] expected = { "AMacro(x)", "AStructType", "anEnumerationType" }; + assertCompletionResults(expected); + } + + //#ifdef /*cursor*/ + public void testMacroRef_NoPrefix() throws Exception { + final String[] expected = { + "AMacro(x)", + "DEBUG", + "XMacro(x, y)", + "_Pragma(arg)", + "__CDT_PARSER__", + "__DATE__", + "__FILE__", + "__LINE__", + "__STDC_HOSTED_", + "__STDC_VERSION_", + "__STDC__", + "__TIME__", + "__asm__", + "__builtin_constant_p(exp)", + "__builtin_va_arg(ap, type)", + "__complex__", + "__const", + "__const__", + "__extension__", + "__imag__", + "__inline__", + "__null", + "__real__", + "__restrict", + "__restrict__", + "__signed__", + "__stdcall", + "__volatile__", + "__typeof__" + }; + assertCompletionResults(expected); + } + + //#ifdef D/*cursor*/ + public void testMacroRef_Prefix() throws Exception { + final String[] expected = { "DEBUG" }; + assertCompletionResults(expected); + } + + //void fooFunction() + //{ + // AStructType* c; + // c->/*cursor*/ + //} + public void testMemberReference_Arrow_NoPrefix() throws Exception { + final String[] expected = { + "aStructField", "xaStructField", + }; + assertCompletionResults(expected); + } + + //void main() { + // struct AStruct a, *ap; + // ap->/*cursor*/ + //} + public void testMemberReference_Arrow_NoPrefix2() throws Exception { + final String[] expected = { + "aStructField", "xaStructField", + }; + assertCompletionResults(expected); + } + + //void fooFunction() + //{ + // AStructType* c; + // c->a/*cursor*/ + //} + public void testMemberReference_Arrow_Prefix() throws Exception { + final String[] expected = { + "aStructField", + }; + assertCompletionResults(expected); + } + + //AStructType* foo(); + // + //void fooFunction() + //{ + // foo()->a/*cursor*/ + //} + public void testMemberReference_Arrow_Prefix2() throws Exception { + final String[] expected = { + "aStructField", + }; + assertCompletionResults(expected); + } + + //void fooFunction() + //{ + // AStructType c; + // c./*cursor*/ + //} + public void testMemberReference_Dot_NoPrefix() throws Exception { + final String[] expected = { + "aStructField", "xaStructField", + }; + assertCompletionResults(expected); + } + + //void fooFunction() + //{ + // AStructType c; + // c.a/*cursor*/ + //} + public void testMemberReference_Dot_Prefix() throws Exception { + final String[] expected = { + "aStructField", + }; + assertCompletionResults(expected); + } + + //typedef int myType; + // + //m/*cursor*/ + public void testTypeDef_Prefix() throws Exception { + final String[] expected = { + "myType", + }; + assertCompletionResults(expected); + } + + //void fooFunction(int x) + //{ + // /*cursor*/ + //} + public void testSingleName_Function_NoPrefix() throws Exception { + final String[] expected = { + "x", + "aVariable", + "xVariable", + "aFunction(void)", + "anotherFunction(void)", + "fooFunction(int)", + "xFunction(void)", + "xOtherFunction(void)", + "anEnumerationType", + "xEnumerationType", + "AStructType", + "XStructType", + "aFirstEnum", + "aSecondEnum", + "aThirdEnum", + "xFirstEnum", + "xSecondEnum", + "xThirdEnum", + "gGlobalInt" + }; + assertCompletionResults(expected); + } + + //void fooFunction(int x) + //{ + // a/*cursor*/ + //} + public void testSingleName_Function_Prefix() throws Exception { + final String[] expected = { + "AMacro(x)", + "AStructType", + "aVariable", + "aFunction(void)", + "anotherFunction(void)", + "anEnumerationType", + "aFirstEnum", + "aSecondEnum", + "aThirdEnum", + }; + assertCompletionResults(expected); + } + + //void fooFunction(int x) + //{ + // int y = /*cursor*/ + //} + public void testSingleName_Assignment_NoPrefix() throws Exception { + final String[] expected = { + "x", + "y", + "aVariable", + "xVariable", + "aFunction(void)", + "anotherFunction(void)", + "fooFunction(int)", + "xFunction(void)", + "xOtherFunction(void)", + "anEnumerationType", + "xEnumerationType", + "AStructType", + "XStructType", + "aFirstEnum", + "aSecondEnum", + "aThirdEnum", + "xFirstEnum", + "xSecondEnum", + "xThirdEnum", + "gGlobalInt" + }; + assertCompletionResults(expected); + } + + //void foo(int x) + //{ + // int y = AM/*cursor*/ + //} + public void testSingleName_Assignment_Prefix() throws Exception { + final String[] expected = { + "AMacro(x)" + }; + assertCompletionResults(expected); + } + }