mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-04-29 19:45:01 +02:00
Bug 331963: Extract local variable doesn't put template type parameters
https://bugs.eclipse.org/bugs/show_bug.cgi?id=331963 patch and test cases
This commit is contained in:
parent
bb65ee266a
commit
54165f3720
2 changed files with 100 additions and 8 deletions
|
@ -28,6 +28,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPointer;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.IArrayType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
|
||||
|
@ -40,9 +41,12 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
|||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTPointerToMember;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTReferenceOperator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPPointerToMemberType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPReferenceType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.dom.rewrite.DeclarationGenerator;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
|
||||
|
@ -111,6 +115,9 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
|
|||
declSpec.setSigned(basicType.isSigned());
|
||||
declSpec.setUnsigned(basicType.isUnsigned());
|
||||
returnedDeclSpec = declSpec;
|
||||
} else if (type instanceof ICPPTemplateInstance) {
|
||||
returnedDeclSpec = getDeclSpecForTemplate((ICPPTemplateInstance) type);
|
||||
|
||||
} else if (type instanceof IBinding) { /* ITypedef, ICompositeType... */
|
||||
// BTW - we need to distinguish (and fail explicitly) on literal composites like:
|
||||
// struct { } aSingleInstance;
|
||||
|
@ -293,24 +300,43 @@ public class DeclarationGeneratorImpl extends DeclarationGenerator {
|
|||
return isPtrOrRefType(type) || type instanceof IArrayType || type instanceof IFunctionType;
|
||||
}
|
||||
|
||||
private IASTNamedTypeSpecifier getDeclSpecForBinding(IBinding binding) {
|
||||
private IASTDeclSpecifier getDeclSpecForTemplate(ICPPTemplateInstance type) {
|
||||
IASTName name = getName(type);
|
||||
if (factory instanceof ICPPNodeFactory) {
|
||||
ICPPNodeFactory cppFactory = (ICPPNodeFactory) factory;
|
||||
ICPPASTTemplateId tempId = cppFactory.newTemplateId(name);
|
||||
for (ICPPTemplateArgument arg : type.getTemplateArguments()) {
|
||||
IASTDeclSpecifier argDeclSpec = createDeclSpecFromType(arg.isTypeValue() ? arg
|
||||
.getTypeValue() : arg.getTypeOfNonTypeValue());
|
||||
IASTTypeId typeId = cppFactory.newTypeId(argDeclSpec, null);
|
||||
tempId.addTemplateArgument(typeId);
|
||||
}
|
||||
return factory.newTypedefNameSpecifier(tempId);
|
||||
}
|
||||
return factory.newTypedefNameSpecifier(name);
|
||||
}
|
||||
|
||||
private IASTNamedTypeSpecifier getDeclSpecForBinding(IBinding binding) {
|
||||
IASTName name = getName(binding);
|
||||
return factory.newTypedefNameSpecifier(name);
|
||||
}
|
||||
|
||||
private IASTName getName(IBinding binding) {
|
||||
char[][] qualifiedNameCharArray = CPPVisitor.getQualifiedNameCharArray(binding);
|
||||
IASTName name;
|
||||
if (qualifiedNameCharArray.length > 1) {
|
||||
|
||||
ICPPASTQualifiedName name = ((ICPPNodeFactory) factory).newQualifiedName();
|
||||
name = ((ICPPNodeFactory) factory).newQualifiedName();
|
||||
for (char[] cs : qualifiedNameCharArray) {
|
||||
name.addName(factory.newName(cs));
|
||||
((ICPPASTQualifiedName) name).addName(factory.newName(cs));
|
||||
}
|
||||
return factory.newTypedefNameSpecifier(name);
|
||||
|
||||
} else if (qualifiedNameCharArray.length == 1) {
|
||||
IASTName name = factory.newName(qualifiedNameCharArray[0]);
|
||||
return factory.newTypedefNameSpecifier(name);
|
||||
name = factory.newName(qualifiedNameCharArray[0]);
|
||||
} else {
|
||||
IASTName name = factory.newName(binding.getName().toCharArray());
|
||||
return factory.newTypedefNameSpecifier(name);
|
||||
name = factory.newName(binding.getName().toCharArray());
|
||||
}
|
||||
return name;
|
||||
}
|
||||
|
||||
}
|
|
@ -480,3 +480,69 @@ void func() {
|
|||
a0;
|
||||
}
|
||||
|
||||
//!Bug 331963 Extract local variable doesn't put template type parameters
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractlocalvariable.ExtractLocalVariableRefactoringTest
|
||||
//@A.cpp
|
||||
|
||||
template<class T>
|
||||
class Foo {
|
||||
};
|
||||
|
||||
Foo<int> getFoo();
|
||||
|
||||
int main() {
|
||||
|
||||
/*$*/getFoo()/*$$*/;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=
|
||||
|
||||
template<class T>
|
||||
class Foo {
|
||||
};
|
||||
|
||||
Foo<int> getFoo();
|
||||
|
||||
int main() {
|
||||
Foo<int> getFoo0 = getFoo();
|
||||
getFoo0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//!Bug 331963 Extract local variable doesn't put template type parameters Namespace
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.extractlocalvariable.ExtractLocalVariableRefactoringTest
|
||||
//@A.cpp
|
||||
namespace bar{
|
||||
template<class T>
|
||||
class Foo {
|
||||
};
|
||||
}
|
||||
|
||||
bar::Foo<int> getFoo();
|
||||
|
||||
int main() {
|
||||
|
||||
/*$*/getFoo()/*$$*/;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
//=
|
||||
namespace bar{
|
||||
template<class T>
|
||||
class Foo {
|
||||
};
|
||||
}
|
||||
|
||||
bar::Foo<int> getFoo();
|
||||
|
||||
int main() {
|
||||
bar::Foo<int> getFoo0 = getFoo();
|
||||
getFoo0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue