diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java index 1cae1d16a37..f1969520b3e 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/dom/parser/cpp/CPPASTConstructorChainInitializer.java @@ -1,29 +1,45 @@ /******************************************************************************* - * 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 * http://www.eclipse.org/legal/epl-v10.html * * Contributors: - * IBM - Initial API and implementation + * John Camelon (IBM) - Initial API and implementation * Markus Schorn (Wind River Systems) *******************************************************************************/ package org.eclipse.cdt.internal.core.dom.parser.cpp; +import java.util.Arrays; + import org.eclipse.cdt.core.dom.ast.ASTVisitor; +import org.eclipse.cdt.core.dom.ast.IASTCompletionContext; import org.eclipse.cdt.core.dom.ast.IASTExpression; import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTNode; +import org.eclipse.cdt.core.dom.ast.IBinding; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPConstructor; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPField; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPNamespace; +import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; +import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.IASTAmbiguityParent; +import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; /** - * @author jcamelon + * For example in the constructor definition
+ * + * Derived() : Base(), field() {
+ * } + *

+ * {@code Base()} and {@code field()} are the constructor chain initializers.
*/ public class CPPASTConstructorChainInitializer extends ASTNode implements - ICPPASTConstructorChainInitializer, IASTAmbiguityParent { + ICPPASTConstructorChainInitializer, IASTAmbiguityParent, IASTCompletionContext { private IASTName name; private IASTExpression value; @@ -109,4 +125,52 @@ public class CPPASTConstructorChainInitializer extends ASTNode implements value = (IASTExpression) other; } } + + public IBinding[] findBindings(IASTName n, boolean isPrefix) { + IBinding[] bindings = CPPSemantics.findBindingsForContentAssist(n, isPrefix); + + ICPPASTBaseSpecifier[] baseClasses = null; + + for (int i = 0; i < bindings.length; i++) { + + if ((bindings[i] instanceof ICPPField) || (bindings[i] instanceof ICPPNamespace)) { + continue; + } else if (bindings[i] instanceof ICPPConstructor) { + + if (baseClasses == null) { + baseClasses = getBaseClasses(n); + } + boolean isBaseClassConstructor = false; + if (baseClasses != null) { + for (ICPPASTBaseSpecifier b : baseClasses) { + char[] bindingName = bindings[i].getNameCharArray(); + char[] baseName = b.getName().getLastName().getSimpleID(); + if (Arrays.equals(bindingName, baseName)) { + isBaseClassConstructor = true; + break; + } + } + } + + if (!isBaseClassConstructor) { + bindings[i] = null; + } + } else { + bindings[i] = null; + } + } + return (IBinding[]) ArrayUtil.removeNulls(IBinding.class, bindings); + } + + private ICPPASTBaseSpecifier[] getBaseClasses(IASTName name) { + for (IASTNode parent = name.getParent(); parent != null; parent = parent.getParent()) { + if (parent instanceof ICPPASTCompositeTypeSpecifier) { + ICPPASTCompositeTypeSpecifier specifier = (ICPPASTCompositeTypeSpecifier) parent; + + return specifier.getBaseSpecifiers(); + } + } + + return null; + } } diff --git a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java index 068f8c69083..429b573a469 100644 --- a/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java +++ b/core/org.eclipse.cdt.core/parser/org/eclipse/cdt/internal/core/parser/InternalParserUtil.java @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2003, 2008 IBM Corporation and others. + * Copyright (c) 2003, 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 @@ -20,6 +20,7 @@ import org.eclipse.cdt.core.parser.CodeReader; import org.eclipse.cdt.core.parser.ParserFactory; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IResource; +import org.eclipse.core.resources.IResourceStatus; import org.eclipse.core.resources.ResourcesPlugin; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; @@ -62,7 +63,18 @@ public class InternalParserUtil extends ParserFactory { */ public static CodeReader createWorkspaceFileReader(String path, IFile file) throws CoreException, IOException{ path = normalizePath(path, file); - InputStream in= file.getContents(true); + InputStream in; + try { + in= file.getContents(true); + } catch (CoreException e) { + switch (e.getStatus().getCode()) { + case IResourceStatus.NOT_FOUND_LOCAL: + case IResourceStatus.NO_LOCATION_LOCAL: + case IResourceStatus.FAILED_READ_LOCAL: + return null; + } + throw e; + } try { return new CodeReader(path, file.getCharset(), in); } finally { diff --git a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java index 15d0bb59038..5edd645865e 100644 --- a/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java +++ b/core/org.eclipse.cdt.ui.tests/ui/org/eclipse/cdt/ui/tests/text/contentassist2/AbstractContentAssistTest.java @@ -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 @@ -40,6 +40,8 @@ import org.eclipse.cdt.ui.tests.text.EditorTestHelper; import org.eclipse.cdt.ui.text.ICCompletionProposal; import org.eclipse.cdt.ui.text.ICPartitions; +import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNameBase; + import org.eclipse.cdt.internal.ui.text.contentassist.CCompletionProposal; import org.eclipse.cdt.internal.ui.text.contentassist.CContentAssistProcessor; import org.eclipse.cdt.internal.ui.text.contentassist.RelevanceConstants; @@ -60,6 +62,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { fIsCpp= isCpp; } + @Override protected void setUp() throws Exception { super.setUp(); if (fIsCpp) { @@ -73,6 +76,8 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { CCorePlugin.getIndexManager().joinIndexer(8000, new NullProgressMonitor()); fEditor= (ITextEditor)EditorTestHelper.openInEditor(fCFile, true); assertNotNull(fEditor); + CPPASTNameBase.sAllowNameComputation= true; + // EditorTestHelper.joinBackgroundActivities((AbstractTextEditor)fEditor); } @@ -84,6 +89,7 @@ public abstract class AbstractContentAssistTest extends BaseUITestCase { */ protected abstract IFile setUpProjectContent(IProject project) throws Exception; + @Override protected void tearDown() throws Exception { EditorTestHelper.closeEditor(fEditor); fEditor= null; 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 6fb5236df48..cb8a5406f06 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 @@ -1,5 +1,5 @@ /******************************************************************************* - * Copyright (c) 2006, 2008 Wind River Systems, Inc. and others. + * Copyright (c) 2006, 2009 Wind River Systems, Inc. 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 @@ -1214,5 +1214,106 @@ public class CompletionTests extends AbstractContentAssistTest { final String[] expected= {"add()"}; assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS); } + + //namespace ns { + // template + // class Base { + // public: + // Base(int par) {} + // }; + //} + // + //class Helper { + //public: + // Helper() {} + //}; + // + //class InitializerListTest : public ::ns::Base, Helper { + //private: + // int mOne; + //public: + // InitializerListTest() : /*cursor*/ + //}; + public void testCunstructorInitializerList_EmptyInput_Bug266586() throws Exception { + final String[] expected= {"mOne", + "Base(int)", "Base(const ns::Base &)", + "Helper(void)", "Helper(const Helper &)", + // Namespaces must be offered as well. In order for this code + // to compile with gcc (e.g. 4.1.2), you need to write + // ::ns::Base() instead of just Base(). + "ns"}; + assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS); + } + //namespace ns { + // template + // class Base { + // public: + // Base(int par) {} + // }; + //} + // + //class Helper { + //public: + // Helper() {} + //}; + // + //class InitializerListTest : public ::ns::Base, Helper { + //private: + // int mOne; + //public: + // InitializerListTest() : ::ns/*cursor*/ + //}; + public void testCunstructorInitializerList_NameContextInput_Bug266586() throws Exception { + final String[] expected= { "ns" }; + assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS); + } + + //namespace ns { + // template + // class Base { + // public: + // Base(int par) {} + // }; + //} + // + //class Helper { + //public: + // Helper() {} + //}; + // + //class InitializerListTest : public ::ns::Base, Helper { + //private: + // int mOne; + //public: + // InitializerListTest() : m/*cursor*/ + //}; + public void testCunstructorInitializerList_MemberInput_Bug266586() throws Exception { + final String[] expected= { "mOne" }; + assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS); + } + + //namespace ns { + // template + // class Base { + // public: + // Base(int par) {} + // }; + //} + // + //class Helper { + //public: + // Helper() {} + //}; + // + //class InitializerListTest : public ::ns::Base, Helper { + //private: + // int mOne; + //public: + // InitializerListTest() : h/*cursor*/ + //}; + public void testCunstructorInitializerList_BaseClassInput_Bug266586() throws Exception { + final String[] expected= { "Helper(void)", "Helper(const Helper &)" }; + assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS); + } } \ No newline at end of file