mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-06-06 17:26: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();
|
||||
}
|
||||
|
||||
//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
|
||||
//#ifndef 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.CPPVisitor;
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||
|
||||
/**
|
||||
* 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);
|
||||
if (index >= 0) {
|
||||
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;
|
||||
FunctionCallFlowInfo info= createFunctionCallFlowInfo();
|
||||
setFlowInfo(node, info);
|
||||
info.mergeReceiver(getFlowInfo(functionNameExpression), fFlowContext);
|
||||
for (IASTInitializerClause arg : arguments) {
|
||||
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.IVariable;
|
||||
|
||||
import org.eclipse.cdt.internal.core.pdom.dom.PDOMName;
|
||||
|
||||
public abstract class FlowInfo {
|
||||
// Return statement handling.
|
||||
protected static final int NOT_POSSIBLE= 0;
|
||||
|
@ -32,12 +30,12 @@ public abstract class FlowInfo {
|
|||
protected static final int THROW= 6;
|
||||
|
||||
// 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 READ_POTENTIAL= 1 << 1;
|
||||
public static final int WRITE_POTENTIAL= 1 << 2;
|
||||
public static final int UNKNOWN= 1 << 3;
|
||||
public static final int READ= 1 << 1;
|
||||
public static final int READ_POTENTIAL= 1 << 2;
|
||||
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]).
|
||||
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
|
||||
* mode.
|
||||
* Checks whether the given local variable binding has the given access mode.
|
||||
*
|
||||
* @param context the flow context used during flow analysis
|
||||
* @param local local variable of interest
|
||||
|
@ -374,9 +371,9 @@ public abstract class FlowInfo {
|
|||
return;
|
||||
} else {
|
||||
if (others == null) {
|
||||
int index_unused= getIndex(UNUSED);
|
||||
for (int i= 0; i < fAccessModes.length; i++) {
|
||||
int unused_index= getIndex(UNUSED);
|
||||
fAccessModes[i]= ACCESS_MODE_CONDITIONAL_TABLE[getIndex(fAccessModes[i])][unused_index];
|
||||
fAccessModes[i]= ACCESS_MODE_CONDITIONAL_TABLE[getIndex(fAccessModes[i])][index_unused];
|
||||
}
|
||||
} else {
|
||||
for (int i= 0; i < fAccessModes.length; i++) {
|
||||
|
@ -398,14 +395,13 @@ public abstract class FlowInfo {
|
|||
return;
|
||||
}
|
||||
|
||||
int unused_index= getIndex(UNUSED);
|
||||
int index_unused= getIndex(UNUSED);
|
||||
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) {
|
||||
// Fast log function
|
||||
switch (accessMode) {
|
||||
case UNUSED:
|
||||
return 0;
|
||||
|
@ -414,7 +410,6 @@ public abstract class FlowInfo {
|
|||
case READ_POTENTIAL:
|
||||
return 2;
|
||||
case WRITE:
|
||||
case READ | WRITE:
|
||||
return 3;
|
||||
case WRITE_POTENTIAL:
|
||||
return 4;
|
||||
|
|
|
@ -248,7 +248,7 @@ public class InputFlowAnalyzer extends FlowAnalyzer {
|
|||
|
||||
@Override
|
||||
protected boolean traverseNode(IASTNode node) {
|
||||
return !isBefore(node, loopRegion.firstLabelStatement) &&
|
||||
return !selection.covers(node) && !isBefore(node, loopRegion.firstLabelStatement) &&
|
||||
!isBefore(loopRegion.lastGotoStatement, node);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue