mirror of
https://github.com/eclipse-cdt/cdt
synced 2025-07-23 17:05:26 +02:00
Extract Function: find and extract dublicated code
This commit is contained in:
parent
6a9abf764d
commit
e5fa863d5c
10 changed files with 1506 additions and 19 deletions
File diff suppressed because it is too large
Load diff
|
@ -261,3 +261,102 @@ int main(){
|
|||
flags="4" id="org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionRefactoring"
|
||||
name="exp" project="RegressionTestProject" selection="23,5" visibility="private"/>
|
||||
</session>
|
||||
|
||||
//!ExtractFunctionRefactoringTest duplicates with different Names History Test
|
||||
//#org.eclipse.cdt.ui.tests.refactoring.RefactoringHistoryTest
|
||||
//@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();
|
||||
void exp(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;
|
||||
exp(oo);
|
||||
}void A::exp(int & i)
|
||||
{
|
||||
++i;
|
||||
help();
|
||||
}
|
||||
|
||||
int A::foo()
|
||||
{
|
||||
int i = 2;
|
||||
exp(i);
|
||||
return i;
|
||||
}
|
||||
|
||||
int A::help()
|
||||
{
|
||||
return 42;
|
||||
}
|
||||
|
||||
//@refScript.xml
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<session version="1.0">
|
||||
<refactoring comment="Create method exp" description="Extract Method Refactoring"
|
||||
fileName="file:$$projectPath$$/A.cpp" flags="4" id="org.eclipse.cdt.internal.ui.refactoring.extractfunction.ExtractFunctionRefactoring"
|
||||
name="exp" project="RegressionTestProject" replaceDuplicates="true" selection="97,13" visibility="private"/>
|
||||
</session>
|
||||
|
|
|
@ -30,6 +30,7 @@ public class ExtractFunctionTestSuite extends TestSuite {
|
|||
suite.addTest(RefactoringTester.suite("ExtractMethodPreprocessorRefactoringTests", "resources/refactoring/ExtractMethodPreprocessor.rts"));
|
||||
suite.addTest(RefactoringTester.suite("Extract Function Templates Tests", "resources/refactoring/ExtractFunctionTemplates.rts"));
|
||||
suite.addTest(RefactoringTester.suite("Extract Method History Test", "resources/refactoring/ExtractMethodHistory.rts"));
|
||||
suite.addTest(RefactoringTester.suite("Extract Function Dublicates Test", "resources/refactoring/ExtractMethodDuplicates.rts"));
|
||||
return suite;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -40,15 +40,13 @@ public class ExtractFunctionComposite extends Composite {
|
|||
Group returnGroup = createReturnGroup(nameVisiComp);
|
||||
createReturnValueChooser(returnGroup, info, ip);
|
||||
|
||||
// Disabled for now
|
||||
//createReplaceCheckBox(nameVisiComp);
|
||||
createReplaceCheckBox(nameVisiComp);
|
||||
|
||||
if (info.getMethodContext().getType() == MethodContext.ContextType.METHOD) {
|
||||
visibilityPanelSetVisible(true);
|
||||
}else {
|
||||
visibilityPanelSetVisible(false);
|
||||
}
|
||||
|
||||
layout();
|
||||
}
|
||||
|
||||
|
@ -106,13 +104,13 @@ public class ExtractFunctionComposite extends Composite {
|
|||
}
|
||||
|
||||
|
||||
// private void createReplaceCheckBox(Composite parent) {
|
||||
// replaceSimilar = new Button(parent, SWT.CHECK | SWT.LEFT);
|
||||
// GridData buttonLayoutData = new GridData(SWT.None);
|
||||
// buttonLayoutData.verticalIndent = 5;
|
||||
// replaceSimilar.setLayoutData(buttonLayoutData);
|
||||
// replaceSimilar.setText(Messages.ExtractFunctionComposite_ReplaceDuplicates);
|
||||
// }
|
||||
private void createReplaceCheckBox(Composite parent) {
|
||||
replaceSimilar = new Button(parent, SWT.CHECK | SWT.LEFT);
|
||||
GridData buttonLayoutData = new GridData(SWT.None);
|
||||
buttonLayoutData.verticalIndent = 5;
|
||||
replaceSimilar.setLayoutData(buttonLayoutData);
|
||||
replaceSimilar.setText(Messages.ExtractFunctionComposite_ReplaceDuplicates);
|
||||
}
|
||||
|
||||
|
||||
public ChooserComposite getReturnChooser() {
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2008 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Copyright (c) 2008, 2009 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
|
@ -17,6 +17,8 @@ import org.eclipse.swt.events.ModifyEvent;
|
|||
import org.eclipse.swt.events.ModifyListener;
|
||||
import org.eclipse.swt.events.MouseAdapter;
|
||||
import org.eclipse.swt.events.MouseEvent;
|
||||
import org.eclipse.swt.events.SelectionEvent;
|
||||
import org.eclipse.swt.events.SelectionListener;
|
||||
import org.eclipse.swt.widgets.Button;
|
||||
import org.eclipse.swt.widgets.Composite;
|
||||
import org.eclipse.swt.widgets.Control;
|
||||
|
@ -65,9 +67,7 @@ public class ExtractFunctionInputPage extends UserInputWizardPage {
|
|||
});
|
||||
}
|
||||
|
||||
/* Disable until it works again.
|
||||
*
|
||||
* comp.getReplaceSimilarButton().addSelectionListener(new SelectionListener(){
|
||||
comp.getReplaceSimilarButton().addSelectionListener(new SelectionListener(){
|
||||
|
||||
public void widgetDefaultSelected(SelectionEvent e) {
|
||||
info.setReplaceDuplicates(comp.getReplaceSimilarButton().isEnabled());
|
||||
|
@ -77,7 +77,7 @@ public class ExtractFunctionInputPage extends UserInputWizardPage {
|
|||
widgetDefaultSelected(e);
|
||||
}
|
||||
|
||||
});*/
|
||||
});
|
||||
|
||||
setControl(comp);
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@ package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
|||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
|
@ -36,6 +37,7 @@ import org.eclipse.text.edits.TextEditGroup;
|
|||
|
||||
import org.eclipse.cdt.core.dom.ast.DOMException;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTComment;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTCompoundStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTDeclaration;
|
||||
|
@ -49,6 +51,7 @@ import org.eclipse.cdt.core.dom.ast.IASTFunctionDefinition;
|
|||
import org.eclipse.cdt.core.dom.ast.IASTIdExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTInitializerExpression;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNamedTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
|
||||
|
@ -63,11 +66,15 @@ import org.eclipse.cdt.core.dom.ast.INodeFactory;
|
|||
import org.eclipse.cdt.core.dom.ast.IParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTCompositeTypeSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTConversionName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTFunctionDeclarator;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTOperatorName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTSimpleDeclSpecifier;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateId;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateParameter;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.ICPPMethod;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
|
@ -105,6 +112,7 @@ import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
|||
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
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.NodeHelper;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.utils.SelectionHelper;
|
||||
|
||||
|
@ -129,7 +137,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
HashMap<String, Integer> nameTrail;
|
||||
|
||||
private ExtractedFunctionConstructionHelper extractedFunctionConstructionHelper;
|
||||
private INodeFactory factory = CPPNodeFactory.getDefault();
|
||||
private final INodeFactory factory = CPPNodeFactory.getDefault();
|
||||
|
||||
public ExtractFunctionRefactoring(IFile file, ISelection selection,
|
||||
ExtractFunctionInformation info, ICProject project) {
|
||||
|
@ -340,6 +348,11 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
methodCall = declarationStatement;
|
||||
}
|
||||
insertCallintoTree(methodCall, container.getNodesToWrite(), rewriter, editGroup);
|
||||
|
||||
if (info.isReplaceDuplicates()) {
|
||||
replaceSimilar(collector, astMethodName, implementationFile, context.getType());
|
||||
}
|
||||
|
||||
for (IASTNode node : container.getNodesToWrite()) {
|
||||
if (node != firstNodeToWrite) {
|
||||
rewriter.remove(node, editGroup);
|
||||
|
@ -404,6 +417,158 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
|
||||
}
|
||||
|
||||
private void replaceSimilar(ModificationCollector collector, final IASTName astMethodName,
|
||||
final IFile implementationFile,
|
||||
final ContextType contextType) {
|
||||
// Find similar code
|
||||
final List<IASTNode> nodesToRewriteWithoutComments = new LinkedList<IASTNode>();
|
||||
|
||||
for (IASTNode node : container.getNodesToWrite()) {
|
||||
if (!(node instanceof IASTComment)) {
|
||||
nodesToRewriteWithoutComments.add(node);
|
||||
}
|
||||
}
|
||||
|
||||
final Vector<IASTNode> initTrail = getTrail(nodesToRewriteWithoutComments);
|
||||
final String title;
|
||||
if (contextType == MethodContext.ContextType.METHOD) {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateMethodCall;
|
||||
} else {
|
||||
title = Messages.ExtractFunctionRefactoring_CreateFunctionCall;
|
||||
}
|
||||
|
||||
if (!hasNameResolvingForSimilarError) {
|
||||
unit.accept(new SimilarFinderVisitor(this, collector, initTrail, implementationFile,
|
||||
astMethodName, nodesToRewriteWithoutComments, title));
|
||||
}
|
||||
}
|
||||
|
||||
protected Vector<IASTNode> getTrail(List<IASTNode> stmts) {
|
||||
final Vector<IASTNode> trail = new Vector<IASTNode>();
|
||||
|
||||
nameTrail = new HashMap<String, Integer>();
|
||||
final Container<Integer> trailCounter = new Container<Integer>(NULL_INTEGER);
|
||||
|
||||
for (IASTNode node : stmts) {
|
||||
node.accept(new CPPASTAllVisitor() {
|
||||
@Override
|
||||
public int visitAll(IASTNode node) {
|
||||
|
||||
if (node instanceof IASTComment) {
|
||||
// Visit Comment, but don't add them to the trail
|
||||
return super.visitAll(node);
|
||||
} else if (node instanceof IASTNamedTypeSpecifier) {
|
||||
// Skip if somewhere is a named Type Specifier
|
||||
trail.add(node);
|
||||
return PROCESS_SKIP;
|
||||
} else if (node instanceof IASTName) {
|
||||
if (node instanceof ICPPASTConversionName && node instanceof ICPPASTOperatorName
|
||||
&& node instanceof ICPPASTTemplateId) {
|
||||
trail.add(node);
|
||||
return super.visitAll(node);
|
||||
} else {
|
||||
// Save Name Sequenz Number
|
||||
IASTName name = (IASTName) node;
|
||||
TrailName trailName = new TrailName();
|
||||
int actCount = trailCounter.getObject().intValue();
|
||||
if (nameTrail.containsKey(name.getRawSignature())) {
|
||||
Integer value = nameTrail.get(name.getRawSignature());
|
||||
actCount = value.intValue();
|
||||
} else {
|
||||
trailCounter.setObject(Integer.valueOf(++actCount));
|
||||
nameTrail.put(name.getRawSignature(), trailCounter.getObject());
|
||||
}
|
||||
trailName.setNameNumber(actCount);
|
||||
trailName.setRealName(name);
|
||||
|
||||
if (info.getReturnVariable() != null
|
||||
&& info.getReturnVariable().getName().getRawSignature().equals(
|
||||
name.getRawSignature())) {
|
||||
returnNumber.setObject(Integer.valueOf(actCount));
|
||||
}
|
||||
|
||||
// Save type informations for the name
|
||||
IBinding bind = name.resolveBinding();
|
||||
IASTName[] declNames = name.getTranslationUnit().getDeclarationsInAST(bind);
|
||||
if (declNames.length > 0) {
|
||||
IASTNode tmpNode = ASTHelper.getDeclarationForNode(declNames[0]);
|
||||
|
||||
IBinding declbind = declNames[0].resolveBinding();
|
||||
if (declbind instanceof ICPPBinding) {
|
||||
ICPPBinding cppBind = (ICPPBinding) declbind;
|
||||
try {
|
||||
trailName.setGloballyQualified(cppBind.isGloballyQualified());
|
||||
} catch (DOMException e) {
|
||||
ILog logger = CUIPlugin.getDefault().getLog();
|
||||
IStatus status = new Status(IStatus.WARNING, CUIPlugin.PLUGIN_ID,
|
||||
IStatus.OK, e.getMessage(), e);
|
||||
|
||||
logger.log(status);
|
||||
}
|
||||
}
|
||||
|
||||
if (tmpNode != null) {
|
||||
trailName.setDeclaration(tmpNode);
|
||||
} else {
|
||||
hasNameResolvingForSimilarError = true;
|
||||
}
|
||||
}
|
||||
|
||||
trail.add(trailName);
|
||||
return PROCESS_SKIP;
|
||||
}
|
||||
} else {
|
||||
trail.add(node);
|
||||
return super.visitAll(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
return trail;
|
||||
}
|
||||
|
||||
protected boolean isStatementInTrail(IASTStatement stmt, final Vector<IASTNode> trail) {
|
||||
final Container<Boolean> same = new Container<Boolean>(Boolean.TRUE);
|
||||
final TrailNodeEqualityChecker equalityChecker = new TrailNodeEqualityChecker(names, namesCounter);
|
||||
|
||||
stmt.accept(new CPPASTAllVisitor() {
|
||||
@Override
|
||||
public int visitAll(IASTNode node) {
|
||||
|
||||
int pos = trailPos.getObject().intValue();
|
||||
|
||||
if (trail.size() <= 0 || pos >= trail.size()) {
|
||||
same.setObject(Boolean.FALSE);
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
|
||||
if (node instanceof IASTComment) {
|
||||
// Visit Comment, but they are not in the trail
|
||||
return super.visitAll(node);
|
||||
}
|
||||
|
||||
IASTNode trailNode = trail.get(pos);
|
||||
trailPos.setObject(Integer.valueOf(pos + 1));
|
||||
|
||||
if (equalityChecker.isEquals(trailNode, node)) {
|
||||
if (node instanceof ICPPASTQualifiedName || node instanceof IASTNamedTypeSpecifier) {
|
||||
return PROCESS_SKIP;
|
||||
} else {
|
||||
return super.visitAll(node);
|
||||
}
|
||||
|
||||
} else {
|
||||
same.setObject(new Boolean(false));
|
||||
return PROCESS_ABORT;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
return same.getObject().booleanValue();
|
||||
}
|
||||
|
||||
private boolean isMethodAllreadyDefined(
|
||||
IASTSimpleDeclaration methodDeclaration,
|
||||
ICPPASTCompositeTypeSpecifier classDeclaration) {
|
||||
|
@ -777,6 +942,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
|
|||
arguments.put(CRefactoringDescription.SELECTION, region.getOffset() + "," + region.getLength()); //$NON-NLS-1$
|
||||
arguments.put(ExtractFunctionRefactoringDescription.NAME, info.getMethodName());
|
||||
arguments.put(ExtractFunctionRefactoringDescription.VISIBILITY, info.getVisibility().toString());
|
||||
arguments.put(ExtractFunctionRefactoringDescription.REPLACE_DUBLICATES, Boolean.toString(info.isReplaceDuplicates()));
|
||||
return arguments;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,6 +32,7 @@ import org.eclipse.cdt.internal.ui.refactoring.utils.VisibilityEnum;
|
|||
public class ExtractFunctionRefactoringDescription extends CRefactoringDescription {
|
||||
protected static final String NAME = "name"; //$NON-NLS-1$
|
||||
protected static final String VISIBILITY = "visibility"; //$NON-NLS-1$
|
||||
protected static final String REPLACE_DUBLICATES = "replaceDuplicates"; //$NON-NLS-1$
|
||||
|
||||
public ExtractFunctionRefactoringDescription(String project, String description,
|
||||
String comment, Map<String, String> arguments) {
|
||||
|
@ -46,6 +47,7 @@ public class ExtractFunctionRefactoringDescription extends CRefactoringDescripti
|
|||
|
||||
info.setMethodName(arguments.get(NAME));
|
||||
info.setVisibility(VisibilityEnum.getEnumForStringRepresentation(arguments.get(VISIBILITY)));
|
||||
info.setReplaceDuplicates(Boolean.parseBoolean(arguments.get(REPLACE_DUBLICATES)));
|
||||
|
||||
proj = getCProject();
|
||||
file = getFile();
|
||||
|
|
|
@ -34,7 +34,7 @@ public final class Messages extends NLS {
|
|||
public static String ExtractFunctionComposite_ReturnValue;
|
||||
public static String ExtractFunctionRefactoring_CreateMethodDef;
|
||||
public static String ExtractFunctionRefactoring_CreateFunctionDef;
|
||||
// public static String ExtractFunctionComposite_ReplaceDuplicates;
|
||||
public static String ExtractFunctionComposite_ReplaceDuplicates;
|
||||
public static String ExtractFunctionRefactoring_CreateMethodCall;
|
||||
public static String ExtractFunctionRefactoring_CreateFunctionCall;
|
||||
public static String ChooserComposite_Return;
|
||||
|
|
|
@ -0,0 +1,146 @@
|
|||
/*******************************************************************************
|
||||
* Copyright (c) 2009 Institute for Software, HSR Hochschule fuer Technik
|
||||
* Rapperswil, University of applied sciences and others
|
||||
* All rights reserved. This program and the accompanying materials
|
||||
* are made available under the terms of the Eclipse Public License v1.0
|
||||
* which accompanies this distribution, and is available at
|
||||
* http://www.eclipse.org/legal/epl-v10.html
|
||||
*
|
||||
* Contributors:
|
||||
* Institute for Software - initial API and implementation
|
||||
*******************************************************************************/
|
||||
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Vector;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import org.eclipse.core.resources.IFile;
|
||||
import org.eclipse.text.edits.TextEditGroup;
|
||||
|
||||
import org.eclipse.cdt.core.dom.ast.IASTName;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTNode;
|
||||
import org.eclipse.cdt.core.dom.ast.IASTStatement;
|
||||
import org.eclipse.cdt.core.dom.ast.cpp.CPPASTVisitor;
|
||||
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
|
||||
|
||||
import org.eclipse.cdt.internal.ui.refactoring.ModificationCollector;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer;
|
||||
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
|
||||
|
||||
final class SimilarFinderVisitor extends CPPASTVisitor {
|
||||
|
||||
private final ExtractFunctionRefactoring refactoring;
|
||||
|
||||
private final Vector<IASTNode> trail;
|
||||
private final IASTName name;
|
||||
private final List<IASTNode> stmts;
|
||||
private int i = 0;
|
||||
private NodeContainer similarContainer;
|
||||
private final List<IASTStatement> stmtToReplace = new ArrayList<IASTStatement>();
|
||||
|
||||
private final ModificationCollector collector;
|
||||
|
||||
SimilarFinderVisitor(ExtractFunctionRefactoring refactoring,
|
||||
ModificationCollector collector, Vector<IASTNode> trail, IFile file, IASTName name,
|
||||
List<IASTNode> stmts, String title) {
|
||||
this.refactoring = refactoring;
|
||||
this.trail = trail;
|
||||
this.name = name;
|
||||
this.stmts = stmts;
|
||||
this.collector = collector;
|
||||
this.similarContainer = new NodeContainer();
|
||||
}
|
||||
|
||||
{
|
||||
shouldVisitStatements = true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int visit(IASTStatement stmt) {
|
||||
|
||||
boolean isAllreadyInMainRefactoring = isInSelection(stmt);
|
||||
|
||||
if( (!isAllreadyInMainRefactoring)
|
||||
&& this.refactoring.isStatementInTrail(stmt, trail)){
|
||||
stmtToReplace.add(stmt);
|
||||
similarContainer.add(stmt);
|
||||
++i;
|
||||
|
||||
if(i==stmts.size()){
|
||||
//found similar code
|
||||
|
||||
boolean similarOnReturnWays = true;
|
||||
for (NameInformation nameInfo : similarContainer.getAllAfterUsedNames()) {
|
||||
if(this.refactoring.names.containsKey(nameInfo.getDeclaration().getRawSignature())){
|
||||
Integer nameOrderNumber = this.refactoring.names.get(nameInfo.getDeclaration().getRawSignature());
|
||||
if(this.refactoring.nameTrail.containsValue(nameOrderNumber)){
|
||||
String orgName = null;
|
||||
boolean found = false;
|
||||
for (Entry<String, Integer> entry : this.refactoring.nameTrail.entrySet()) {
|
||||
if(entry.getValue().equals(nameOrderNumber)){
|
||||
orgName = entry.getKey();
|
||||
}
|
||||
}
|
||||
if(orgName != null){
|
||||
for (NameInformation orgNameInfo : this.refactoring.container.getAllAfterUsedNamesChoosenByUser()) {
|
||||
if( orgName.equals(orgNameInfo.getDeclaration().getRawSignature()) ){
|
||||
found = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(!found){
|
||||
similarOnReturnWays = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(similarOnReturnWays){
|
||||
System.out.println(6);
|
||||
IASTNode call = refactoring.getMethodCall(name,
|
||||
this.refactoring.nameTrail, this.refactoring.names,
|
||||
this.refactoring.container, similarContainer);
|
||||
ASTRewrite rewrite = collector.rewriterForTranslationUnit(stmtToReplace.get(0)
|
||||
.getTranslationUnit());
|
||||
TextEditGroup editGroup = new TextEditGroup("Replace Dublicated Code");
|
||||
rewrite.replace(stmtToReplace.get(0), call, editGroup);
|
||||
if (stmtToReplace.size() > 1) {
|
||||
for (int i = 1; i < stmtToReplace.size(); ++i) {
|
||||
rewrite.remove(stmtToReplace.get(i), editGroup);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clear();
|
||||
}
|
||||
|
||||
return PROCESS_SKIP;
|
||||
} else {
|
||||
clear();
|
||||
return super.visit(stmt);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private boolean isInSelection(IASTStatement stmt) {
|
||||
List<IASTNode>nodes = this.refactoring.container.getNodesToWrite();
|
||||
for (IASTNode node : nodes) {
|
||||
if(node.equals(stmt)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private void clear() {
|
||||
i = 0;
|
||||
this.refactoring.names.clear();
|
||||
similarContainer = new NodeContainer();
|
||||
this.refactoring.namesCounter.setObject(ExtractFunctionRefactoring.NULL_INTEGER);
|
||||
this.refactoring.trailPos.setObject(ExtractFunctionRefactoring.NULL_INTEGER);
|
||||
stmtToReplace.clear();
|
||||
}
|
||||
}
|
|
@ -22,7 +22,7 @@ ExtractFunctionInputPage_1=is used after the extracted block - it needs to be pa
|
|||
ExtractFunctionComposite_ReturnValue=Return value:
|
||||
ExtractFunctionRefactoring_CreateMethodDef=Create Method Definition
|
||||
ExtractFunctionRefactoring_CreateFunctionDef=Create Function Definition
|
||||
#ExtractFunctionComposite_ReplaceDuplicates=Replace all occurrences of statements with method.
|
||||
ExtractFunctionComposite_ReplaceDuplicates=Replace all occurrences of statements with method.
|
||||
ExtractFunctionRefactoring_CreateMethodCall=Create Method Call
|
||||
ExtractFunctionRefactoring_CreateFunctionCall=Create Function Call
|
||||
ChooserComposite_Return=Return
|
||||
|
|
Loading…
Add table
Reference in a new issue