mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-30 21:55:31 +02:00
Fixed passing parameters by pointer and renaming of parameters in
Extract Function refactoring.
This commit is contained in:
parent
38803901ec
commit
8dc598a145
14 changed files with 580 additions and 293 deletions
|
@ -6,7 +6,7 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Mike Kucera (IBM) - Initial API and implementation
|
* Mike Kucera (IBM) - Initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.parser.tests;
|
package org.eclipse.cdt.core.parser.tests;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ public class ASTComparer extends Assert {
|
||||||
|
|
||||||
private static Set<String> methodsToIgnore = new HashSet<String>(Arrays.asList(
|
private static Set<String> methodsToIgnore = new HashSet<String>(Arrays.asList(
|
||||||
// Prevent infinite recursion
|
// Prevent infinite recursion
|
||||||
"getParent",
|
"getParent",
|
||||||
"getTranslationUnit",
|
"getTranslationUnit",
|
||||||
"getLastName",
|
"getLastName",
|
||||||
|
|
||||||
|
@ -39,6 +39,7 @@ public class ASTComparer extends Assert {
|
||||||
// Can be different in copy
|
// Can be different in copy
|
||||||
"isFrozen",
|
"isFrozen",
|
||||||
"getContainingFilename",
|
"getContainingFilename",
|
||||||
|
"getOriginalNode",
|
||||||
|
|
||||||
// These methods are problematic
|
// These methods are problematic
|
||||||
"getProblem",
|
"getProblem",
|
||||||
|
@ -62,18 +63,16 @@ public class ASTComparer extends Assert {
|
||||||
"isLValue"
|
"isLValue"
|
||||||
));
|
));
|
||||||
|
|
||||||
|
|
||||||
public static void assertCopy(IASTNode node1, IASTNode node2) {
|
public static void assertCopy(IASTNode node1, IASTNode node2) {
|
||||||
try {
|
try {
|
||||||
assertCopy(node1, node2, 0);
|
assertCopy(node1, node2, 0);
|
||||||
} catch(Exception e) {
|
} catch (Exception e) {
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void assertCopy(IASTNode node1, IASTNode node2, int n) throws Exception {
|
private static void assertCopy(IASTNode node1, IASTNode node2, int n) throws Exception {
|
||||||
if(node1 == null && node2 == null)
|
if (node1 == null && node2 == null)
|
||||||
return;
|
return;
|
||||||
assertNotNull(node1);
|
assertNotNull(node1);
|
||||||
assertNotNull(node2);
|
assertNotNull(node2);
|
||||||
|
@ -86,11 +85,11 @@ public class ASTComparer extends Assert {
|
||||||
|
|
||||||
BeanInfo beanInfo = Introspector.getBeanInfo(klass1);
|
BeanInfo beanInfo = Introspector.getBeanInfo(klass1);
|
||||||
|
|
||||||
for(PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
|
for (PropertyDescriptor property : beanInfo.getPropertyDescriptors()) {
|
||||||
Method getter = property.getReadMethod();
|
Method getter = property.getReadMethod();
|
||||||
if(getter == null)
|
if (getter == null)
|
||||||
continue;
|
continue;
|
||||||
if(methodsToIgnore.contains(getter.getName()))
|
if (methodsToIgnore.contains(getter.getName()))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (getter.getAnnotation(Deprecated.class) != null)
|
if (getter.getAnnotation(Deprecated.class) != null)
|
||||||
|
@ -99,48 +98,43 @@ public class ASTComparer extends Assert {
|
||||||
try {
|
try {
|
||||||
Class returnType = getter.getReturnType();
|
Class returnType = getter.getReturnType();
|
||||||
|
|
||||||
if(IASTNode.class.isAssignableFrom(returnType)) {
|
if (IASTNode.class.isAssignableFrom(returnType)) {
|
||||||
//System.out.println(spaces(n) + "Testing1: " + getter.getName());
|
//System.out.println(spaces(n) + "Testing1: " + getter.getName());
|
||||||
IASTNode result1 = (IASTNode) getter.invoke(node1);
|
IASTNode result1 = (IASTNode) getter.invoke(node1);
|
||||||
IASTNode result2 = (IASTNode) getter.invoke(node2);
|
IASTNode result2 = (IASTNode) getter.invoke(node2);
|
||||||
assertCopy(result1, result2, n+1); // members must be same
|
assertCopy(result1, result2, n + 1); // members must be same
|
||||||
}
|
} else if (returnType.isArray() && IASTNode.class.isAssignableFrom(returnType.getComponentType())) {
|
||||||
else if(returnType.isArray() && IASTNode.class.isAssignableFrom(returnType.getComponentType())) {
|
|
||||||
//System.out.println(spaces(n) + "Testing2: " + getter.getName());
|
//System.out.println(spaces(n) + "Testing2: " + getter.getName());
|
||||||
IASTNode[] result1 = (IASTNode[]) getter.invoke(node1);
|
IASTNode[] result1 = (IASTNode[]) getter.invoke(node1);
|
||||||
IASTNode[] result2 = (IASTNode[]) getter.invoke(node2);
|
IASTNode[] result2 = (IASTNode[]) getter.invoke(node2);
|
||||||
if(result1 == null && result2 == null)
|
if (result1 == null && result2 == null)
|
||||||
continue;
|
continue;
|
||||||
assertNotNull(result1);
|
assertNotNull(result1);
|
||||||
assertNotNull(result2);
|
assertNotNull(result2);
|
||||||
assertEquals(result1.length, result2.length);
|
assertEquals(result1.length, result2.length);
|
||||||
for(int i = 0; i < result1.length; i++)
|
for(int i = 0; i < result1.length; i++)
|
||||||
assertCopy(result1[i], result2[i], n+1);
|
assertCopy(result1[i], result2[i], n + 1);
|
||||||
}
|
} else if ((returnType.isPrimitive() || returnType.equals(String.class)) && !returnType.equals(Void.class)) {
|
||||||
else if((returnType.isPrimitive() || returnType.equals(String.class)) && !returnType.equals(Void.class)) {
|
|
||||||
//System.out.println(spaces(n) + "Testing3: " + getter.getName());
|
//System.out.println(spaces(n) + "Testing3: " + getter.getName());
|
||||||
Object result1 = getter.invoke(node1);
|
Object result1 = getter.invoke(node1);
|
||||||
Object result2 = getter.invoke(node2);
|
Object result2 = getter.invoke(node2);
|
||||||
assertEquals(result1, result2);
|
assertEquals(result1, result2);
|
||||||
}
|
}
|
||||||
|
} catch (AssertionFailedError e) {
|
||||||
} catch(AssertionFailedError e) {
|
|
||||||
System.out.printf("Failure when calling %s.%s() @(%d,%d)\n",
|
System.out.printf("Failure when calling %s.%s() @(%d,%d)\n",
|
||||||
node1.getClass().getSimpleName(),
|
node1.getClass().getSimpleName(),
|
||||||
getter.getName(),
|
getter.getName(),
|
||||||
((ASTNode)node1).getOffset(),
|
((ASTNode) node1).getOffset(),
|
||||||
((ASTNode)node1).getLength());
|
((ASTNode) node1).getLength());
|
||||||
throw e;
|
throw e;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// private static String spaces(int n) {
|
// private static String spaces(int n) {
|
||||||
// char[] spaces = new char[n*2];
|
// char[] spaces = new char[n*2];
|
||||||
// Arrays.fill(spaces, ' ');
|
// Arrays.fill(spaces, ' ');
|
||||||
// return new String(spaces);
|
// return new String(spaces);
|
||||||
// }
|
// }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,6 +18,10 @@ package org.eclipse.cdt.core.dom.ast;
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface IASTComment extends IASTNode {
|
public interface IASTComment extends IASTNode {
|
||||||
|
/**
|
||||||
|
* @since 5.4
|
||||||
|
*/
|
||||||
|
public final IASTComment[] EMPTY_COMMENT_ARRAY = {};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the comment.
|
* Set the comment.
|
||||||
|
@ -39,5 +43,4 @@ public interface IASTComment extends IASTNode {
|
||||||
* @return true if this is a blockcomment
|
* @return true if this is a blockcomment
|
||||||
*/
|
*/
|
||||||
public boolean isBlockComment();
|
public boolean isBlockComment();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Doug Schaefer (IBM) - Initial API and implementation
|
* Doug Schaefer (IBM) - Initial API and implementation
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast;
|
package org.eclipse.cdt.core.dom.ast;
|
||||||
|
|
||||||
|
@ -17,7 +17,6 @@ package org.eclipse.cdt.core.dom.ast;
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface IASTIdExpression extends IASTExpression, IASTNameOwner {
|
public interface IASTIdExpression extends IASTExpression, IASTNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <code>ID_NAME</code> represents the relationship between an
|
* <code>ID_NAME</code> represents the relationship between an
|
||||||
* <code>IASTIdExpression</code> and a <code>IASTName</code>.
|
* <code>IASTIdExpression</code> and a <code>IASTName</code>.
|
||||||
|
|
|
@ -6,8 +6,8 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM) - Initial API and implementation
|
* John Camelon (IBM) - Initial API and implementation
|
||||||
* Mike Kucera (IBM)
|
* Mike Kucera (IBM)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.core.dom.ast.cpp;
|
package org.eclipse.cdt.core.dom.ast.cpp;
|
||||||
|
|
||||||
|
@ -23,7 +23,6 @@ import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
* @noimplement This interface is not intended to be implemented by clients.
|
* @noimplement This interface is not intended to be implemented by clients.
|
||||||
*/
|
*/
|
||||||
public interface ICPPASTFieldReference extends IASTFieldReference, IASTImplicitNameOwner {
|
public interface ICPPASTFieldReference extends IASTFieldReference, IASTImplicitNameOwner {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Was template keyword used?
|
* Was template keyword used?
|
||||||
*
|
*
|
||||||
|
|
|
@ -14,6 +14,7 @@ package org.eclipse.cdt.internal.core.dom.parser;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
import org.eclipse.cdt.core.dom.ast.ASTNodeProperty;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
|
import org.eclipse.cdt.core.dom.ast.ExpansionOverlapsBoundaryException;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTCopyLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTImageLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
@ -373,4 +374,19 @@ public abstract class ASTNode implements IASTNode {
|
||||||
protected void setCopyLocation(IASTNode originalNode) {
|
protected void setCopyLocation(IASTNode originalNode) {
|
||||||
locations = new IASTNodeLocation[] { new ASTCopyLocation(originalNode) };
|
locations = new IASTNodeLocation[] { new ASTCopyLocation(originalNode) };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* If the node is a copy of some other node, returns the original node.
|
||||||
|
* Otherwise returns the node itself.
|
||||||
|
*/
|
||||||
|
public IASTNode getOriginalNode() {
|
||||||
|
IASTNode node = this;
|
||||||
|
while (true) {
|
||||||
|
IASTNodeLocation[] locations = node.getNodeLocations();
|
||||||
|
if (locations.length == 0 || !(locations[0] instanceof IASTCopyLocation))
|
||||||
|
break;
|
||||||
|
node = ((IASTCopyLocation) locations[0]).getOriginalNode();
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,10 +6,10 @@
|
||||||
* http://www.eclipse.org/legal/epl-v10.html
|
* http://www.eclipse.org/legal/epl-v10.html
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* John Camelon (IBM Rational Software) - Initial API and implementation
|
* John Camelon (IBM Rational Software) - Initial API and implementation
|
||||||
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
* Yuan Zhang / Beth Tibbitts (IBM Research)
|
||||||
* Bryan Wilkinson (QNX)
|
* Bryan Wilkinson (QNX)
|
||||||
* Markus Schorn (Wind River Systems)
|
* Markus Schorn (Wind River Systems)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.core.dom.parser.c;
|
package org.eclipse.cdt.internal.core.dom.parser.c;
|
||||||
|
|
||||||
|
@ -30,21 +30,19 @@ import org.eclipse.cdt.internal.core.dom.parser.ProblemType;
|
||||||
/**
|
/**
|
||||||
* Field reference in C.
|
* Field reference in C.
|
||||||
*/
|
*/
|
||||||
public class CASTFieldReference extends ASTNode implements IASTFieldReference, IASTAmbiguityParent, IASTCompletionContext {
|
public class CASTFieldReference extends ASTNode
|
||||||
|
implements IASTFieldReference, IASTAmbiguityParent, IASTCompletionContext {
|
||||||
private IASTExpression owner;
|
private IASTExpression owner;
|
||||||
private IASTName name;
|
private IASTName name;
|
||||||
private boolean ptr;
|
private boolean ptr;
|
||||||
|
|
||||||
public CASTFieldReference() {
|
public CASTFieldReference() {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CASTFieldReference(IASTName name, IASTExpression owner) {
|
public CASTFieldReference(IASTName name, IASTExpression owner) {
|
||||||
this(name, owner, false);
|
this(name, owner, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public CASTFieldReference(IASTName name, IASTExpression owner, boolean ptr) {
|
public CASTFieldReference(IASTName name, IASTExpression owner, boolean ptr) {
|
||||||
setFieldOwner(owner);
|
setFieldOwner(owner);
|
||||||
setFieldName(name);
|
setFieldName(name);
|
||||||
|
@ -111,41 +109,40 @@ public class CASTFieldReference extends ASTNode implements IASTFieldReference, I
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean accept( ASTVisitor action ){
|
public boolean accept(ASTVisitor action) {
|
||||||
if( action.shouldVisitExpressions ){
|
if (action.shouldVisitExpressions) {
|
||||||
switch( action.visit( this ) ){
|
switch (action.visit(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT: return false;
|
||||||
case ASTVisitor.PROCESS_SKIP : return true;
|
case ASTVisitor.PROCESS_SKIP: return true;
|
||||||
default : break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if( owner != null ) if( !owner.accept( action ) ) return false;
|
if (owner != null && !owner.accept(action)) return false;
|
||||||
if( name != null ) if( !name.accept( action ) ) return false;
|
if (name != null && !name.accept(action)) return false;
|
||||||
|
|
||||||
if( action.shouldVisitExpressions ){
|
if (action.shouldVisitExpressions) {
|
||||||
switch( action.leave( this ) ){
|
switch (action.leave(this)) {
|
||||||
case ASTVisitor.PROCESS_ABORT : return false;
|
case ASTVisitor.PROCESS_ABORT: return false;
|
||||||
case ASTVisitor.PROCESS_SKIP : return true;
|
case ASTVisitor.PROCESS_SKIP: return true;
|
||||||
default : break;
|
default: break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int getRoleForName(IASTName n ) {
|
public int getRoleForName(IASTName n) {
|
||||||
if( n == this.name )
|
if (n == this.name)
|
||||||
return r_reference;
|
return r_reference;
|
||||||
return r_unclear;
|
return r_unclear;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void replace(IASTNode child, IASTNode other) {
|
public void replace(IASTNode child, IASTNode other) {
|
||||||
if( child == owner)
|
if (child == owner) {
|
||||||
{
|
other.setPropertyInParent(child.getPropertyInParent());
|
||||||
other.setPropertyInParent( child.getPropertyInParent() );
|
other.setParent(child.getParent());
|
||||||
other.setParent( child.getParent() );
|
|
||||||
owner = (IASTExpression) other;
|
owner = (IASTExpression) other;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -159,7 +156,6 @@ public class CASTFieldReference extends ASTNode implements IASTFieldReference, I
|
||||||
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
|
return new ProblemType(ISemanticProblem.TYPE_UNKNOWN_FOR_EXPRESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLValue() {
|
public boolean isLValue() {
|
||||||
if (isPointerDereference())
|
if (isPointerDereference())
|
||||||
|
|
|
@ -18,7 +18,11 @@ import static org.eclipse.cdt.core.dom.ast.IASTExpression.ValueCategory.PRVALUE;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.glvalueType;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.prvalueType;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.ExpressionTypes.typeFromFunctionCall;
|
||||||
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.*;
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.ALLCVQ;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.CVTYPE;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.REF;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.TDEF;
|
||||||
|
import static org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil.getUltimateTypeUptoPointers;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
@ -53,15 +57,13 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPSemantics;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CVQualifier;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
|
|
||||||
public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReference, IASTAmbiguityParent,
|
public class CPPASTFieldReference extends ASTNode
|
||||||
ICPPASTCompletionContext {
|
implements ICPPASTFieldReference, IASTAmbiguityParent, ICPPASTCompletionContext {
|
||||||
|
|
||||||
private boolean isTemplate;
|
private boolean isTemplate;
|
||||||
private IASTExpression owner;
|
private IASTExpression owner;
|
||||||
private IASTName name;
|
private IASTName name;
|
||||||
private boolean isDeref;
|
private boolean isDeref;
|
||||||
|
private IASTImplicitName[] implicitNames;
|
||||||
private IASTImplicitName[] implicitNames = null;
|
|
||||||
|
|
||||||
public CPPASTFieldReference() {
|
public CPPASTFieldReference() {
|
||||||
}
|
}
|
||||||
|
@ -148,15 +150,15 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
|
||||||
if (!isDeref)
|
if (!isDeref)
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
// collect the function bindings
|
// Collect the function bindings
|
||||||
List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>();
|
List<ICPPFunction> functionBindings = new ArrayList<ICPPFunction>();
|
||||||
getFieldOwnerType(functionBindings);
|
getFieldOwnerType(functionBindings);
|
||||||
if (functionBindings.isEmpty())
|
if (functionBindings.isEmpty())
|
||||||
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
return implicitNames = IASTImplicitName.EMPTY_NAME_ARRAY;
|
||||||
|
|
||||||
// create a name to wrap each binding
|
// Create a name to wrap each binding
|
||||||
implicitNames = new IASTImplicitName[functionBindings.size()];
|
implicitNames = new IASTImplicitName[functionBindings.size()];
|
||||||
int i=-1;
|
int i= -1;
|
||||||
for (ICPPFunction op : functionBindings) {
|
for (ICPPFunction op : functionBindings) {
|
||||||
if (op != null && !(op instanceof CPPImplicitFunction)) {
|
if (op != null && !(op instanceof CPPImplicitFunction)) {
|
||||||
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
|
CPPASTImplicitName operatorName = new CPPASTImplicitName(OverloadableOperator.ARROW, this);
|
||||||
|
@ -280,7 +282,6 @@ public class CPPASTFieldReference extends ASTNode implements ICPPASTFieldReferen
|
||||||
}
|
}
|
||||||
return fieldType;
|
return fieldType;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ValueCategory getValueCategory() {
|
public ValueCategory getValueCategory() {
|
||||||
|
|
|
@ -12,10 +12,17 @@
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.ui.tests.refactoring.extractfunction;
|
package org.eclipse.cdt.ui.tests.refactoring.extractfunction;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import junit.framework.Test;
|
import junit.framework.Test;
|
||||||
|
|
||||||
|
import org.eclipse.jface.preference.IPreferenceStore;
|
||||||
import org.eclipse.ltk.core.refactoring.Refactoring;
|
import org.eclipse.ltk.core.refactoring.Refactoring;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.ui.CUIPlugin;
|
||||||
|
import org.eclipse.cdt.ui.PreferenceConstants;
|
||||||
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase;
|
import org.eclipse.cdt.ui.tests.refactoring.RefactoringTestBase;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
@ -31,6 +38,10 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
private ExtractFunctionInformation refactoringInfo;
|
private ExtractFunctionInformation refactoringInfo;
|
||||||
private String extractedFunctionName = "extracted";
|
private String extractedFunctionName = "extracted";
|
||||||
private String returnValue;
|
private String returnValue;
|
||||||
|
// Map from old names to new ones.
|
||||||
|
private Map<String, String> parameterRename = new HashMap<String, String>();
|
||||||
|
// New positions of parameters, or null.
|
||||||
|
private int[] parameterOrder;
|
||||||
private VisibilityEnum visibility = VisibilityEnum.v_private;
|
private VisibilityEnum visibility = VisibilityEnum.v_private;
|
||||||
private boolean virtual;
|
private boolean virtual;
|
||||||
private boolean replaceDuplicates = true;
|
private boolean replaceDuplicates = true;
|
||||||
|
@ -47,6 +58,26 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
return suite(ExtractFunctionRefactoringTest.class);
|
return suite(ExtractFunctionRefactoringTest.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void setUp() throws Exception {
|
||||||
|
super.setUp();
|
||||||
|
resetPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void tearDown() throws Exception {
|
||||||
|
super.tearDown();
|
||||||
|
resetPreferences();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void resetPreferences() {
|
||||||
|
getPreferenceStore().setToDefault(PreferenceConstants.FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER);
|
||||||
|
}
|
||||||
|
|
||||||
|
private IPreferenceStore getPreferenceStore() {
|
||||||
|
return CUIPlugin.getDefault().getPreferenceStore();
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected Refactoring createRefactoring() {
|
protected Refactoring createRefactoring() {
|
||||||
refactoringInfo = new ExtractFunctionInformation();
|
refactoringInfo = new ExtractFunctionInformation();
|
||||||
|
@ -61,14 +92,32 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
if (refactoringInfo.getMandatoryReturnVariable() == null) {
|
if (refactoringInfo.getMandatoryReturnVariable() == null) {
|
||||||
if (returnValue != null) {
|
if (returnValue != null) {
|
||||||
for (NameInformation nameInfo : refactoringInfo.getParameters()) {
|
for (NameInformation nameInfo : refactoringInfo.getParameters()) {
|
||||||
nameInfo.setReturnValue(returnValue.equals(String.valueOf(nameInfo.getName().getSimpleID())));
|
nameInfo.setReturnValue(returnValue.equals(getName(nameInfo)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (!parameterRename.isEmpty()) {
|
||||||
|
for (NameInformation nameInfo : refactoringInfo.getParameters()) {
|
||||||
|
String newName = parameterRename.get(getName(nameInfo));
|
||||||
|
if (newName != null)
|
||||||
|
nameInfo.setNewName(newName);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (parameterOrder != null) {
|
||||||
|
List<NameInformation> parameters = refactoringInfo.getParameters();
|
||||||
|
NameInformation[] originalParameters = parameters.toArray(new NameInformation[parameters.size()]);
|
||||||
|
for (int i = 0; i < parameterOrder.length; i++) {
|
||||||
|
parameters.set(parameterOrder[i], originalParameters[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
refactoringInfo.setVisibility(visibility);
|
refactoringInfo.setVisibility(visibility);
|
||||||
refactoringInfo.setVirtual(virtual);
|
refactoringInfo.setVirtual(virtual);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private String getName(NameInformation nameInfo) {
|
||||||
|
return String.valueOf(nameInfo.getName().getSimpleID());
|
||||||
|
}
|
||||||
|
|
||||||
//A.h
|
//A.h
|
||||||
//#ifndef A_H_
|
//#ifndef A_H_
|
||||||
//#define A_H_
|
//#define A_H_
|
||||||
|
@ -536,7 +585,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//A.cpp
|
//A.cpp
|
||||||
//#include "A.h"
|
//#include "A.h"
|
||||||
//
|
//
|
||||||
//#define ZWO 2
|
//#define TWO 2
|
||||||
//
|
//
|
||||||
//A::A() {
|
//A::A() {
|
||||||
//}
|
//}
|
||||||
|
@ -547,7 +596,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//int A::foo() {
|
//int A::foo() {
|
||||||
// int i = 2;
|
// int i = 2;
|
||||||
// /*$*/++i;
|
// /*$*/++i;
|
||||||
// i += ZWO;
|
// i += TWO;
|
||||||
// help();/*$$*/
|
// help();/*$$*/
|
||||||
// return i;
|
// return i;
|
||||||
//}
|
//}
|
||||||
|
@ -558,7 +607,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//====================
|
//====================
|
||||||
//#include "A.h"
|
//#include "A.h"
|
||||||
//
|
//
|
||||||
//#define ZWO 2
|
//#define TWO 2
|
||||||
//
|
//
|
||||||
//A::A() {
|
//A::A() {
|
||||||
//}
|
//}
|
||||||
|
@ -568,7 +617,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//
|
//
|
||||||
//int A::extracted(int i) {
|
//int A::extracted(int i) {
|
||||||
// ++i;
|
// ++i;
|
||||||
// i += ZWO;
|
// i += TWO;
|
||||||
// help();
|
// help();
|
||||||
// return i;
|
// return i;
|
||||||
//}
|
//}
|
||||||
|
@ -698,7 +747,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//
|
//
|
||||||
//private:
|
//private:
|
||||||
// int help();
|
// int help();
|
||||||
// void extracted(int* i);
|
// void extracted(int* j);
|
||||||
//};
|
//};
|
||||||
//
|
//
|
||||||
//#endif /*A_H_*/
|
//#endif /*A_H_*/
|
||||||
|
@ -731,8 +780,8 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//A::~A() {
|
//A::~A() {
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
//void A::extracted(int* i) {
|
//void A::extracted(int* j) {
|
||||||
// ++*i;
|
// ++*j;
|
||||||
// help();
|
// help();
|
||||||
//}
|
//}
|
||||||
//
|
//
|
||||||
|
@ -745,7 +794,94 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//int A::help() {
|
//int A::help() {
|
||||||
// return 42;
|
// return 42;
|
||||||
//}
|
//}
|
||||||
public void testPointer() throws Exception {
|
public void testRenamedParameter() throws Exception {
|
||||||
|
parameterRename.put("i", "j");
|
||||||
|
assertRefactoringSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
//A.c
|
||||||
|
//struct A {
|
||||||
|
// int i;
|
||||||
|
// int j;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//int test() {
|
||||||
|
// struct A a = { 1, 2 };
|
||||||
|
// return /*$*/a.i + a.j/*$$*/;
|
||||||
|
//}
|
||||||
|
//====================
|
||||||
|
//struct A {
|
||||||
|
// int i;
|
||||||
|
// int j;
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//int extracted(const struct A* a) {
|
||||||
|
// return a->i + a->j;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int test() {
|
||||||
|
// struct A a = { 1, 2 };
|
||||||
|
// return extracted(&a);
|
||||||
|
//}
|
||||||
|
public void testInputParameterPassedByPointer() throws Exception {
|
||||||
|
assertRefactoringSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
//A.c
|
||||||
|
//int test() {
|
||||||
|
// int i = 0;
|
||||||
|
// int j = 1;
|
||||||
|
// /*$*/int k = i;
|
||||||
|
// i = j;
|
||||||
|
// j = k;/*$$*/
|
||||||
|
// return i - j;
|
||||||
|
//}
|
||||||
|
//====================
|
||||||
|
//void swap(int* i, int* j) {
|
||||||
|
// int k = *i;
|
||||||
|
// *i = *j;
|
||||||
|
// *j = k;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int test() {
|
||||||
|
// int i = 0;
|
||||||
|
// int j = 1;
|
||||||
|
// swap(&i, &j);
|
||||||
|
// return i - j;
|
||||||
|
//}
|
||||||
|
public void testOutputParameterPassedByPointer() throws Exception {
|
||||||
|
extractedFunctionName = "swap";
|
||||||
|
returnValue = NO_RETURN_VALUE;
|
||||||
|
assertRefactoringSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
//A.h
|
||||||
|
//class A {
|
||||||
|
//public:
|
||||||
|
// int method();
|
||||||
|
// int const_method() const;
|
||||||
|
//};
|
||||||
|
|
||||||
|
//A.cpp
|
||||||
|
//#include "A.h"
|
||||||
|
//
|
||||||
|
//int test() {
|
||||||
|
// A a, b;
|
||||||
|
// return /*$*/a.method() + b.const_method()/*$$*/ + a.const_method();
|
||||||
|
//}
|
||||||
|
//====================
|
||||||
|
//#include "A.h"
|
||||||
|
//
|
||||||
|
//int extracted(A b, A* a) {
|
||||||
|
// return a->method() + b.const_method();
|
||||||
|
//}
|
||||||
|
//int test() {
|
||||||
|
// A a, b;
|
||||||
|
// return extracted(b, &a) + a.const_method();
|
||||||
|
//}
|
||||||
|
public void _testOutputParameterWithMethodCall() throws Exception {
|
||||||
|
// Currently fails due to http://bugs.eclipse.org/bugs/show_bug.cgi?id=370887
|
||||||
|
getPreferenceStore().setValue(PreferenceConstants.FUNCTION_PASS_OUTPUT_PARAMETERS_BY_POINTER, true);
|
||||||
assertRefactoringSuccess();
|
assertRefactoringSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2562,91 +2698,6 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
public void testDuplicates() throws Exception {
|
public void testDuplicates() throws Exception {
|
||||||
assertRefactoringSuccess();
|
assertRefactoringSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
//A.h
|
|
||||||
//#ifndef A_H_
|
|
||||||
//#define A_H_
|
|
||||||
//
|
|
||||||
//class A {
|
|
||||||
//public:
|
|
||||||
// A();
|
|
||||||
// virtual ~A();
|
|
||||||
// int foo();
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
// int help();
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//#endif /*A_H_*/
|
|
||||||
//====================
|
|
||||||
//#ifndef A_H_
|
|
||||||
//#define A_H_
|
|
||||||
//
|
|
||||||
//class A {
|
|
||||||
//public:
|
|
||||||
// A();
|
|
||||||
// virtual ~A();
|
|
||||||
// int foo();
|
|
||||||
//
|
|
||||||
//private:
|
|
||||||
// int help();
|
|
||||||
// int extracted(int i);
|
|
||||||
//};
|
|
||||||
//
|
|
||||||
//#endif /*A_H_*/
|
|
||||||
|
|
||||||
//A.cpp
|
|
||||||
//#include "A.h"
|
|
||||||
//
|
|
||||||
//A::A() {
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//A::~A() {
|
|
||||||
// int oo = 99;
|
|
||||||
// ++oo;
|
|
||||||
// help();
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//int A::foo() {
|
|
||||||
// int i = 2;
|
|
||||||
// /*$*/++i;
|
|
||||||
// help();/*$$*/
|
|
||||||
// return i;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//int A::help() {
|
|
||||||
// return 42;
|
|
||||||
//}
|
|
||||||
//====================
|
|
||||||
//#include "A.h"
|
|
||||||
//
|
|
||||||
//A::A() {
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//A::~A() {
|
|
||||||
// int oo = 99;
|
|
||||||
// oo = extracted(oo);
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//int A::extracted(int i) {
|
|
||||||
// ++i;
|
|
||||||
// help();
|
|
||||||
// return i;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//int A::foo() {
|
|
||||||
// int i = 2;
|
|
||||||
// i = extracted(i);
|
|
||||||
// return i;
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
//int A::help() {
|
|
||||||
// return 42;
|
|
||||||
//}
|
|
||||||
public void testDuplicatesWithDifferentNames() throws Exception {
|
|
||||||
assertRefactoringSuccess();
|
|
||||||
}
|
|
||||||
|
|
||||||
//A.h
|
//A.h
|
||||||
//#ifndef A_H_
|
//#ifndef A_H_
|
||||||
//#define A_H_
|
//#define A_H_
|
||||||
|
@ -2930,7 +2981,96 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//int A::help() {
|
//int A::help() {
|
||||||
// return 42;
|
// return 42;
|
||||||
//}
|
//}
|
||||||
public void testDuplicatesWithDifferentNamesAndReturnType() throws Exception {
|
public void testDuplicatesWithDifferentNames() throws Exception {
|
||||||
|
assertRefactoringSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
|
//A.h
|
||||||
|
//#ifndef A_H_
|
||||||
|
//#define A_H_
|
||||||
|
//
|
||||||
|
//class A {
|
||||||
|
//public:
|
||||||
|
// A();
|
||||||
|
// virtual ~A();
|
||||||
|
// int foo();
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
// int help();
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#endif /*A_H_*/
|
||||||
|
//====================
|
||||||
|
//#ifndef A_H_
|
||||||
|
//#define A_H_
|
||||||
|
//
|
||||||
|
//class A {
|
||||||
|
//public:
|
||||||
|
// A();
|
||||||
|
// virtual ~A();
|
||||||
|
// int foo();
|
||||||
|
//
|
||||||
|
//private:
|
||||||
|
// int help();
|
||||||
|
// int extracted(int j, int i);
|
||||||
|
//};
|
||||||
|
//
|
||||||
|
//#endif /*A_H_*/
|
||||||
|
|
||||||
|
//A.cpp
|
||||||
|
//#include "A.h"
|
||||||
|
//
|
||||||
|
//A::A() {
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//A::~A() {
|
||||||
|
// int aa = 9;
|
||||||
|
// int bb = 99;
|
||||||
|
// aa += bb;
|
||||||
|
// help();
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int A::foo() {
|
||||||
|
// int i = 2;
|
||||||
|
// int j = 3;
|
||||||
|
// /*$*/i += j;
|
||||||
|
// help();/*$$*/
|
||||||
|
// return i;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int A::help() {
|
||||||
|
// return 42;
|
||||||
|
//}
|
||||||
|
//====================
|
||||||
|
//#include "A.h"
|
||||||
|
//
|
||||||
|
//A::A() {
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//A::~A() {
|
||||||
|
// int aa = 9;
|
||||||
|
// int bb = 99;
|
||||||
|
// aa = extracted(bb, aa);
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int A::extracted(int j, int i) {
|
||||||
|
// i += j;
|
||||||
|
// help();
|
||||||
|
// return i;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int A::foo() {
|
||||||
|
// int i = 2;
|
||||||
|
// int j = 3;
|
||||||
|
// i = extracted(j, i);
|
||||||
|
// return i;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//int A::help() {
|
||||||
|
// return 42;
|
||||||
|
//}
|
||||||
|
public void testDuplicatesWithDifferentNamesAndReordering() throws Exception {
|
||||||
|
parameterOrder = new int[] { 1, 0 };
|
||||||
assertRefactoringSuccess();
|
assertRefactoringSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3105,7 +3245,7 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
//int A::help() {
|
//int A::help() {
|
||||||
// return 42;
|
// return 42;
|
||||||
//}
|
//}
|
||||||
public void testDuplicateNameUsedAfterwardsInDuplicateButNotInOriginalSelectionThisIsNoDuplicate() throws Exception {
|
public void testOutputParameterInDuplicateButNotInOriginal() throws Exception {
|
||||||
assertRefactoringSuccess();
|
assertRefactoringSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,6 @@ import org.eclipse.cdt.core.dom.ast.IASTArrayDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
import org.eclipse.cdt.core.dom.ast.IASTArrayModifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
|
@ -30,6 +29,7 @@ import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.IType;
|
import org.eclipse.cdt.core.dom.ast.IType;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTranslationUnit;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPNodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
|
import org.eclipse.cdt.core.dom.rewrite.TypeHelper;
|
||||||
import org.eclipse.cdt.core.model.ITranslationUnit;
|
import org.eclipse.cdt.core.model.ITranslationUnit;
|
||||||
|
@ -40,13 +40,16 @@ import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
||||||
* Additional information about an IASTName in code being refactored.
|
* Additional information about an IASTName in code being refactored.
|
||||||
*/
|
*/
|
||||||
public class NameInformation {
|
public class NameInformation {
|
||||||
|
public static enum Indirection { NONE, POINTER, REFERENCE }
|
||||||
|
|
||||||
public static final int INDEX_FOR_ADDED = -1;
|
public static final int INDEX_FOR_ADDED = -1;
|
||||||
|
|
||||||
private final IASTName name;
|
private final IASTName name;
|
||||||
private IASTName declarationName;
|
private IASTName declarationName;
|
||||||
private final List<IASTName> references;
|
private final List<IASTName> references;
|
||||||
private List<IASTName> referencesAfterCached;
|
private final List<IASTName> referencesBeforeSelection;
|
||||||
private int lastCachedReferencesHash;
|
private final List<IASTName> referencesInSelection;
|
||||||
|
private final List<IASTName> referencesAfterSelection;
|
||||||
private boolean isOutput;
|
private boolean isOutput;
|
||||||
private boolean mustBeReturnValue;
|
private boolean mustBeReturnValue;
|
||||||
private boolean isWriteAccess;
|
private boolean isWriteAccess;
|
||||||
|
@ -57,11 +60,15 @@ public class NameInformation {
|
||||||
private boolean isDeleted;
|
private boolean isDeleted;
|
||||||
private String defaultValue;
|
private String defaultValue;
|
||||||
private String newTypeName;
|
private String newTypeName;
|
||||||
|
private Indirection indirection;
|
||||||
|
|
||||||
public NameInformation(IASTName name) {
|
public NameInformation(IASTName name) {
|
||||||
this.name = name;
|
this.name = name;
|
||||||
this.newName = String.valueOf(name.getSimpleID());
|
this.newName = String.valueOf(name.getSimpleID());
|
||||||
references = new ArrayList<IASTName>();
|
references = new ArrayList<IASTName>();
|
||||||
|
referencesBeforeSelection = new ArrayList<IASTName>();
|
||||||
|
referencesInSelection = new ArrayList<IASTName>();
|
||||||
|
referencesAfterSelection = new ArrayList<IASTName>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static NameInformation createInfoForAddedParameter(String type, String name,
|
public static NameInformation createInfoForAddedParameter(String type, String name,
|
||||||
|
@ -99,6 +106,7 @@ public class NameInformation {
|
||||||
|
|
||||||
void setOutput(boolean isOutput) {
|
void setOutput(boolean isOutput) {
|
||||||
this.isOutput = isOutput;
|
this.isOutput = isOutput;
|
||||||
|
indirection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isOutputParameter() {
|
public boolean isOutputParameter() {
|
||||||
|
@ -111,6 +119,7 @@ public class NameInformation {
|
||||||
|
|
||||||
public void setMustBeReturnValue(boolean mustBeReturnValue) {
|
public void setMustBeReturnValue(boolean mustBeReturnValue) {
|
||||||
this.mustBeReturnValue = mustBeReturnValue;
|
this.mustBeReturnValue = mustBeReturnValue;
|
||||||
|
indirection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReturnValue() {
|
public boolean isReturnValue() {
|
||||||
|
@ -120,6 +129,7 @@ public class NameInformation {
|
||||||
public void setReturnValue(boolean isReturnValue) {
|
public void setReturnValue(boolean isReturnValue) {
|
||||||
Assert.isTrue(isReturnValue || !mustBeReturnValue);
|
Assert.isTrue(isReturnValue || !mustBeReturnValue);
|
||||||
this.isReturnValue = isReturnValue;
|
this.isReturnValue = isReturnValue;
|
||||||
|
indirection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getNewName() {
|
public String getNewName() {
|
||||||
|
@ -136,6 +146,7 @@ public class NameInformation {
|
||||||
|
|
||||||
void setWriteAccess(boolean isWriteAceess) {
|
void setWriteAccess(boolean isWriteAceess) {
|
||||||
this.isWriteAccess = isWriteAceess;
|
this.isWriteAccess = isWriteAceess;
|
||||||
|
indirection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isDeleted() {
|
public boolean isDeleted() {
|
||||||
|
@ -182,6 +193,7 @@ public class NameInformation {
|
||||||
void setDeclarationName(IASTName declarationName) {
|
void setDeclarationName(IASTName declarationName) {
|
||||||
Assert.isTrue(declarationName.getParent() instanceof IASTDeclarator);
|
Assert.isTrue(declarationName.getParent() instanceof IASTDeclarator);
|
||||||
this.declarationName = declarationName;
|
this.declarationName = declarationName;
|
||||||
|
indirection = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTName getName() {
|
public IASTName getName() {
|
||||||
|
@ -189,11 +201,19 @@ public class NameInformation {
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isRenamed() {
|
public boolean isRenamed() {
|
||||||
return name == null ? newName != null : String.valueOf(name.getSimpleID()).equals(name);
|
return name == null ? newName != null : !String.valueOf(name.getSimpleID()).equals(newName);
|
||||||
}
|
}
|
||||||
|
|
||||||
void addReference(IASTName name) {
|
void addReference(IASTName name, int startOffset, int endOffset) {
|
||||||
references.add(name);
|
references.add(name);
|
||||||
|
int nodeOffset = name.getFileLocation().getNodeOffset();
|
||||||
|
if (nodeOffset >= endOffset) {
|
||||||
|
referencesAfterSelection.add(name);
|
||||||
|
} else if (nodeOffset >= startOffset) {
|
||||||
|
referencesInSelection.add(name);
|
||||||
|
} else {
|
||||||
|
referencesBeforeSelection.add(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getTypeName() {
|
public String getTypeName() {
|
||||||
|
@ -224,22 +244,20 @@ public class NameInformation {
|
||||||
return writer.toString();
|
return writer.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<IASTName> getReferencesAfterSelection(int endOffset) {
|
public List<IASTName> getReferencesBeforeSelection() {
|
||||||
if (referencesAfterCached == null || lastCachedReferencesHash != references.hashCode()) {
|
return referencesBeforeSelection;
|
||||||
lastCachedReferencesHash = references.hashCode();
|
|
||||||
referencesAfterCached = new ArrayList<IASTName>();
|
|
||||||
for (IASTName ref : references) {
|
|
||||||
IASTFileLocation loc = ref.getFileLocation();
|
|
||||||
if (loc.getNodeOffset() >= endOffset) {
|
|
||||||
referencesAfterCached.add(ref);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return referencesAfterCached;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isReferencedAfterSelection(int endOffset) {
|
public List<IASTName> getReferencesInSelection() {
|
||||||
return !getReferencesAfterSelection(endOffset).isEmpty();
|
return referencesInSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<IASTName> getReferencesAfterSelection() {
|
||||||
|
return referencesAfterSelection;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isReferencedAfterSelection() {
|
||||||
|
return !referencesAfterSelection.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory) {
|
public IASTParameterDeclaration getParameterDeclaration(INodeFactory nodeFactory) {
|
||||||
|
@ -251,29 +269,47 @@ public class NameInformation {
|
||||||
IASTDeclSpecifier declSpec = safeCopy(getDeclSpecifier());
|
IASTDeclSpecifier declSpec = safeCopy(getDeclSpecifier());
|
||||||
IASTDeclarator declarator = createDeclarator(nodeFactory, sourceDeclarator, paramName);
|
IASTDeclarator declarator = createDeclarator(nodeFactory, sourceDeclarator, paramName);
|
||||||
|
|
||||||
if (isOutputParameter()) {
|
Indirection indirection = getIndirection();
|
||||||
if (nodeFactory instanceof ICPPNodeFactory && !passOutputByPointer) {
|
if (indirection == Indirection.POINTER) {
|
||||||
declarator.addPointerOperator(((ICPPNodeFactory) nodeFactory).newReferenceOperator(false));
|
declarator.addPointerOperator(nodeFactory.newPointer());
|
||||||
} else {
|
} else if (indirection == Indirection.REFERENCE) {
|
||||||
declarator.addPointerOperator(nodeFactory.newPointer());
|
declarator.addPointerOperator(((ICPPNodeFactory) nodeFactory).newReferenceOperator(false));
|
||||||
}
|
}
|
||||||
} else if (declSpec != null && !isWriteAccess) {
|
|
||||||
IType type = TypeHelper.createType(sourceDeclarator);
|
if (indirection != Indirection.NONE && !isWriteAccess && declSpec != null) {
|
||||||
if (TypeHelper.shouldBePassedByReference(type, declarationName.getTranslationUnit())) {
|
declSpec.setConst(true);
|
||||||
if (nodeFactory instanceof ICPPNodeFactory) {
|
|
||||||
declarator.addPointerOperator(((ICPPNodeFactory) nodeFactory).newReferenceOperator(false));
|
|
||||||
} else {
|
|
||||||
declarator.addPointerOperator(nodeFactory.newPointer());
|
|
||||||
}
|
|
||||||
declSpec.setConst(true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declarator.setNestedDeclarator(sourceDeclarator.getNestedDeclarator());
|
declarator.setNestedDeclarator(sourceDeclarator.getNestedDeclarator());
|
||||||
|
|
||||||
return nodeFactory.newParameterDeclaration(declSpec, declarator);
|
return nodeFactory.newParameterDeclaration(declSpec, declarator);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Indirection getIndirection() {
|
||||||
|
if (indirection == null) {
|
||||||
|
indirection = Indirection.NONE;
|
||||||
|
boolean isCpp = declarationName.getTranslationUnit() instanceof ICPPASTTranslationUnit;
|
||||||
|
if (isOutputParameter()) {
|
||||||
|
if (isCpp && !passOutputByPointer) {
|
||||||
|
indirection = Indirection.REFERENCE;
|
||||||
|
} else {
|
||||||
|
indirection = Indirection.POINTER;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
IType type = TypeHelper.createType(getDeclarator());
|
||||||
|
if (TypeHelper.shouldBePassedByReference(type, declarationName.getTranslationUnit())) {
|
||||||
|
if (isCpp) {
|
||||||
|
if (!isWriteAccess) {
|
||||||
|
indirection = Indirection.REFERENCE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
indirection = Indirection.POINTER;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return indirection;
|
||||||
|
}
|
||||||
|
|
||||||
private IASTDeclarator createDeclarator(INodeFactory nodeFactory, IASTDeclarator sourceDeclarator,
|
private IASTDeclarator createDeclarator(INodeFactory nodeFactory, IASTDeclarator sourceDeclarator,
|
||||||
String name) {
|
String name) {
|
||||||
IASTName astName = name != null ?
|
IASTName astName = name != null ?
|
||||||
|
@ -311,5 +347,6 @@ public class NameInformation {
|
||||||
|
|
||||||
public void setPassOutputByPointer(boolean passOutputByPointer) {
|
public void setPassOutputByPointer(boolean passOutputByPointer) {
|
||||||
this.passOutputByPointer = passOutputByPointer;
|
this.passOutputByPointer = passOutputByPointer;
|
||||||
|
indirection = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,6 +28,7 @@ import org.eclipse.core.runtime.preferences.IPreferencesService;
|
||||||
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
import org.eclipse.cdt.core.dom.ast.IASTMacroExpansionLocation;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
|
@ -73,6 +74,8 @@ public class NodeContainer {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
names = new ArrayList<NameInformation>();
|
names = new ArrayList<NameInformation>();
|
||||||
|
final int startOffset = getStartOffset();
|
||||||
|
final int endOffset = getEndOffset();
|
||||||
|
|
||||||
IPreferencesService preferences = Platform.getPreferencesService();
|
IPreferencesService preferences = Platform.getPreferencesService();
|
||||||
final boolean passOutputByPointer = preferences.getBoolean(CUIPlugin.PLUGIN_ID,
|
final boolean passOutputByPointer = preferences.getBoolean(CUIPlugin.PLUGIN_ID,
|
||||||
|
@ -87,34 +90,36 @@ public class NodeContainer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public int visit(IASTName name) {
|
public int visit(IASTName name) {
|
||||||
IBinding binding = name.resolveBinding();
|
if (name.getPropertyInParent() != IASTFieldReference.FIELD_NAME) {
|
||||||
|
IBinding binding = name.resolveBinding();
|
||||||
if (binding instanceof ICPPBinding && !(binding instanceof ICPPTemplateTypeParameter)) {
|
|
||||||
ICPPBinding cppBinding = (ICPPBinding) binding;
|
if (binding instanceof ICPPBinding && !(binding instanceof ICPPTemplateTypeParameter)) {
|
||||||
try {
|
ICPPBinding cppBinding = (ICPPBinding) binding;
|
||||||
if (!cppBinding.isGloballyQualified()) {
|
try {
|
||||||
NameInformation nameInfo = new NameInformation(name);
|
if (!cppBinding.isGloballyQualified()) {
|
||||||
nameInfo.setPassOutputByPointer(passOutputByPointer);
|
NameInformation nameInfo = new NameInformation(name);
|
||||||
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
nameInfo.setPassOutputByPointer(passOutputByPointer);
|
||||||
for (IASTName ref : refs) {
|
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
||||||
nameInfo.addReference(ref);
|
for (IASTName ref : refs) {
|
||||||
|
nameInfo.addReference(ref, startOffset, endOffset);
|
||||||
|
}
|
||||||
|
names.add(nameInfo);
|
||||||
}
|
}
|
||||||
names.add(nameInfo);
|
} catch (DOMException e) {
|
||||||
|
ILog logger = CUIPlugin.getDefault().getLog();
|
||||||
|
IStatus status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID,
|
||||||
|
e.getMessage(), e);
|
||||||
|
logger.log(status);
|
||||||
}
|
}
|
||||||
} catch (DOMException e) {
|
} else if (binding instanceof IVariable) {
|
||||||
ILog logger = CUIPlugin.getDefault().getLog();
|
NameInformation nameInformation = new NameInformation(name);
|
||||||
IStatus status = new Status(IStatus.WARNING,
|
|
||||||
CUIPlugin.PLUGIN_ID, IStatus.OK, e.getMessage(), e);
|
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
||||||
logger.log(status);
|
for (IASTName ref : refs) {
|
||||||
|
nameInformation.addReference(ref, startOffset, endOffset);
|
||||||
|
}
|
||||||
|
names.add(nameInformation);
|
||||||
}
|
}
|
||||||
} else if (binding instanceof IVariable) {
|
|
||||||
NameInformation nameInformation = new NameInformation(name);
|
|
||||||
|
|
||||||
IASTName[] refs = name.getTranslationUnit().getReferences(binding);
|
|
||||||
for (IASTName ref : refs) {
|
|
||||||
nameInformation.addReference(ref);
|
|
||||||
}
|
|
||||||
names.add(nameInformation);
|
|
||||||
}
|
}
|
||||||
return super.visit(name);
|
return super.visit(name);
|
||||||
}
|
}
|
||||||
|
@ -152,12 +157,11 @@ public class NodeContainer {
|
||||||
Set<IASTName> declarations = new HashSet<IASTName>();
|
Set<IASTName> declarations = new HashSet<IASTName>();
|
||||||
interfaceNames = new ArrayList<NameInformation>();
|
interfaceNames = new ArrayList<NameInformation>();
|
||||||
|
|
||||||
int endOffset = getEndOffset();
|
|
||||||
for (NameInformation nameInfo : names) {
|
for (NameInformation nameInfo : names) {
|
||||||
IASTName declarationName = nameInfo.getDeclarationName();
|
IASTName declarationName = nameInfo.getDeclarationName();
|
||||||
if (declarations.add(declarationName)) {
|
if (declarations.add(declarationName)) {
|
||||||
if (isDeclaredInSelection(nameInfo)) {
|
if (isDeclaredInSelection(nameInfo)) {
|
||||||
if (nameInfo.isReferencedAfterSelection(endOffset)) {
|
if (nameInfo.isReferencedAfterSelection()) {
|
||||||
nameInfo.setMustBeReturnValue(true);
|
nameInfo.setMustBeReturnValue(true);
|
||||||
interfaceNames.add(nameInfo);
|
interfaceNames.add(nameInfo);
|
||||||
}
|
}
|
||||||
|
@ -173,7 +177,7 @@ public class NodeContainer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (nameInfo.isWriteAccess() && nameInfo.isReferencedAfterSelection(endOffset)) {
|
if (nameInfo.isWriteAccess() && nameInfo.isReferencedAfterSelection()) {
|
||||||
nameInfo.setOutput(true);
|
nameInfo.setOutput(true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2011 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,11 +8,13 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
|
@ -24,7 +26,6 @@ import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTFunctionCallExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
|
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
|
@ -44,7 +45,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFieldReference;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTFunctionDefinition;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTIdExpression;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTLiteralExpression;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||||
|
@ -58,30 +58,27 @@ import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
* @author Mirko Stocker
|
* @author Mirko Stocker
|
||||||
*/
|
*/
|
||||||
public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
public class ExtractExpression extends ExtractedFunctionConstructionHelper {
|
||||||
private final static char[] ZERO= { '0' };
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> list,
|
public void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> nodes,
|
||||||
ASTRewrite rewrite, TextEditGroup group) {
|
List<NameInformation> parameters, ASTRewrite rewrite, TextEditGroup group) {
|
||||||
CPPASTReturnStatement statement = new CPPASTReturnStatement();
|
CPPASTReturnStatement statement = new CPPASTReturnStatement();
|
||||||
IASTExpression nullReturnExp =
|
statement.setReturnValue(getExpression(nodes));
|
||||||
new CPPASTLiteralExpression(IASTLiteralExpression.lk_integer_constant, ZERO);
|
ASTRewrite subRewrite = rewrite.insertBefore(compound, null, statement, group);
|
||||||
statement.setReturnValue(nullReturnExp);
|
Map<IASTName, NameInformation> changedParameters = getChangedParameterReferences(parameters);
|
||||||
ASTRewrite nestedRewrite = rewrite.insertBefore(compound, null, statement, group);
|
INodeFactory nodeFactory = nodes.get(0).getTranslationUnit().getASTNodeFactory();
|
||||||
|
adjustParameterReferences(statement, changedParameters, nodeFactory, subRewrite, group);
|
||||||
nestedRewrite.replace(nullReturnExp, getExpression(list), group);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTExpression getExpression(List<IASTNode> list) {
|
private IASTExpression getExpression(List<IASTNode> nodes) {
|
||||||
if (list.size() > 1) {
|
if (nodes.size() > 1) {
|
||||||
CPPASTBinaryExpression expression = new CPPASTBinaryExpression();
|
CPPASTBinaryExpression expression = new CPPASTBinaryExpression();
|
||||||
expression.setParent(list.get(0).getParent());
|
expression.setParent(nodes.get(0).getParent());
|
||||||
expression.setOperand1((IASTExpression) list.get(0).copy(CopyStyle.withLocations));
|
expression.setOperand1((IASTExpression) nodes.get(0).copy(CopyStyle.withLocations));
|
||||||
expression.setOperator(((IASTBinaryExpression) list.get(1).getParent()).getOperator());
|
expression.setOperator(((IASTBinaryExpression) nodes.get(1).getParent()).getOperator());
|
||||||
expression.setOperand2(getExpression(list.subList(1, list.size())));
|
expression.setOperand2(getExpression(nodes.subList(1, nodes.size())));
|
||||||
return expression;
|
return expression;
|
||||||
} else {
|
} else {
|
||||||
return (IASTExpression) list.get(0).copy(CopyStyle.withLocations);
|
return (IASTExpression) nodes.get(0).copy(CopyStyle.withLocations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -61,6 +61,7 @@ import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
import org.eclipse.cdt.core.dom.ast.IBasicType;
|
||||||
import org.eclipse.cdt.core.dom.ast.IBinding;
|
import org.eclipse.cdt.core.dom.ast.IBinding;
|
||||||
import org.eclipse.cdt.core.dom.ast.IField;
|
import org.eclipse.cdt.core.dom.ast.IField;
|
||||||
|
@ -101,7 +102,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTQualifiedName;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTReturnStatement;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTemplateDeclaration;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNodeFactory;
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.SemanticUtil;
|
||||||
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
import org.eclipse.cdt.internal.core.dom.rewrite.astwriter.ASTWriterVisitor;
|
||||||
|
|
||||||
|
@ -113,6 +113,7 @@ import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
|
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation.Indirection;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor;
|
import org.eclipse.cdt.internal.ui.refactoring.utils.CPPASTAllVisitor;
|
||||||
|
@ -138,8 +139,8 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
|
|
||||||
HashMap<String, Integer> nameTrail;
|
HashMap<String, Integer> nameTrail;
|
||||||
|
|
||||||
private ExtractedFunctionConstructionHelper extractedFunctionConstructionHelper;
|
private ExtractedFunctionConstructionHelper functionConstructionHelper;
|
||||||
private final INodeFactory nodeFactory = CPPNodeFactory.getDefault();
|
private INodeFactory nodeFactory;
|
||||||
DefaultCodeFormatterOptions formattingOptions;
|
DefaultCodeFormatterOptions formattingOptions;
|
||||||
|
|
||||||
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
||||||
|
@ -167,6 +168,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
nodeFactory = ast.getASTNodeFactory();
|
||||||
container = findExtractableNodes();
|
container = findExtractableNodes();
|
||||||
sm.worked(1);
|
sm.worked(1);
|
||||||
|
|
||||||
|
@ -212,7 +214,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
PreferenceConstants.getPreferenceScopes(project.getProject()));
|
PreferenceConstants.getPreferenceScopes(project.getProject()));
|
||||||
info.sortParameters(outFirst);
|
info.sortParameters(outFirst);
|
||||||
|
|
||||||
extractedFunctionConstructionHelper =
|
functionConstructionHelper =
|
||||||
ExtractedFunctionConstructionHelper.createFor(container.getNodesToWrite());
|
ExtractedFunctionConstructionHelper.createFor(container.getNodesToWrite());
|
||||||
|
|
||||||
boolean isExtractExpression = container.getNodesToWrite().get(0) instanceof IASTExpression;
|
boolean isExtractExpression = container.getNodesToWrite().get(0) instanceof IASTExpression;
|
||||||
|
@ -354,7 +356,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMethodCalls(final IASTName astMethodName, MethodContext context,
|
private void createMethodCalls(IASTName methodName, MethodContext context,
|
||||||
ModificationCollector collector) throws CoreException {
|
ModificationCollector collector) throws CoreException {
|
||||||
String title;
|
String title;
|
||||||
if (context.getType() == MethodContext.ContextType.METHOD) {
|
if (context.getType() == MethodContext.ContextType.METHOD) {
|
||||||
|
@ -363,7 +365,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
||||||
}
|
}
|
||||||
|
|
||||||
IASTNode methodCall = getMethodCall(astMethodName);
|
IASTNode methodCall = getMethodCall(methodName);
|
||||||
|
|
||||||
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
||||||
ASTRewrite rewriter = collector.rewriterForTranslationUnit(
|
ASTRewrite rewriter = collector.rewriterForTranslationUnit(
|
||||||
|
@ -377,7 +379,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
insertCallIntoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
insertCallIntoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
||||||
|
|
||||||
if (info.isReplaceDuplicates()) {
|
if (info.isReplaceDuplicates()) {
|
||||||
replaceSimilar(collector, astMethodName);
|
replaceSimilar(collector, methodName);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (IASTNode node : container.getNodesToWrite()) {
|
for (IASTNode node : container.getNodesToWrite()) {
|
||||||
|
@ -415,7 +417,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return binExp;
|
return binExp;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createMethodDefinition(final IASTName astMethodName, MethodContext context,
|
private void createMethodDefinition(final IASTName methodName, MethodContext context,
|
||||||
IASTNode firstNode, ModificationCollector collector) {
|
IASTNode firstNode, ModificationCollector collector) {
|
||||||
IASTFunctionDefinition node = NodeHelper.findFunctionDefinitionInAncestors(firstNode);
|
IASTFunctionDefinition node = NodeHelper.findFunctionDefinitionInAncestors(firstNode);
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
|
@ -427,7 +429,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
|
|
||||||
ASTRewrite rewriter = collector.rewriterForTranslationUnit(node.getTranslationUnit());
|
ASTRewrite rewriter = collector.rewriterForTranslationUnit(node.getTranslationUnit());
|
||||||
addMethod(astMethodName, context, rewriter, node, new TextEditGroup(title));
|
addMethod(methodName, context, rewriter, node, new TextEditGroup(title));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -618,17 +620,17 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addMethod(IASTName astMethodName, MethodContext context, ASTRewrite rewriter,
|
private void addMethod(IASTName methodName, MethodContext context, ASTRewrite rewrite,
|
||||||
IASTNode insertPoint, TextEditGroup group) {
|
IASTNode insertPoint, TextEditGroup group) {
|
||||||
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
|
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
|
||||||
if (context.getType() == ContextType.METHOD) {
|
if (context.getType() == ContextType.METHOD) {
|
||||||
if (context.getMethodQName() != null) {
|
if (context.getMethodQName() != null) {
|
||||||
for (int i = 0; i < (context.getMethodQName().getNames().length - 1); i++) {
|
for (int i = 0; i < context.getMethodQName().getNames().length - 1; i++) {
|
||||||
qname.addName(new CPPASTName(context.getMethodQName().getNames()[i].toCharArray()));
|
qname.addName(new CPPASTName(context.getMethodQName().getNames()[i].toCharArray()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
qname.addName(astMethodName);
|
qname.addName(methodName);
|
||||||
|
|
||||||
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
|
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
|
||||||
func.setParent(ast);
|
func.setParent(ast);
|
||||||
|
@ -637,32 +639,33 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
func.setDeclSpecifier(returnType);
|
func.setDeclSpecifier(returnType);
|
||||||
|
|
||||||
IASTStandardFunctionDeclarator createdFunctionDeclarator =
|
IASTStandardFunctionDeclarator createdFunctionDeclarator =
|
||||||
extractedFunctionConstructionHelper.createFunctionDeclarator(qname,
|
functionConstructionHelper.createFunctionDeclarator(qname,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameters(), ast.getASTNodeFactory());
|
info.getParameters(), nodeFactory);
|
||||||
func.setDeclarator(createdFunctionDeclarator);
|
func.setDeclarator(createdFunctionDeclarator);
|
||||||
|
|
||||||
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
IASTCompoundStatement compound = new CPPASTCompoundStatement();
|
||||||
func.setBody(compound);
|
func.setBody(compound);
|
||||||
|
|
||||||
ASTRewrite subRW;
|
ASTRewrite subRewrite;
|
||||||
if (insertPoint.getParent() instanceof ICPPASTTemplateDeclaration) {
|
IASTNode parent = insertPoint.getParent();
|
||||||
|
if (parent instanceof ICPPASTTemplateDeclaration) {
|
||||||
|
ICPPASTTemplateDeclaration parentTemplate = (ICPPASTTemplateDeclaration) parent;
|
||||||
CPPASTTemplateDeclaration templateDeclaration = new CPPASTTemplateDeclaration();
|
CPPASTTemplateDeclaration templateDeclaration = new CPPASTTemplateDeclaration();
|
||||||
templateDeclaration.setParent(ast);
|
templateDeclaration.setParent(ast);
|
||||||
|
|
||||||
for (ICPPASTTemplateParameter param : ((ICPPASTTemplateDeclaration) insertPoint.getParent()).getTemplateParameters()) {
|
for (ICPPASTTemplateParameter param : parentTemplate.getTemplateParameters()) {
|
||||||
templateDeclaration.addTemplateParameter(param.copy(CopyStyle.withLocations));
|
templateDeclaration.addTemplateParameter(param.copy(CopyStyle.withLocations));
|
||||||
}
|
}
|
||||||
|
|
||||||
templateDeclaration.setDeclaration(func);
|
templateDeclaration.setDeclaration(func);
|
||||||
subRW = rewriter.insertBefore(insertPoint.getParent().getParent(), insertPoint.getParent(),
|
subRewrite = rewrite.insertBefore(parent.getParent(), parent, templateDeclaration, group);
|
||||||
templateDeclaration, group);
|
|
||||||
} else {
|
} else {
|
||||||
subRW = rewriter.insertBefore(insertPoint.getParent(), insertPoint, func, group);
|
subRewrite = rewrite.insertBefore(parent, insertPoint, func, group);
|
||||||
}
|
}
|
||||||
|
|
||||||
extractedFunctionConstructionHelper.constructMethodBody(compound,
|
functionConstructionHelper.constructMethodBody(compound, container.getNodesToWrite(),
|
||||||
container.getNodesToWrite(), subRW, group);
|
info.getParameters(), subRewrite, group);
|
||||||
|
|
||||||
// Set return value
|
// Set return value
|
||||||
NameInformation returnVariable = info.getReturnVariable();
|
NameInformation returnVariable = info.getReturnVariable();
|
||||||
|
@ -675,7 +678,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
expr.setName(new CPPASTName(returnVariable.getNewName().toCharArray()));
|
expr.setName(new CPPASTName(returnVariable.getNewName().toCharArray()));
|
||||||
}
|
}
|
||||||
returnStmt.setReturnValue(expr);
|
returnStmt.setReturnValue(expr);
|
||||||
subRW.insertBefore(compound, null, returnStmt, group);
|
subRewrite.insertBefore(compound, null, returnStmt, group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -686,7 +689,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
private IASTDeclSpecifier getReturnType() {
|
private IASTDeclSpecifier getReturnType() {
|
||||||
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
IASTNode firstNodeToWrite = container.getNodesToWrite().get(0);
|
||||||
NameInformation returnVariable = info.getReturnVariable();
|
NameInformation returnVariable = info.getReturnVariable();
|
||||||
return extractedFunctionConstructionHelper.determineReturnType(firstNodeToWrite,
|
return functionConstructionHelper.determineReturnType(firstNodeToWrite,
|
||||||
returnVariable);
|
returnVariable);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -755,28 +758,28 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
return getReturnAssignment(stmt, callExpression, retName);
|
return getReturnAssignment(stmt, callExpression, retName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTNode getMethodCall(IASTName astMethodName) {
|
private IASTNode getMethodCall(IASTName methodName) {
|
||||||
IASTExpressionStatement stmt = new CPPASTExpressionStatement();
|
IASTExpressionStatement statement = new CPPASTExpressionStatement();
|
||||||
|
|
||||||
IASTFunctionCallExpression callExpression = new CPPASTFunctionCallExpression();
|
IASTFunctionCallExpression callExpression = new CPPASTFunctionCallExpression();
|
||||||
IASTIdExpression idExpression = new CPPASTIdExpression();
|
IASTIdExpression idExpression = new CPPASTIdExpression();
|
||||||
idExpression.setName(new CPPASTName(astMethodName.toCharArray()));
|
idExpression.setName(new CPPASTName(methodName.toCharArray()));
|
||||||
List<IASTInitializerClause> args = getCallParameters();
|
List<IASTInitializerClause> args = getCallParameters();
|
||||||
callExpression.setArguments(args.toArray(new IASTInitializerClause[args.size()]));
|
callExpression.setArguments(args.toArray(new IASTInitializerClause[args.size()]));
|
||||||
callExpression.setFunctionNameExpression(idExpression);
|
callExpression.setFunctionNameExpression(idExpression);
|
||||||
|
|
||||||
if (info.getReturnVariable() == null) {
|
if (info.getReturnVariable() == null) {
|
||||||
return getReturnAssignment(stmt, callExpression);
|
return getReturnAssignment(statement, callExpression);
|
||||||
}
|
}
|
||||||
IASTName retname = newName(info.getReturnVariable().getName());
|
IASTName retName = newName(info.getReturnVariable().getName());
|
||||||
return getReturnAssignment(stmt, callExpression, retname);
|
return getReturnAssignment(statement, callExpression, retName);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
||||||
IASTFunctionCallExpression callExpression, IASTName retname) {
|
IASTFunctionCallExpression callExpression, IASTName retname) {
|
||||||
if (info.getReturnVariable().equals(info.getMandatoryReturnVariable())) {
|
if (info.getReturnVariable().equals(info.getMandatoryReturnVariable())) {
|
||||||
IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(info
|
IASTSimpleDeclaration orgDecl = NodeHelper.findSimpleDeclarationInParents(
|
||||||
.getReturnVariable().getDeclarationName());
|
info.getReturnVariable().getDeclarationName());
|
||||||
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
IASTSimpleDeclaration decl = new CPPASTSimpleDeclaration();
|
||||||
|
|
||||||
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy(CopyStyle.withLocations));
|
decl.setDeclSpecifier(orgDecl.getDeclSpecifier().copy(CopyStyle.withLocations));
|
||||||
|
@ -810,15 +813,15 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
private IASTNode getReturnAssignment(IASTExpressionStatement stmt,
|
||||||
IASTExpression callExpression) {
|
IASTExpression callExpression) {
|
||||||
IASTNode node = container.getNodesToWrite().get(0);
|
IASTNode node = container.getNodesToWrite().get(0);
|
||||||
return extractedFunctionConstructionHelper.createReturnAssignment(node, stmt, callExpression);
|
return functionConstructionHelper.createReturnAssignment(node, stmt, callExpression);
|
||||||
}
|
}
|
||||||
|
|
||||||
private IASTSimpleDeclaration getDeclaration(IASTName name) {
|
private IASTSimpleDeclaration getDeclaration(IASTName name) {
|
||||||
IASTSimpleDeclaration simpleDecl = new CPPASTSimpleDeclaration();
|
IASTSimpleDeclaration simpleDecl = new CPPASTSimpleDeclaration();
|
||||||
IASTStandardFunctionDeclarator declarator =
|
IASTStandardFunctionDeclarator declarator =
|
||||||
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
functionConstructionHelper.createFunctionDeclarator(name,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameters(), ast.getASTNodeFactory());
|
info.getParameters(), nodeFactory);
|
||||||
simpleDecl.addDeclarator(declarator);
|
simpleDecl.addDeclarator(declarator);
|
||||||
return simpleDecl;
|
return simpleDecl;
|
||||||
}
|
}
|
||||||
|
@ -831,9 +834,9 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
}
|
}
|
||||||
simpleDecl.setParent(ast);
|
simpleDecl.setParent(ast);
|
||||||
IASTStandardFunctionDeclarator declarator =
|
IASTStandardFunctionDeclarator declarator =
|
||||||
extractedFunctionConstructionHelper.createFunctionDeclarator(name,
|
functionConstructionHelper.createFunctionDeclarator(name,
|
||||||
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
info.getDeclarator(), info.getReturnVariable(), container.getNodesToWrite(),
|
||||||
info.getParameters(), ast.getASTNodeFactory());
|
info.getParameters(), nodeFactory);
|
||||||
simpleDecl.addDeclarator(declarator);
|
simpleDecl.addDeclarator(declarator);
|
||||||
return simpleDecl;
|
return simpleDecl;
|
||||||
}
|
}
|
||||||
|
@ -881,8 +884,10 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
||||||
if (!container.isDeclaredInSelection(nameInfo)) {
|
if (!container.isDeclaredInSelection(nameInfo)) {
|
||||||
IASTName declaration = nameInfo.getDeclarationName();
|
IASTName declaration = nameInfo.getDeclarationName();
|
||||||
if (declarations.add(declaration)) {
|
if (declarations.add(declaration)) {
|
||||||
IASTIdExpression expression = new CPPASTIdExpression();
|
IASTExpression expression = nodeFactory.newIdExpression(newName(declaration));
|
||||||
expression.setName(newName(declaration));
|
if (nameInfo.getIndirection() == Indirection.POINTER) {
|
||||||
|
expression = nodeFactory.newUnaryExpression(IASTUnaryExpression.op_amper, expression);
|
||||||
|
}
|
||||||
args.add(expression);
|
args.add(expression);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,10 +8,12 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
|
@ -19,9 +21,11 @@ import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTSimpleDeclSpecifier;
|
||||||
|
@ -35,9 +39,12 @@ import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
|
||||||
public class ExtractStatement extends ExtractedFunctionConstructionHelper {
|
public class ExtractStatement extends ExtractedFunctionConstructionHelper {
|
||||||
@Override
|
@Override
|
||||||
public void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> nodes,
|
public void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> nodes,
|
||||||
ASTRewrite rewrite, TextEditGroup group) {
|
List<NameInformation> parameters, ASTRewrite rewrite, TextEditGroup group) {
|
||||||
|
Map<IASTName, NameInformation> changedParameters = getChangedParameterReferences(parameters);
|
||||||
|
INodeFactory nodeFactory = nodes.get(0).getTranslationUnit().getASTNodeFactory();
|
||||||
for (IASTNode node : nodes) {
|
for (IASTNode node : nodes) {
|
||||||
rewrite.insertBefore(compound, null, node, group);
|
ASTRewrite subRewrite = rewrite.insertBefore(compound, null, node, group);
|
||||||
|
adjustParameterReferences(node, changedParameters, nodeFactory, subRewrite, group);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*******************************************************************************
|
/*******************************************************************************
|
||||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
* Copyright (c) 2008, 2012 Institute for Software, HSR Hochschule fuer Technik
|
||||||
* Rapperswil, University of applied sciences and others
|
* Rapperswil, University of applied sciences 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
|
||||||
|
@ -8,31 +8,41 @@
|
||||||
*
|
*
|
||||||
* Contributors:
|
* Contributors:
|
||||||
* Institute for Software - initial API and implementation
|
* Institute for Software - initial API and implementation
|
||||||
|
* Sergey Prigogin (Google)
|
||||||
*******************************************************************************/
|
*******************************************************************************/
|
||||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.HashMap;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import org.eclipse.text.edits.TextEditGroup;
|
import org.eclipse.text.edits.TextEditGroup;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.core.dom.ast.ASTVisitor;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
import org.eclipse.cdt.core.dom.ast.IASTExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
import org.eclipse.cdt.core.dom.ast.IASTExpressionStatement;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
import org.eclipse.cdt.core.dom.ast.IASTNode.CopyStyle;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
|
||||||
|
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
|
||||||
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
||||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||||
|
|
||||||
|
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation;
|
||||||
|
import org.eclipse.cdt.internal.ui.refactoring.NameInformation.Indirection;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Mirko Stocker
|
* @author Mirko Stocker
|
||||||
|
@ -46,8 +56,8 @@ public abstract class ExtractedFunctionConstructionHelper {
|
||||||
return new ExtractStatement();
|
return new ExtractStatement();
|
||||||
}
|
}
|
||||||
|
|
||||||
public abstract void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> list,
|
public abstract void constructMethodBody(IASTCompoundStatement compound, List<IASTNode> nodes,
|
||||||
ASTRewrite rewrite, TextEditGroup group);
|
List<NameInformation> parameters, ASTRewrite rewrite, TextEditGroup group);
|
||||||
|
|
||||||
public abstract IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
public abstract IASTDeclSpecifier determineReturnType(IASTNode extractedNode,
|
||||||
NameInformation returnVariable);
|
NameInformation returnVariable);
|
||||||
|
@ -99,4 +109,83 @@ public abstract class ExtractedFunctionConstructionHelper {
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adjusts parameter references under the given node to account for renamed parameters and
|
||||||
|
* parameters passed by pointer.
|
||||||
|
*
|
||||||
|
* @param node the root node of the AST subtree to be adjusted
|
||||||
|
* @param changedParameters the map from references to changed parameters to parameters
|
||||||
|
* themselves
|
||||||
|
* @param rewrite the rewrite for the node
|
||||||
|
* @param group the edit group to add the changes to
|
||||||
|
*/
|
||||||
|
protected static void adjustParameterReferences(IASTNode node,
|
||||||
|
final Map<IASTName, NameInformation> changedParameters, final INodeFactory nodeFactory,
|
||||||
|
final ASTRewrite rewrite, final TextEditGroup group) {
|
||||||
|
if (changedParameters.isEmpty())
|
||||||
|
return;
|
||||||
|
node.accept(new ASTVisitor() {
|
||||||
|
{
|
||||||
|
shouldVisitNames = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int visit(IASTName name) {
|
||||||
|
NameInformation param = changedParameters.get(((ASTNode) name).getOriginalNode());
|
||||||
|
if (param != null) {
|
||||||
|
IASTName newName = null;
|
||||||
|
if (param.isRenamed()) {
|
||||||
|
newName = nodeFactory.newName(param.getNewName().toCharArray());
|
||||||
|
}
|
||||||
|
if (param.getIndirection() == Indirection.POINTER &&
|
||||||
|
name.getPropertyInParent() == IASTIdExpression.ID_NAME) {
|
||||||
|
IASTIdExpression idExp = (IASTIdExpression) name.getParent();
|
||||||
|
if (idExp.getPropertyInParent() == IASTFieldReference.FIELD_OWNER &&
|
||||||
|
!((IASTFieldReference) idExp.getParent()).isPointerDereference()) {
|
||||||
|
IASTFieldReference dotRef = (IASTFieldReference) idExp.getParent();
|
||||||
|
IASTFieldReference arrowRef = dotRef.copy(CopyStyle.withLocations);
|
||||||
|
arrowRef.setIsPointerDereference(true);
|
||||||
|
if (newName != null) {
|
||||||
|
idExp = (IASTIdExpression) arrowRef.getFieldOwner();
|
||||||
|
idExp.setName(newName);
|
||||||
|
}
|
||||||
|
rewrite.replace(dotRef, arrowRef, group);
|
||||||
|
} else {
|
||||||
|
IASTIdExpression newIdExp = idExp.copy(CopyStyle.withLocations);
|
||||||
|
IASTUnaryExpression starExp =
|
||||||
|
nodeFactory.newUnaryExpression(IASTUnaryExpression.op_star, newIdExp);
|
||||||
|
if (newName != null) {
|
||||||
|
newIdExp.setName(newName);
|
||||||
|
}
|
||||||
|
rewrite.replace(idExp, starExp, group);
|
||||||
|
}
|
||||||
|
} else if (newName != null) {
|
||||||
|
rewrite.replace(name, newName, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return super.visit(name);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns a map from references to parameters inside the body of the extracted function to
|
||||||
|
* the parameters themselves. The map includes only the parameters that are either renamed,
|
||||||
|
* or passed by pointer.
|
||||||
|
*
|
||||||
|
* @param parameters the function parameters.
|
||||||
|
* @return a map from references to parameters to parameters themselves.
|
||||||
|
*/
|
||||||
|
protected static Map<IASTName, NameInformation> getChangedParameterReferences(List<NameInformation> parameters) {
|
||||||
|
final Map<IASTName, NameInformation> referenceLookupMap = new HashMap<IASTName, NameInformation>();
|
||||||
|
for (NameInformation param : parameters) {
|
||||||
|
if (param.isRenamed() || param.getIndirection() == Indirection.POINTER) {
|
||||||
|
for (IASTName name : param.getReferencesInSelection()) {
|
||||||
|
referenceLookupMap.put(name, param);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return referenceLookupMap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue