mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-07 17:56:01 +02:00
Few bug fixes for Extract Function refactoring.
This commit is contained in:
parent
dcc522e86e
commit
018eb7334b
4 changed files with 60 additions and 18 deletions
|
@ -819,6 +819,38 @@ public class ExtractFunctionRefactoringTest extends RefactoringTestBase {
|
||||||
assertRefactoringSuccess();
|
assertRefactoringSuccess();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//A.h
|
||||||
|
//class A {
|
||||||
|
//public:
|
||||||
|
// A(int i, const char* s);
|
||||||
|
// int method();
|
||||||
|
//};
|
||||||
|
|
||||||
|
//A.cpp
|
||||||
|
//#include "A.h"
|
||||||
|
//
|
||||||
|
//void test(int i, const char* s) {
|
||||||
|
// /*$*/A a(i, s);/*$$*/
|
||||||
|
// if (i != 0)
|
||||||
|
// a.method();
|
||||||
|
//}
|
||||||
|
//====================
|
||||||
|
//#include "A.h"
|
||||||
|
//
|
||||||
|
//A extracted(int i, const char* s) {
|
||||||
|
// A a(i, s);
|
||||||
|
// return a;
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//void test(int i, const char* s) {
|
||||||
|
// A a = extracted(i, s);
|
||||||
|
// if (i != 0)
|
||||||
|
// a.method();
|
||||||
|
//}
|
||||||
|
public void testReturnValueWithCtorInitializer() throws Exception {
|
||||||
|
assertRefactoringSuccess();
|
||||||
|
}
|
||||||
|
|
||||||
//A.h
|
//A.h
|
||||||
//#ifndef A_H_
|
//#ifndef A_H_
|
||||||
//#define A_H_
|
//#define A_H_
|
||||||
|
|
|
@ -84,6 +84,7 @@ import org.eclipse.cdt.core.dom.ast.gnu.c.ICASTKnRFunctionDeclarator;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVariableReadWriteFlags;
|
||||||
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
|
||||||
|
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Special flow analyzer to determine the return value of the extracted method
|
* Special flow analyzer to determine the return value of the extracted method
|
||||||
|
@ -919,7 +920,21 @@ abstract class FlowAnalyzer extends ASTGenericVisitor {
|
||||||
int index = fFlowContext.getIndexFromLocal(variable);
|
int index = fFlowContext.getIndexFromLocal(variable);
|
||||||
if (index >= 0) {
|
if (index >= 0) {
|
||||||
int accessMode = CPPVariableReadWriteFlags.getReadWriteFlags(node);
|
int accessMode = CPPVariableReadWriteFlags.getReadWriteFlags(node);
|
||||||
setFlowInfo(node, new LocalFlowInfo(variable, index, accessMode, fFlowContext));
|
if (accessMode != 0) {
|
||||||
|
int flowInfoMode = FlowInfo.UNUSED;
|
||||||
|
switch (accessMode) {
|
||||||
|
case PDOMName.READ_ACCESS:
|
||||||
|
flowInfoMode = FlowInfo.READ;
|
||||||
|
break;
|
||||||
|
case PDOMName.WRITE_ACCESS:
|
||||||
|
flowInfoMode = FlowInfo.WRITE;
|
||||||
|
break;
|
||||||
|
case PDOMName.READ_ACCESS | PDOMName.WRITE_ACCESS:
|
||||||
|
flowInfoMode = FlowInfo.UNKNOWN;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
setFlowInfo(node, new LocalFlowInfo(variable, index, flowInfoMode, fFlowContext));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1010,9 +1025,9 @@ abstract class FlowAnalyzer extends ASTGenericVisitor {
|
||||||
return;
|
return;
|
||||||
FunctionCallFlowInfo info= createFunctionCallFlowInfo();
|
FunctionCallFlowInfo info= createFunctionCallFlowInfo();
|
||||||
setFlowInfo(node, info);
|
setFlowInfo(node, info);
|
||||||
|
info.mergeReceiver(getFlowInfo(functionNameExpression), fFlowContext);
|
||||||
for (IASTInitializerClause arg : arguments) {
|
for (IASTInitializerClause arg : arguments) {
|
||||||
info.mergeArgument(getFlowInfo(arg), fFlowContext);
|
info.mergeArgument(getFlowInfo(arg), fFlowContext);
|
||||||
}
|
}
|
||||||
info.mergeReceiver(getFlowInfo(functionNameExpression), fFlowContext);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,6 @@ import java.util.Set;
|
||||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||||
import org.eclipse.cdt.core.dom.ast.IVariable;
|
import org.eclipse.cdt.core.dom.ast.IVariable;
|
||||||
|
|
||||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
|
||||||
|
|
||||||
public abstract class FlowInfo {
|
public abstract class FlowInfo {
|
||||||
// Return statement handling.
|
// Return statement handling.
|
||||||
protected static final int NOT_POSSIBLE= 0;
|
protected static final int NOT_POSSIBLE= 0;
|
||||||
|
@ -32,12 +30,12 @@ public abstract class FlowInfo {
|
||||||
protected static final int THROW= 6;
|
protected static final int THROW= 6;
|
||||||
|
|
||||||
// Local access handling.
|
// Local access handling.
|
||||||
public static final int READ= PDOMName.READ_ACCESS; // 1 << 9
|
|
||||||
public static final int WRITE= PDOMName.WRITE_ACCESS; // 1 << 10
|
|
||||||
public static final int UNUSED= 1 << 0;
|
public static final int UNUSED= 1 << 0;
|
||||||
public static final int READ_POTENTIAL= 1 << 1;
|
public static final int READ= 1 << 1;
|
||||||
public static final int WRITE_POTENTIAL= 1 << 2;
|
public static final int READ_POTENTIAL= 1 << 2;
|
||||||
public static final int UNKNOWN= 1 << 3;
|
public static final int WRITE= 1 << 3;
|
||||||
|
public static final int WRITE_POTENTIAL= 1 << 4;
|
||||||
|
public static final int UNKNOWN= 1 << 5;
|
||||||
|
|
||||||
// Table to merge access modes for condition statements (e.g branch[x] || branch[y]).
|
// Table to merge access modes for condition statements (e.g branch[x] || branch[y]).
|
||||||
private static final int[][] ACCESS_MODE_CONDITIONAL_TABLE= {
|
private static final int[][] ACCESS_MODE_CONDITIONAL_TABLE= {
|
||||||
|
@ -236,8 +234,7 @@ public abstract class FlowInfo {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given local variable binding has the given access
|
* Checks whether the given local variable binding has the given access mode.
|
||||||
* mode.
|
|
||||||
*
|
*
|
||||||
* @param context the flow context used during flow analysis
|
* @param context the flow context used during flow analysis
|
||||||
* @param local local variable of interest
|
* @param local local variable of interest
|
||||||
|
@ -374,9 +371,9 @@ public abstract class FlowInfo {
|
||||||
return;
|
return;
|
||||||
} else {
|
} else {
|
||||||
if (others == null) {
|
if (others == null) {
|
||||||
|
int index_unused= getIndex(UNUSED);
|
||||||
for (int i= 0; i < fAccessModes.length; i++) {
|
for (int i= 0; i < fAccessModes.length; i++) {
|
||||||
int unused_index= getIndex(UNUSED);
|
fAccessModes[i]= ACCESS_MODE_CONDITIONAL_TABLE[getIndex(fAccessModes[i])][index_unused];
|
||||||
fAccessModes[i]= ACCESS_MODE_CONDITIONAL_TABLE[getIndex(fAccessModes[i])][unused_index];
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
for (int i= 0; i < fAccessModes.length; i++) {
|
for (int i= 0; i < fAccessModes.length; i++) {
|
||||||
|
@ -398,14 +395,13 @@ public abstract class FlowInfo {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
int unused_index= getIndex(UNUSED);
|
int index_unused= getIndex(UNUSED);
|
||||||
for (int i= 0; i < fAccessModes.length; i++) {
|
for (int i= 0; i < fAccessModes.length; i++) {
|
||||||
fAccessModes[i]= ACCESS_MODE_CONDITIONAL_TABLE[getIndex(fAccessModes[i])][unused_index];
|
fAccessModes[i]= ACCESS_MODE_CONDITIONAL_TABLE[getIndex(fAccessModes[i])][index_unused];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int getIndex(int accessMode) {
|
private static int getIndex(int accessMode) {
|
||||||
// Fast log function
|
|
||||||
switch (accessMode) {
|
switch (accessMode) {
|
||||||
case UNUSED:
|
case UNUSED:
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -414,7 +410,6 @@ public abstract class FlowInfo {
|
||||||
case READ_POTENTIAL:
|
case READ_POTENTIAL:
|
||||||
return 2;
|
return 2;
|
||||||
case WRITE:
|
case WRITE:
|
||||||
case READ | WRITE:
|
|
||||||
return 3;
|
return 3;
|
||||||
case WRITE_POTENTIAL:
|
case WRITE_POTENTIAL:
|
||||||
return 4;
|
return 4;
|
||||||
|
|
|
@ -248,7 +248,7 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected boolean traverseNode(IASTNode node) {
|
protected boolean traverseNode(IASTNode node) {
|
||||||
return !isBefore(node, loopRegion.firstLabelStatement) &&
|
return !selection.covers(node) && !isBefore(node, loopRegion.firstLabelStatement) &&
|
||||||
!isBefore(loopRegion.lastGotoStatement, node);
|
!isBefore(loopRegion.lastGotoStatement, node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue