mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-05 16:56:04 +02:00
Bug 399931 - Fix for toggling functions with return type from context.
Change-Id: I188d851500c4464d12977c82805679eee31663f2 Signed-off-by: Thomas Corbat <tcorbat@hsr.ch>
This commit is contained in:
parent
d997a7c313
commit
ed3e9cf973
7 changed files with 489 additions and 60 deletions
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2014 IBM Corporation and others.
|
||||
* Copyright (c) 2006, 2015 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
|
||||
|
@ -156,7 +156,10 @@ public interface INodeFactory {
|
|||
public IASTName newName();
|
||||
|
||||
public IASTName newName(char[] name);
|
||||
|
||||
|
||||
/** @since 5.11 */
|
||||
public IASTName newName(String name);
|
||||
|
||||
public IASTNullStatement newNullStatement();
|
||||
|
||||
public IASTParameterDeclaration newParameterDeclaration(IASTDeclSpecifier declSpec, IASTDeclarator declarator);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2014 IBM Corporation and others.
|
||||
* Copyright (c) 2006, 2015 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
|
||||
|
@ -278,6 +278,14 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
@Deprecated
|
||||
public ICPPASTQualifiedName newQualifiedName();
|
||||
|
||||
/**
|
||||
* Creates an {@link ICPPASTQualifiedName} and adds name qualifiers for the
|
||||
* elements of {@code nameQualifiers}. {@code nameQualifiers} cannot contain decltype specifiers
|
||||
* for creation of {@link ICPPASTDecltypeSpecifier}.
|
||||
* @since 5.11
|
||||
*/
|
||||
public ICPPASTQualifiedName newQualifiedName(String[] nameQualifiers, String name);
|
||||
|
||||
/**
|
||||
* @since 5.9
|
||||
*/
|
||||
|
@ -290,6 +298,11 @@ public interface ICPPNodeFactory extends INodeFactory {
|
|||
@Override
|
||||
public ICPPASTName newName(char[] name);
|
||||
|
||||
/**
|
||||
* @since 5.11
|
||||
*/
|
||||
public ICPPASTNamedTypeSpecifier newNamedTypeSpecifier(IASTName name);
|
||||
|
||||
/**
|
||||
* Creates a range based for statement.
|
||||
* @since 5.3
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2014 IBM Corporation and others.
|
||||
* Copyright (c) 2006, 2015 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
|
||||
|
@ -364,7 +364,12 @@ public class CNodeFactory extends NodeFactory implements ICNodeFactory {
|
|||
public IASTName newName(char[] name) {
|
||||
return new CASTName(name);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public IASTName newName(String name) {
|
||||
return newName(name.toCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public IASTNullStatement newNullStatement() {
|
||||
return new CASTNullStatement();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2006, 2014 IBM Corporation and others.
|
||||
* Copyright (c) 2006, 2015 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
|
||||
|
@ -519,6 +519,16 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTName(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTName newName(String name) {
|
||||
return newName(name.toCharArray());
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTNamedTypeSpecifier newNamedTypeSpecifier(IASTName name) {
|
||||
return new CPPASTNamedTypeSpecifier(name);
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTNamespaceAlias newNamespaceAlias(IASTName alias, IASTName qualifiedName) {
|
||||
return new CPPASTNamespaceAlias(alias, qualifiedName);
|
||||
|
@ -621,6 +631,15 @@ public class CPPNodeFactory extends NodeFactory implements ICPPNodeFactory {
|
|||
return new CPPASTQualifiedName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTQualifiedName newQualifiedName(String[] nameQualifiers, String name) {
|
||||
ICPPASTQualifiedName qualifiedName = newQualifiedName(newName(name));
|
||||
for (String qualifier : nameQualifiers) {
|
||||
qualifiedName.addNameSpecifier(newName(qualifier));
|
||||
}
|
||||
return qualifiedName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ICPPASTRangeBasedForStatement newRangeBasedForStatement() {
|
||||
return new CPPASTRangeBasedForStatement();
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Copyright (c) 2008, 2015 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -8,9 +8,11 @@
|
|||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
* Thomas Corbat (IFS)
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.core.dom.rewrite.astwriter;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
|
@ -80,11 +82,15 @@ public class NameWriter extends NodeWriter {
|
|||
private boolean needsTemplateQualifier(ICPPASTTemplateId templId){
|
||||
if (templId.getParent() instanceof ICPPASTQualifiedName) {
|
||||
ICPPASTQualifiedName qName = (ICPPASTQualifiedName) templId.getParent();
|
||||
return isDependentName(qName, templId);
|
||||
return !isPartOfFunctionDeclarator(qName) && isDependentName(qName, templId);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
private boolean isPartOfFunctionDeclarator(ICPPASTQualifiedName qName) {
|
||||
return qName.getParent() instanceof IASTFunctionDeclarator;
|
||||
}
|
||||
|
||||
private boolean isDependentName(ICPPASTQualifiedName qname, ICPPASTTemplateId tempId) {
|
||||
ICPPASTNameSpecifier[] segments = qname.getAllSegments();
|
||||
for (int i = 0; i < segments.length; ++i){
|
||||
|
|
|
@ -3273,4 +3273,282 @@ public class ToggleRefactoringTest extends RefactoringTestBase {
|
|||
public void testToggleFunctionFailsOnSyntaxError_389299() throws Exception {
|
||||
assertRefactoringFailure();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//class test
|
||||
//{
|
||||
// typedef int M;
|
||||
//public:
|
||||
// M /*$*/f/*$$*/(){
|
||||
// return 1;
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//class test
|
||||
//{
|
||||
// typedef int M;
|
||||
//public:
|
||||
// M f();
|
||||
//};
|
||||
//
|
||||
//inline test::M test::f() {
|
||||
// return 1;
|
||||
//}
|
||||
public void testToggleFunctionWithScopedTypedefReturntype_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename T1, typename T2>
|
||||
//class Tpl {
|
||||
// typedef T1 M;
|
||||
//public:
|
||||
// M /*$*/f/*$$*/(){
|
||||
// return M();
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//template<typename T1, typename T2>
|
||||
//class Tpl {
|
||||
// typedef T1 M;
|
||||
//public:
|
||||
// M f();
|
||||
//};
|
||||
//
|
||||
//template<typename T1, typename T2>
|
||||
//inline typename Tpl<T1, T2>::M Tpl<T1, T2>::f() {
|
||||
// return M();
|
||||
//}
|
||||
public void testToggleFunctionWithScopedTypedefReturntypeFromTemplate_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename TOuter>
|
||||
//struct TplOuter {
|
||||
// template<typename TInner>
|
||||
// struct TplInner {
|
||||
// typedef TInner R;
|
||||
// R /*$*/f/*$$*/(){
|
||||
// return R();
|
||||
// }
|
||||
// };
|
||||
//};
|
||||
//====================
|
||||
//template<typename TOuter>
|
||||
//struct TplOuter {
|
||||
// template<typename TInner>
|
||||
// struct TplInner {
|
||||
// typedef TInner R;
|
||||
// R f();
|
||||
// };
|
||||
//};
|
||||
//
|
||||
//template<typename TOuter>
|
||||
//template<typename TInner>
|
||||
//inline typename TplOuter<TOuter>::template TplInner<TInner>::R TplOuter<TOuter>::TplInner<
|
||||
// TInner>::f() {
|
||||
// return R();
|
||||
//}
|
||||
public void testToggleFunctionFromNestedTemplate_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename Item>
|
||||
//struct Bag {
|
||||
// Bag /*$*/create/*$$*/(){
|
||||
// return Bag();
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//template<typename Item>
|
||||
//struct Bag {
|
||||
// Bag create();
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//inline Bag<Item> Bag<Item>::create() {
|
||||
// return Bag();
|
||||
//}
|
||||
public void testToggleFunctionWithTemplateReturnType_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename Item>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//struct Bag<Item*> {
|
||||
// Bag /*$*/create/*$$*/() {
|
||||
// return Bag();
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//template<typename Item>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//struct Bag<Item*> {
|
||||
// Bag create();
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//inline Bag<Item*> Bag<Item*>::create() {
|
||||
// return Bag();
|
||||
//}
|
||||
public void testToggleMemberFunctionOfPartialSpecialization_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename Item, typename T>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//struct Bag<Item*, int> {
|
||||
// Bag /*$*/create/*$$*/() {
|
||||
// return Bag();
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//template<typename Item, typename T>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//struct Bag<Item*, int> {
|
||||
// Bag create();
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//inline Bag<Item*, int> Bag<Item*, int>::create() {
|
||||
// return Bag();
|
||||
//}
|
||||
public void testToggleMemberFunctionOfPartialSpecializationWithTwoParameters_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename Item, typename T>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//struct Bag<Item**, int**> {
|
||||
// Bag /*$*/create/*$$*/() {
|
||||
// return Bag();
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//template<typename Item, typename T>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//struct Bag<Item**, int**> {
|
||||
// Bag create();
|
||||
//};
|
||||
//
|
||||
//template<typename Item>
|
||||
//inline Bag<Item**, int**> Bag<Item**, int**>::create() {
|
||||
// return Bag();
|
||||
//}
|
||||
public void testToggleMemberFunctionOfPartialSpecializationMultiplePointers_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename Item>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<>
|
||||
//struct Bag<int> {
|
||||
// Bag /*$*/create/*$$*/() {
|
||||
// return Bag();
|
||||
// }
|
||||
//};
|
||||
//====================
|
||||
//template<typename Item>
|
||||
//struct Bag {
|
||||
//};
|
||||
//
|
||||
//template<>
|
||||
//struct Bag<int> {
|
||||
// Bag create();
|
||||
//};
|
||||
//
|
||||
//inline Bag<int> Bag<int>::create() {
|
||||
// return Bag();
|
||||
//}
|
||||
public void testToggleMemberFunctionOfFullSpecialization_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename R>
|
||||
//struct Qualifier {
|
||||
// typedef R ReturnType;
|
||||
//};
|
||||
//
|
||||
//template<typename T>
|
||||
//struct ToggleType {
|
||||
// typename Qualifier<int>::ReturnType /*$*/create/*$$*/() {
|
||||
// return typename Qualifier<int>::ReturnType();
|
||||
//}
|
||||
//};
|
||||
//====================
|
||||
//template<typename R>
|
||||
//struct Qualifier {
|
||||
// typedef R ReturnType;
|
||||
//};
|
||||
//
|
||||
//template<typename T>
|
||||
//struct ToggleType {
|
||||
// typename Qualifier<int>::ReturnType create();
|
||||
//};
|
||||
//
|
||||
//template<typename T>
|
||||
//inline typename Qualifier<int>::ReturnType ToggleType<T>::create() {
|
||||
// return typename Qualifier<int>::ReturnType();
|
||||
//}
|
||||
public void testToggleWithTemplateQualifierInReturnType_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
|
||||
//A.h
|
||||
//template<typename R>
|
||||
//struct Qualifier {
|
||||
// typedef R ReturnType;
|
||||
//};
|
||||
//
|
||||
//template<typename T>
|
||||
//struct ToggleType {
|
||||
// typename Qualifier<T>::ReturnType /*$*/create/*$$*/() {
|
||||
// return typename Qualifier<T>::ReturnType();
|
||||
//}
|
||||
//};
|
||||
//====================
|
||||
//template<typename R>
|
||||
//struct Qualifier {
|
||||
// typedef R ReturnType;
|
||||
//};
|
||||
//
|
||||
//template<typename T>
|
||||
//struct ToggleType {
|
||||
// typename Qualifier<T>::ReturnType create();
|
||||
//};
|
||||
//
|
||||
//template<typename T>
|
||||
//inline typename Qualifier<T>::ReturnType ToggleType<T>::create() {
|
||||
// return typename Qualifier<T>::ReturnType();
|
||||
//}
|
||||
public void testToggleWithTemplateArgumentDependentQualifierInReturnType_399931() throws Exception {
|
||||
assertRefactoringSuccess();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,10 +14,13 @@
|
|||
package org.eclipse.cdt.internal.ui.refactoring.togglefunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Stack;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.ASTNodeFactoryFactory;
|
||||
import org.eclipse.cdt.core.dom.ast.ASTTypeUtil;
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
|
@ -31,34 +34,43 @@ import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTTranslationUnit;
|
||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.IType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCatchHandler;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConstructorChainInitializer;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionWithTryBlock;
|
||||
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.ICPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNamespaceDefinition;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleTypeTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypeId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassTemplate;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateArgument;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateInstance;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite.CommentPosition;
|
||||
import org.eclipse.cdt.ui.CUIPlugin;
|
||||
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTCompoundStatement;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionWithTryBlock;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateId;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTypeId;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||
import org.eclipse.cdt.internal.core.dom.rewrite.DeclarationGeneratorImpl;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.NodeHelper;
|
||||
|
||||
public class ToggleNodeHelper extends NodeHelper {
|
||||
private static final String EMPTY_STRING = ""; //$NON-NLS-1$
|
||||
private static final ICPPNodeFactory factory = ASTNodeFactoryFactory.getDefaultCPPNodeFactory();
|
||||
|
||||
private static void removeParameterInitializations(IASTFunctionDeclarator funcDecl) {
|
||||
for (IASTNode child : funcDecl.getChildren()) {
|
||||
|
@ -84,7 +96,7 @@ public class ToggleNodeHelper extends NodeHelper {
|
|||
static IASTSimpleDeclaration createDeclarationFromDefinition(IASTFunctionDefinition oldDefinition) {
|
||||
IASTDeclarator newDeclarator = oldDefinition.getDeclarator().copy(CopyStyle.withLocations);
|
||||
IASTDeclSpecifier newDeclSpec = oldDefinition.getDeclSpecifier().copy(CopyStyle.withLocations);
|
||||
IASTSimpleDeclaration newDeclaration = new CPPASTSimpleDeclaration(newDeclSpec);
|
||||
IASTSimpleDeclaration newDeclaration = factory.newSimpleDeclaration(newDeclSpec);
|
||||
newDeclaration.addDeclarator(newDeclarator);
|
||||
return newDeclaration;
|
||||
}
|
||||
|
@ -95,11 +107,9 @@ public class ToggleNodeHelper extends NodeHelper {
|
|||
ICPPASTFunctionDefinition newFunc = null;
|
||||
newFuncDecl = adjustParamNames(newFuncDecl, oldDefinition);
|
||||
if (oldDefinition instanceof ICPPASTFunctionWithTryBlock) {
|
||||
newFunc = new CPPASTFunctionWithTryBlock(newDeclSpec, newFuncDecl,
|
||||
new CPPASTCompoundStatement());
|
||||
newFunc = factory.newFunctionTryBlock(newDeclSpec, newFuncDecl, factory.newCompoundStatement());
|
||||
} else {
|
||||
newFunc = new CPPASTFunctionDefinition(newDeclSpec, newFuncDecl,
|
||||
new CPPASTCompoundStatement());
|
||||
newFunc = factory.newFunctionDefinition(newDeclSpec, newFuncDecl, factory.newCompoundStatement());
|
||||
}
|
||||
copyInitializerList(newFunc, oldDefinition);
|
||||
return newFunc;
|
||||
|
@ -127,49 +137,146 @@ public class ToggleNodeHelper extends NodeHelper {
|
|||
|
||||
static IASTFunctionDefinition getQualifiedNameDefinition(IASTFunctionDefinition oldDefinition,
|
||||
IASTTranslationUnit definitionUnit, IASTNode nameSpace) {
|
||||
|
||||
ICPPASTDeclSpecifier newDeclSpec =
|
||||
(ICPPASTDeclSpecifier) oldDefinition.getDeclSpecifier().copy(CopyStyle.withLocations);
|
||||
|
||||
newDeclSpec.setVirtual(false);
|
||||
newDeclSpec.setInline(true);
|
||||
newDeclSpec.setStorageClass(IASTDeclSpecifier.sc_unspecified);
|
||||
|
||||
ICPPASTDeclSpecifier newDeclSpecifier = createDeclSpecifier(oldDefinition);
|
||||
IASTFunctionDeclarator newDeclarator = oldDefinition.getDeclarator().copy(CopyStyle.withLocations);
|
||||
newDeclarator.setName(getQualifiedName(oldDefinition.getDeclarator(), nameSpace));
|
||||
removeParameterInitializations(newDeclarator);
|
||||
|
||||
|
||||
ICPPASTFunctionDefinition newFunction =
|
||||
createFunctionSignatureWithEmptyBody(newDeclSpec, newDeclarator, oldDefinition);
|
||||
|
||||
createFunctionSignatureWithEmptyBody(newDeclSpecifier, newDeclarator, oldDefinition);
|
||||
|
||||
return newFunction;
|
||||
}
|
||||
|
||||
private static ICPPASTDeclSpecifier createDeclSpecifier(IASTFunctionDefinition oldDefinition) {
|
||||
IASTDeclSpecifier originalDeclSpecifier = oldDefinition.getDeclSpecifier();
|
||||
ICPPASTDeclSpecifier newDeclSpecifier = (ICPPASTDeclSpecifier) originalDeclSpecifier.copy(CopyStyle.withLocations);
|
||||
if (newDeclSpecifier instanceof ICPPASTNamedTypeSpecifier) {
|
||||
ICPPASTNamedTypeSpecifier newNamedTypeSpecifier = (ICPPASTNamedTypeSpecifier) newDeclSpecifier;
|
||||
IASTName typename = ((ICPPASTNamedTypeSpecifier) originalDeclSpecifier).getName();
|
||||
IBinding typenameBinding = typename.resolveBinding();
|
||||
adaptTemplateQualifiers(newNamedTypeSpecifier, typenameBinding);
|
||||
}
|
||||
newDeclSpecifier.setVirtual(false);
|
||||
newDeclSpecifier.setInline(true);
|
||||
newDeclSpecifier.setStorageClass(IASTDeclSpecifier.sc_unspecified);
|
||||
return newDeclSpecifier;
|
||||
}
|
||||
|
||||
private static void adaptTemplateQualifiers(ICPPASTNamedTypeSpecifier newDeclSpecifier,
|
||||
IBinding typenameBinding) {
|
||||
if (typenameBinding instanceof ICPPBinding) {
|
||||
try {
|
||||
String[] nameParts = ((ICPPBinding) typenameBinding).getQualifiedName();
|
||||
String qualifiedName = typenameBinding.getName();
|
||||
String[] nameQualifiers = Arrays.copyOf(nameParts, nameParts.length - 1);
|
||||
ICPPASTQualifiedName qualifiedTypeName = factory.newQualifiedName(nameQualifiers, qualifiedName);
|
||||
|
||||
if (typenameBinding instanceof ICPPTemplateInstance) {
|
||||
ICPPTemplateInstance templateInstance = (ICPPTemplateInstance) typenameBinding;
|
||||
ICPPTemplateArgument[] templateArguments = templateInstance.getTemplateArguments();
|
||||
IASTName lastName = qualifiedTypeName.getLastName();
|
||||
ICPPASTTemplateId newTemplateId = createTemplateIdForArguments(lastName, templateArguments);
|
||||
qualifiedTypeName.setLastName(newTemplateId);
|
||||
}
|
||||
|
||||
boolean setTypename = adaptQualifiers(typenameBinding, qualifiedTypeName);
|
||||
newDeclSpecifier.setName(qualifiedTypeName);
|
||||
newDeclSpecifier.setIsTypename(setTypename);
|
||||
} catch (DOMException e) {
|
||||
CUIPlugin.log(e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean adaptQualifiers(IBinding typenameBinding, ICPPASTQualifiedName qualifiedTypeName) {
|
||||
boolean setTypename = false;
|
||||
IBinding owner = typenameBinding.getOwner();
|
||||
ICPPASTNameSpecifier[] qualifiers = qualifiedTypeName.getQualifier();
|
||||
if (qualifiers.length > 0) {
|
||||
int level = qualifiers.length - 1;
|
||||
while (owner != null && level >= 0) {
|
||||
IASTName qualifierName = (IASTName) qualifiers[level];
|
||||
ICPPASTTemplateId newTemplateId = createTemplateIdForQualifier(qualifierName, owner);
|
||||
if (newTemplateId != null) {
|
||||
qualifiers[level] = newTemplateId;
|
||||
newTemplateId.setParent(qualifiedTypeName);
|
||||
setTypename = true;
|
||||
}
|
||||
owner = owner.getOwner();
|
||||
level--;
|
||||
}
|
||||
}
|
||||
return setTypename;
|
||||
}
|
||||
|
||||
private static ICPPASTTemplateId createTemplateIdForQualifier(IASTName qualifierName, IBinding templateBinding) {
|
||||
ICPPASTTemplateId newTemplateId = null;
|
||||
if (templateBinding instanceof ICPPClassTemplate) {
|
||||
ICPPClassTemplate classTemplateBinding = (ICPPClassTemplate) templateBinding;
|
||||
newTemplateId = createTemplateId(qualifierName, classTemplateBinding);
|
||||
} else if (templateBinding instanceof ICPPTemplateInstance) {
|
||||
ICPPTemplateInstance instanceBinding = (ICPPTemplateInstance) templateBinding;
|
||||
ICPPTemplateArgument[] templateArguments = instanceBinding.getTemplateArguments();
|
||||
newTemplateId = createTemplateIdForArguments(qualifierName, templateArguments);
|
||||
}
|
||||
return newTemplateId;
|
||||
}
|
||||
|
||||
private static ICPPASTTemplateId createTemplateIdForArguments(IASTName qualifierName, ICPPTemplateArgument[] templateArguments) {
|
||||
ICPPASTTemplateId newTemplateId = factory.newTemplateId(qualifierName);
|
||||
for (ICPPTemplateArgument templateArgument : templateArguments) {
|
||||
IType type = templateArgument.getOriginalTypeValue();
|
||||
DeclarationGeneratorImpl declarationGeneratorImpl = new DeclarationGeneratorImpl(factory);
|
||||
IASTDeclarator abstractDeclarator = declarationGeneratorImpl.createDeclaratorFromType(type, EMPTY_STRING.toCharArray());
|
||||
IType ultimateType = SemanticUtil.getUltimateType(type, false);
|
||||
IASTName templateParameterName = factory.newName(ASTTypeUtil.getType(ultimateType, false));
|
||||
ICPPASTNamedTypeSpecifier typeSpecifier = factory.newNamedTypeSpecifier(templateParameterName);
|
||||
ICPPASTTypeId newTypeId = factory.newTypeId(typeSpecifier, abstractDeclarator);
|
||||
newTemplateId.addTemplateArgument(newTypeId);
|
||||
}
|
||||
return newTemplateId;
|
||||
}
|
||||
|
||||
private static ICPPASTTemplateId createTemplateId(IASTName qualifierName, ICPPClassTemplate ownerBinding) {
|
||||
ICPPASTTemplateId newTemplateId = factory.newTemplateId(qualifierName);
|
||||
for (ICPPTemplateParameter templateParameter : ownerBinding.getTemplateParameters()) {
|
||||
IASTName abstractDeclaratorName = factory.newName();
|
||||
ICPPASTDeclarator abstractDeclarator = factory.newDeclarator(abstractDeclaratorName);
|
||||
ICPPASTName templateParameterName = factory.newName(templateParameter.getNameCharArray());
|
||||
ICPPASTNamedTypeSpecifier typeSpecifier = factory.newNamedTypeSpecifier(templateParameterName);
|
||||
ICPPASTTypeId newTypeId = factory.newTypeId(typeSpecifier, abstractDeclarator);
|
||||
newTemplateId.addTemplateArgument(newTypeId);
|
||||
}
|
||||
return newTemplateId;
|
||||
}
|
||||
|
||||
public static ICPPASTTemplateDeclaration getTemplateDeclaration(
|
||||
IASTFunctionDefinition oldFunction, IASTFunctionDefinition newFunction) {
|
||||
ArrayList<ICPPASTTemplateDeclaration> templateDeclarations = getAllTemplateDeclaration(oldFunction);
|
||||
ArrayList<ICPPASTTemplateDeclaration> templateDeclarations = getAllTemplateDeclarations(oldFunction);
|
||||
return addTemplateDeclarationsInOrder(templateDeclarations, newFunction);
|
||||
}
|
||||
|
||||
private static ICPPASTTemplateDeclaration addTemplateDeclarationsInOrder(
|
||||
ArrayList<ICPPASTTemplateDeclaration> templDecs, IASTFunctionDefinition newFunction) {
|
||||
ListIterator<ICPPASTTemplateDeclaration> iter1 = templDecs.listIterator();
|
||||
ICPPASTTemplateDeclaration child = null;
|
||||
while (iter1.hasNext()) {
|
||||
child = iter1.next();
|
||||
child.setDeclaration(newFunction);
|
||||
ListIterator<ICPPASTTemplateDeclaration> iter2 = iter1;
|
||||
if (iter2.hasNext()) {
|
||||
ICPPASTTemplateDeclaration parent = iter2.next();
|
||||
child.setParent(parent);
|
||||
parent.setDeclaration(child);
|
||||
child = parent;
|
||||
for (ICPPASTTemplateDeclaration templateDeclaration : templDecs) {
|
||||
if (templateDeclaration.getTemplateParameters().length == 0) {
|
||||
continue;
|
||||
}
|
||||
if (child == null) {
|
||||
child = templateDeclaration;
|
||||
child.setDeclaration(newFunction);
|
||||
} else {
|
||||
templateDeclaration.setDeclaration(child);
|
||||
child.setParent(templateDeclaration);
|
||||
child = templateDeclaration;
|
||||
}
|
||||
}
|
||||
return child;
|
||||
}
|
||||
|
||||
private static ArrayList<ICPPASTTemplateDeclaration> getAllTemplateDeclaration(IASTNode node) {
|
||||
private static ArrayList<ICPPASTTemplateDeclaration> getAllTemplateDeclarations(IASTNode node) {
|
||||
ArrayList<ICPPASTTemplateDeclaration> templdecs = new ArrayList<ICPPASTTemplateDeclaration>();
|
||||
while (node.getParent() != null) {
|
||||
node = node.getParent();
|
||||
|
@ -226,13 +333,13 @@ public class ToggleNodeHelper extends NodeHelper {
|
|||
*/
|
||||
static ICPPASTQualifiedName getQualifiedName(IASTFunctionDeclarator declarator, IASTNode limiter) {
|
||||
Stack<IASTNode> nodes = getQualifiedNames(declarator, limiter, declarator);
|
||||
CPPASTQualifiedName qName = reAssembleQualifiedName(nodes);
|
||||
ICPPASTQualifiedName qName = reAssembleQualifiedName(nodes);
|
||||
qName.addName(declarator.getName().copy(CopyStyle.withLocations));
|
||||
return qName;
|
||||
}
|
||||
|
||||
private static CPPASTQualifiedName reAssembleQualifiedName(Stack<IASTNode> nodes) {
|
||||
CPPASTQualifiedName qName = new CPPASTQualifiedName();
|
||||
private static ICPPASTQualifiedName reAssembleQualifiedName(Stack<IASTNode> nodes) {
|
||||
ICPPASTQualifiedName qName = factory.newQualifiedName(null);
|
||||
while (!nodes.isEmpty()) {
|
||||
IASTNode nnode = nodes.pop();
|
||||
if (nnode instanceof IASTCompositeTypeSpecifier) {
|
||||
|
@ -258,10 +365,10 @@ public class ToggleNodeHelper extends NodeHelper {
|
|||
} else if (node instanceof ICPPASTNamespaceDefinition) {
|
||||
nodes.push(((ICPPASTNamespaceDefinition) node).copy(CopyStyle.withLocations));
|
||||
lastName = ((ICPPASTNamespaceDefinition) node).getName();
|
||||
} else if (shouldAddTemplateBrackets(node)) {
|
||||
} else if (!(lastName instanceof ICPPASTTemplateId) && shouldAddTemplateBrackets(node)) {
|
||||
if (!nodes.isEmpty())
|
||||
nodes.pop();
|
||||
ICPPASTTemplateId templateID = ToggleNodeHelper.getTemplateParameter(node, lastName);
|
||||
ICPPASTTemplateId templateID = getTemplateParameter(node, lastName);
|
||||
nodes.add(templateID);
|
||||
}
|
||||
}
|
||||
|
@ -271,21 +378,19 @@ public class ToggleNodeHelper extends NodeHelper {
|
|||
private static boolean shouldAddTemplateBrackets(IASTNode node) {
|
||||
return node instanceof ICPPASTTemplateDeclaration
|
||||
&& !(((ICPPASTTemplateDeclaration) node).getDeclaration()
|
||||
instanceof CPPASTFunctionDefinition);
|
||||
instanceof ICPPASTFunctionDefinition);
|
||||
}
|
||||
|
||||
private static ICPPASTTemplateId getTemplateParameter(IASTNode node, IASTName name) {
|
||||
ICPPASTTemplateId templateID = new CPPASTTemplateId();
|
||||
templateID.setTemplateName(name.copy(CopyStyle.withLocations));
|
||||
ICPPASTTemplateId templateID = factory.newTemplateId(name.copy(CopyStyle.withLocations));
|
||||
for (IASTNode child : node.getChildren()) {
|
||||
if (child instanceof ICPPASTSimpleTypeTemplateParameter) {
|
||||
ICPPASTSimpleTypeTemplateParameter tempChild = (ICPPASTSimpleTypeTemplateParameter) child;
|
||||
|
||||
CPPASTNamedTypeSpecifier namedTypeSpecifier = new CPPASTNamedTypeSpecifier();
|
||||
namedTypeSpecifier.setName(tempChild.getName().copy(CopyStyle.withLocations));
|
||||
|
||||
CPPASTTypeId id = new CPPASTTypeId();
|
||||
id.setDeclSpecifier(namedTypeSpecifier);
|
||||
|
||||
IASTName argumentName = tempChild.getName().copy(CopyStyle.withLocations);
|
||||
ICPPASTNamedTypeSpecifier namedTypeSpecifier = factory.newNamedTypeSpecifier(argumentName);
|
||||
|
||||
ICPPASTTypeId id = factory.newTypeId(namedTypeSpecifier, null);
|
||||
templateID.addTemplateArgument(id);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue