1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-08-02 13:55:39 +02:00

Bug 434446 - [code assist] struct not being recognised as a valid base

class

structs are now being shown as candidates for base classes

while I was at it I also fixed proposals for typedefs, template
parameters and template aliases.

Change-Id: I319b06a195eed88a12969207a21584dc2477219e
Signed-off-by: Michi <woskimi@yahoo.de>
Reviewed-on: https://git.eclipse.org/r/38379
Reviewed-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
Tested-by: Sergey Prigogin <eclipse.sprigogin@gmail.com>
This commit is contained in:
Michi 2014-12-16 21:01:12 +01:00 committed by Sergey Prigogin
parent 5ba7b39f01
commit c647a52118
5 changed files with 93 additions and 88 deletions

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2011 IBM Corporation and others. * Copyright (c) 2004, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -9,6 +9,7 @@
* John Camelon (IBM) - Initial API and implementation * John Camelon (IBM) - Initial API and implementation
* Bryan Wilkinson (QNX) * Bryan Wilkinson (QNX)
* Markus Schorn (Wind River Systems) * Markus Schorn (Wind River Systems)
* Michael Woski
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.internal.core.dom.parser.cpp; package org.eclipse.cdt.internal.core.dom.parser.cpp;
@ -19,10 +20,14 @@ import org.eclipse.cdt.core.dom.ast.ASTVisitor;
import org.eclipse.cdt.core.dom.ast.IASTName; import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IBinding; import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext; import org.eclipse.cdt.core.dom.ast.ICPPASTCompletionContext;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier.ICPPASTBaseSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier; import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNameSpecifier;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPAliasTemplate;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType; import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateTypeParameter;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode; import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics; import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
@ -30,13 +35,11 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
* Base class specifier * Base class specifier
*/ */
public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier, ICPPASTCompletionContext { public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier, ICPPASTCompletionContext {
private boolean isVirtual; private boolean isVirtual;
private int visibility; private int visibility;
private ICPPASTNameSpecifier nameSpecifier; private ICPPASTNameSpecifier nameSpecifier;
private boolean fIsPackExpansion; private boolean fIsPackExpansion;
public CPPASTBaseSpecifier() { public CPPASTBaseSpecifier() {
} }
@ -157,12 +160,23 @@ public class CPPASTBaseSpecifier extends ASTNode implements ICPPASTBaseSpecifier
} }
for (IBinding binding : bindings) { for (IBinding binding : bindings) {
if (binding instanceof ICPPClassType) { if (binding instanceof IType) {
ICPPClassType base = (ICPPClassType) binding; IType type = (IType) binding;
int key = base.getKey();
if (key == ICPPClassType.k_class && while (type instanceof ITypedef || type instanceof ICPPAliasTemplate) {
(classType == null || !base.isSameType(classType))) { type = type instanceof ITypedef ?
filtered.add(base); ((ITypedef) type).getType() : ((ICPPAliasTemplate) type).getType();
}
if (type instanceof ICPPClassType) {
int key = ((ICPPClassType) type).getKey();
if ((key == ICPPClassType.k_class || key == ICPPClassType.k_struct
|| type instanceof ICPPDeferredClassInstance || type instanceof ICPPUnknownMemberClass)
&& (classType == null || !type.isSameType(classType))) {
filtered.add(binding);
}
} else if (type instanceof ICPPTemplateTypeParameter) {
filtered.add(binding);
} }
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2009, 2013 Google, Inc and others. * Copyright (c) 2009, 2014 Google, Inc and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -29,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPMember;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod; import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope; import org.eclipse.cdt.core.dom.ast.cpp.ICPPScope;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization; import org.eclipse.cdt.core.dom.ast.cpp.ICPPSpecialization;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
import org.eclipse.cdt.core.parser.util.ArrayUtil; import org.eclipse.cdt.core.parser.util.ArrayUtil;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper; import org.eclipse.cdt.internal.core.dom.parser.cpp.ClassTypeHelper;
import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance; import org.eclipse.cdt.internal.core.dom.parser.cpp.ICPPDeferredClassInstance;
@ -76,7 +77,8 @@ public class AccessContext {
*/ */
private boolean isUnqualifiedLookup; private boolean isUnqualifiedLookup;
private ICPPClassType namingClass; // depends on the binding for which we check the access private ICPPClassType namingClass; // depends on the binding for which we check the access
private ICPPClassType firstCandidateForNamingClass; // the first candidate is independent of the binding for which we do the access-check // The first candidate is independent of the binding for which we do the access-check.
private ICPPClassType firstCandidateForNamingClass;
private DOMException initializationException; private DOMException initializationException;
public AccessContext(IASTName name) { public AccessContext(IASTName name) {
@ -89,6 +91,9 @@ public class AccessContext {
* @return <code>true</code> if the binding is accessible. * @return <code>true</code> if the binding is accessible.
*/ */
public boolean isAccessible(IBinding binding) { public boolean isAccessible(IBinding binding) {
if (binding instanceof ICPPTemplateParameter)
return true;
int bindingVisibility; int bindingVisibility;
if (binding instanceof ICPPMember) { if (binding instanceof ICPPMember) {
bindingVisibility = ((ICPPMember) binding).getVisibility(); bindingVisibility = ((ICPPMember) binding).getVisibility();
@ -97,7 +102,8 @@ public class AccessContext {
binding = ((ICPPSpecialization) binding).getSpecializedBinding(); binding = ((ICPPSpecialization) binding).getSpecializedBinding();
} }
if (binding instanceof ICPPClassTemplatePartialSpecialization) { if (binding instanceof ICPPClassTemplatePartialSpecialization) {
// A class template partial specialization inherits the visibility of its primary class template. // A class template partial specialization inherits the visibility of its primary
// class template.
binding = ((ICPPClassTemplatePartialSpecialization) binding).getPrimaryClassTemplate(); binding = ((ICPPClassTemplatePartialSpecialization) binding).getPrimaryClassTemplate();
} }
if (binding instanceof ICPPAliasTemplateInstance) { if (binding instanceof ICPPAliasTemplateInstance) {

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -17,12 +17,11 @@ import junit.framework.TestSuite;
/** /**
* @author hamer * @author hamer
* *
* Testing Class_Reference, with No prefix * Testing class reference, with no prefix
* Bug#50621 :Wrong completion kind in a class declaration * https://bugs.eclipse.org/bugs/show_bug.cgi?id=50621
* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=169860
*/ */
public class CompletionTest_ClassReference_NoPrefix extends CompletionProposalsBaseTest{ public class CompletionTest_ClassReference_NoPrefix extends CompletionProposalsBaseTest{
private final String fileName = "CompletionTestStart21.h"; private final String fileName = "CompletionTestStart21.h";
private final String fileFullPath ="resources/contentassist/" + fileName; private final String fileFullPath ="resources/contentassist/" + fileName;
private final String headerFileName = "CompletionTestStart.h"; private final String headerFileName = "CompletionTestStart.h";
@ -31,12 +30,13 @@ public class CompletionTest_ClassReference_NoPrefix extends CompletionProposals
private final String[] expectedResults = { private final String[] expectedResults = {
"aClass", "aClass",
"anotherClass", "anotherClass",
"xOtherClass" "xOtherClass",
"AStruct",
"XStruct"
}; };
public CompletionTest_ClassReference_NoPrefix(String name) { public CompletionTest_ClassReference_NoPrefix(String name) {
super(name); super(name);
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=169860
} }
public static Test suite() { public static Test suite() {
@ -45,59 +45,38 @@ public class CompletionTest_ClassReference_NoPrefix extends CompletionProposals
return suite; return suite;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getCompletionPosition()
*/
@Override @Override
protected int getCompletionPosition() { protected int getCompletionPosition() {
return getBuffer().indexOf(" ") + 2; return getBuffer().indexOf(" ") + 2;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedPrefix()
*/
@Override @Override
protected String getExpectedPrefix() { protected String getExpectedPrefix() {
return expectedPrefix; return expectedPrefix;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedResultsValues()
*/
@Override @Override
protected String[] getExpectedResultsValues() { protected String[] getExpectedResultsValues() {
return expectedResults; return expectedResults;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileName()
*/
@Override @Override
protected String getFileName() { protected String getFileName() {
return fileName; return fileName;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileFullPath()
*/
@Override @Override
protected String getFileFullPath() { protected String getFileFullPath() {
return fileFullPath; return fileFullPath;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileFullPath()
*/
@Override @Override
protected String getHeaderFileFullPath() { protected String getHeaderFileFullPath() {
return headerFileFullPath; return headerFileFullPath;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileName()
*/
@Override @Override
protected String getHeaderFileName() { protected String getHeaderFileName() {
return headerFileName; return headerFileName;
} }
} }

View file

@ -1,5 +1,5 @@
/******************************************************************************* /*******************************************************************************
* Copyright (c) 2004, 2007 IBM Corporation and others. * Copyright (c) 2004, 2014 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials * All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0 * are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at * which accompanies this distribution, and is available at
@ -17,86 +17,64 @@ import junit.framework.TestSuite;
/** /**
* @author hamer * @author hamer
* *
* Testing Class_Reference, with prefix * Testing class reference, with prefix
* Bug#50621 :Wrong completion kind in a class declaration * https://bugs.eclipse.org/bugs/show_bug.cgi?id=50621
* * https://bugs.eclipse.org/bugs/show_bug.cgi?id=169860
*/ */
public class CompletionTest_ClassReference_Prefix extends CompletionProposalsBaseTest{ public class CompletionTest_ClassReference_Prefix extends CompletionProposalsBaseTest{
private final String fileName = "CompletionTestStart20.h";
private final String fileName = "CompletionTestStart20.h"; //$NON-NLS-1$ private final String fileFullPath ="resources/contentassist/" + fileName;
private final String fileFullPath ="resources/contentassist/" + fileName; //$NON-NLS-1$ private final String headerFileName = "CompletionTestStart.h";
private final String headerFileName = "CompletionTestStart.h"; //$NON-NLS-1$ private final String headerFileFullPath ="resources/contentassist/" + headerFileName;
private final String headerFileFullPath ="resources/contentassist/" + headerFileName; //$NON-NLS-1$ private final String expectedPrefix = "a";
private final String expectedPrefix = "a"; //$NON-NLS-1$
private final String[] expectedResults = { private final String[] expectedResults = {
"aClass", //$NON-NLS-1$ "aClass",
"anotherClass" //$NON-NLS-1$ "anotherClass",
"AStruct"
}; };
public CompletionTest_ClassReference_Prefix(String name) { public CompletionTest_ClassReference_Prefix(String name) {
super(name); super(name);
// https://bugs.eclipse.org/bugs/show_bug.cgi?id=169860
} }
public static Test suite() { public static Test suite() {
TestSuite suite= new TestSuite(CompletionTest_ClassReference_Prefix.class.getName()); TestSuite suite= new TestSuite(CompletionTest_ClassReference_Prefix.class.getName());
suite.addTest(new CompletionTest_ClassReference_Prefix("testCompletionProposals")); //$NON-NLS-1$ suite.addTest(new CompletionTest_ClassReference_Prefix("testCompletionProposals"));
return suite; return suite;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getCompletionPosition()
*/
@Override @Override
protected int getCompletionPosition() { protected int getCompletionPosition() {
return getBuffer().indexOf(" a ") + 2; //$NON-NLS-1$ return getBuffer().indexOf(" a ") + 2;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedPrefix()
*/
@Override @Override
protected String getExpectedPrefix() { protected String getExpectedPrefix() {
return expectedPrefix; return expectedPrefix;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getExpectedResultsValues()
*/
@Override @Override
protected String[] getExpectedResultsValues() { protected String[] getExpectedResultsValues() {
return expectedResults; return expectedResults;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileName()
*/
@Override @Override
protected String getFileName() { protected String getFileName() {
return fileName; return fileName;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getFileFullPath()
*/
@Override @Override
protected String getFileFullPath() { protected String getFileFullPath() {
return fileFullPath; return fileFullPath;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileFullPath()
*/
@Override @Override
protected String getHeaderFileFullPath() { protected String getHeaderFileFullPath() {
return headerFileFullPath; return headerFileFullPath;
} }
/* (non-Javadoc)
* @see org.eclipse.cdt.core.codeassist.tests.CompletionProposalsTest#getHeaderFileName()
*/
@Override @Override
protected String getHeaderFileName() { protected String getHeaderFileName() {
return headerFileName; return headerFileName;
} }
} }

View file

@ -14,6 +14,7 @@
* Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion) * Jens Elmenthaler - http://bugs.eclipse.org/173458 (camel case completion)
* Nathan Ridge * Nathan Ridge
* Thomas Corbat (IFS) * Thomas Corbat (IFS)
* Michael Woski
*******************************************************************************/ *******************************************************************************/
package org.eclipse.cdt.ui.tests.text.contentassist2; package org.eclipse.cdt.ui.tests.text.contentassist2;
@ -194,6 +195,12 @@ public class CompletionTests extends AbstractContentAssistTest {
// template<> // template<>
// struct Specialization<int, int> { // struct Specialization<int, int> {
// }; // };
//
// template<typename T1, typename T2>
// using AliasForSpecialization = Specialization<T1, T2>;
//
// template<typename T1, typename T2>
// using AliasForTemplateAlias = AliasForSpecialization<T1, T2>;
public CompletionTests(String name) { public CompletionTests(String name) {
super(name, true); super(name, true);
@ -706,6 +713,27 @@ public class CompletionTests extends AbstractContentAssistTest {
assertCompletionResults(fCursorOffset, expected, REPLACEMENT); assertCompletionResults(fCursorOffset, expected, REPLACEMENT);
} }
// class BaseTest : Spec/*cursor*/
public void testBaseClassIsStruct_434446() throws Exception {
final String[] expected = { "Specialization<>" };
assertCompletionResults(fCursorOffset, expected, REPLACEMENT);
}
// class BaseTest : Alias/*cursor*/
public void testBaseClassIsTemplateAlias_434446() throws Exception {
// TODO Bug 455797, proposals are currently not presented as templates.
final String[] expected = { "AliasForSpecialization",
"AliasForTemplateAlias" };
assertCompletionResults(fCursorOffset, expected, ID);
}
// template<typename TP_Param>
// class BaseTest : TP/*cursor*/
public void testBaseClassIsTemplateParameter() throws Exception {
final String[] expected = { "TP_Param" };
assertCompletionResults(fCursorOffset, expected, REPLACEMENT);
}
// struct A {}; // struct A {};
// //
// template<typename T> // template<typename T>