1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-23 06:32:10 +02:00

Content assist for ctor initializer list by Jens Elmenthaler, bug 266586.

This commit is contained in:
Markus Schorn 2009-03-04 08:38:45 +00:00
parent d128bcecf4
commit 2d44a1f492
4 changed files with 191 additions and 8 deletions

View file

@ -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 <br>
* <code>
* Derived() : Base(), field() { <br>
* }
* </code><br>
* {@code Base()} and {@code field()} are the constructor chain initializers.<br>
*/
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;
}
}

View file

@ -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 {

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
@ -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;

View file

@ -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
@ -1215,4 +1215,105 @@ public class CompletionTests extends AbstractContentAssistTest {
assertCompletionResults(fCursorOffset, expected, COMPARE_REP_STRINGS);
}
//namespace ns {
// template<class T>
// class Base {
// public:
// Base(int par) {}
// };
//}
//
//class Helper {
//public:
// Helper() {}
//};
//
//class InitializerListTest : public ::ns::Base<Helper>, 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> &)",
"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<Helper>() instead of just Base<Helper>().
"ns"};
assertCompletionResults(fCursorOffset, expected, COMPARE_ID_STRINGS);
}
//namespace ns {
// template<class T>
// class Base {
// public:
// Base(int par) {}
// };
//}
//
//class Helper {
//public:
// Helper() {}
//};
//
//class InitializerListTest : public ::ns::Base<Helper>, 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 T>
// class Base {
// public:
// Base(int par) {}
// };
//}
//
//class Helper {
//public:
// Helper() {}
//};
//
//class InitializerListTest : public ::ns::Base<Helper>, 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 T>
// class Base {
// public:
// Base(int par) {}
// };
//}
//
//class Helper {
//public:
// Helper() {}
//};
//
//class InitializerListTest : public ::ns::Base<Helper>, 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);
}
}