1
0
Fork 0
mirror of https://github.com/eclipse-cdt/cdt synced 2025-04-29 19:45:01 +02:00

FIXED - bug 291190: Refactoring tests use the index without read-locks

https://bugs.eclipse.org/bugs/show_bug.cgi?id=291190
This commit is contained in:
Emanuel Graf 2009-10-20 10:19:04 +00:00
parent 8c5477d2d0
commit 95e3b558d5
9 changed files with 328 additions and 318 deletions

View file

@ -301,6 +301,12 @@ public abstract class CRefactoring extends Refactoring {
return fIndex;
}
public IASTTranslationUnit getUnit() {
return unit;
}
protected ArrayList<IASTName> findAllMarkedNames() {
final ArrayList<IASTName> namesVector = new ArrayList<IASTName>();

View file

@ -194,6 +194,10 @@ public class MethodContext {
return null;
}
public boolean isInline() {
return qname == null;
}
private static ICPPClassType getClassBinding(ICPPASTQualifiedName qname){
IASTName classname = qname.getNames()[qname.getNames().length - 2];
ICPPClassType bind = (ICPPClassType)classname.resolveBinding();

View file

@ -15,7 +15,6 @@ import java.util.List;
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.IASTCompoundStatement;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
@ -29,10 +28,12 @@ import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IBasicType;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.ITypedef;
import org.eclipse.cdt.core.dom.ast.IBasicType.Kind;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTNewExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTQualifiedName;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPClassType;
import org.eclipse.cdt.core.dom.rewrite.ASTRewrite;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTBinaryExpression;
@ -47,10 +48,8 @@ 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.CPPASTSimpleDeclaration;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPBasicType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPClassType;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPFunction;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPNamespace;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPTypedef;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.ui.refactoring.NodeContainer.NameInformation;
@ -120,8 +119,11 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
}
return createSimpleDeclSpecifier(Kind.eVoid);
}
if(declSpecifier.isFrozen()) {
return declSpecifier.copy();
}else {
return declSpecifier;
}
}
private IASTDeclSpecifier handleLiteralExpression(IASTLiteralExpression extractedNode) {
@ -207,65 +209,39 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
CPPBasicType basicType = (CPPBasicType) expressionType;
return createSimpleDeclSpecifier(basicType.getKind());
} else if (expressionType instanceof CPPTypedef) {
} else if (expressionType instanceof ITypedef) {
return getDeclSpecForType(((CPPTypedef)expressionType));
return getDeclSpecForType(((ITypedef)expressionType));
} else if (expressionType instanceof CPPClassType) {
} else if (expressionType instanceof ICPPClassType) {
return getDeclSpecForType((CPPClassType)expressionType);
return getDeclSpecForType((ICPPClassType)expressionType);
}
return null;
}
private CPPASTNamedTypeSpecifier getDeclSpecForType(CPPClassType classType) {
private IASTDeclSpecifier getDeclSpecForType(ICPPClassType expressionType) {
IASTName name = null;
char[][] qualifiedNameCharArray = CPPVisitor.getQualifiedNameCharArray(expressionType);
name = new CPPASTQualifiedName();
for (char[] cs : qualifiedNameCharArray) {
((ICPPASTQualifiedName) name).addName(new CPPASTName(cs));
}
return new CPPASTNamedTypeSpecifier(name);
}
private CPPASTNamedTypeSpecifier getDeclSpecForType(ITypedef classType) {
IASTName name = null;
try {
IBinding bind = classType.getOwner();
if (bind instanceof CPPNamespace) {
ICPPASTQualifiedName qname = getQname(classType, bind);
qname.addName((IASTName) classType.getDefinition().copy());
name = qname;
}else {
name = (IASTName) classType.getDefinition();
}
} catch (DOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
name= new CPPASTName(classType.getNameCharArray());
char[][] qualifiedNameCharArray = CPPVisitor.getQualifiedNameCharArray(classType);
name = new CPPASTQualifiedName();
for (char[] cs : qualifiedNameCharArray) {
((ICPPASTQualifiedName) name).addName(new CPPASTName(cs));
}
return new CPPASTNamedTypeSpecifier(name.copy());
}
private ICPPASTQualifiedName getQname(IBinding classType, IBinding bind) {
CPPNamespace namespace = (CPPNamespace) bind;
char[][] names = namespace.getFullyQualifiedNameCharArray();
CPPASTQualifiedName qname = new CPPASTQualifiedName();
for (char[] string : names) {
qname.addName(new CPPASTName(string));
}
return qname;
}
private IASTDeclSpecifier getDeclSpecForType(CPPTypedef typedef) {
IASTName name = null;
try {
IBinding bind = typedef.getOwner();
if (bind instanceof CPPNamespace) {
ICPPASTQualifiedName qname = getQname(typedef, bind);
qname.addName((IASTName) typedef.getDefinition().copy());
name = qname;
}else {
name = (IASTName) typedef.getDefinition();
}
} catch (DOMException e) {
// TODO Auto-generated catch block
e.printStackTrace();
name= new CPPASTName(typedef.getNameCharArray());
}
return new CPPASTNamedTypeSpecifier(name.copy());
return new CPPASTNamedTypeSpecifier(name);
}
private static IASTDeclSpecifier createSimpleDeclSpecifier(IBasicType.Kind type) {
@ -307,8 +283,8 @@ public class ExtractExpression extends ExtractedFunctionConstructionHelper {
return declaration.getDeclSpecifier();
}
}
}else if(binding instanceof CPPTypedef) {
CPPTypedef typedef = (CPPTypedef) binding;
}else if(binding instanceof ITypedef) {
ITypedef typedef = (ITypedef) binding;
return new CPPASTNamedTypeSpecifier(new CPPASTName(typedef.getNameCharArray()));
}

View file

@ -57,7 +57,6 @@ import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IASTParameterDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTPointerOperator;
import org.eclipse.cdt.core.dom.ast.IASTReturnStatement;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTSimpleDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTStandardFunctionDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTStatement;
@ -72,11 +71,9 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTDeclSpecifier;
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;
@ -98,7 +95,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTInitializerExpression;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
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.CPPASTSimpleDeclSpecifier;
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.CPPNodeFactory;
@ -157,7 +153,11 @@ public class ExtractFunctionRefactoring extends CRefactoring {
public RefactoringStatus checkInitialConditions(IProgressMonitor pm)
throws CoreException, OperationCanceledException {
SubMonitor sm = SubMonitor.convert(pm, 10);
RefactoringStatus status = super.checkInitialConditions(sm.newChild(6));
try {
lockIndex();
try {
super.checkInitialConditions(sm.newChild(6));
container = findExtractableNodes();
sm.worked(1);
@ -165,7 +165,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
if (isProgressMonitorCanceld(sm, initStatus))
return initStatus;
checkForNonExtractableStatements(container, status);
checkForNonExtractableStatements(container, initStatus);
sm.worked(1);
if (isProgressMonitorCanceld(sm, initStatus))
@ -182,13 +182,13 @@ public class ExtractFunctionRefactoring extends CRefactoring {
info.setAllUsedNames(container.getUsedNamesUnique());
if (container.size() < 1) {
status.addFatalError(Messages.ExtractFunctionRefactoring_NoStmtSelected);
initStatus.addFatalError(Messages.ExtractFunctionRefactoring_NoStmtSelected);
sm.done();
return status;
return initStatus;
}
if (container.getAllDeclaredInScope().size() > 1) {
status.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
initStatus.addFatalError(Messages.ExtractFunctionRefactoring_TooManySelected);
} else if (container.getAllDeclaredInScope().size() == 1) {
info.setInScopeDeclaredVariable(container.getAllDeclaredInScope().get(0));
}
@ -220,7 +220,14 @@ public class ExtractFunctionRefactoring extends CRefactoring {
}
sm.done();
return status;
}
finally {
unlockIndex();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return initStatus;
}
private void markWriteAccess() throws CoreException {
@ -280,20 +287,25 @@ public class ExtractFunctionRefactoring extends CRefactoring {
@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm)
throws CoreException, OperationCanceledException {
RefactoringStatus status = super.checkFinalConditions(pm);
RefactoringStatus finalConditions = null;
try {
lockIndex();
try {
finalConditions = super.checkFinalConditions(pm);
final IASTName astMethodName = new CPPASTName(info.getMethodName()
.toCharArray());
MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0), getIndex());
if (context.getType() == ContextType.METHOD) {
if (context.getType() == ContextType.METHOD && !context.isInline()) {
ICPPASTCompositeTypeSpecifier classDeclaration = (ICPPASTCompositeTypeSpecifier) context
.getMethodDeclaration().getParent();
IASTSimpleDeclaration methodDeclaration = getDeclaration(astMethodName);
if (isMethodAllreadyDefined(methodDeclaration, classDeclaration)) {
status.addError(Messages.ExtractFunctionRefactoring_NameInUse);
return status;
if (isMethodAllreadyDefined(methodDeclaration, classDeclaration, getIndex())) {
finalConditions.addError(Messages.ExtractFunctionRefactoring_NameInUse);
return finalConditions;
}
}
for (NameInformation name : info.getAllUsedNames()) {
@ -302,21 +314,30 @@ public class ExtractFunctionRefactoring extends CRefactoring {
}
}
return status;
}
finally {
unlockIndex();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
return finalConditions;
}
@Override
protected void collectModifications(IProgressMonitor pm,
ModificationCollector collector) throws CoreException,
OperationCanceledException {
try {
lockIndex();
try {
final IASTName astMethodName = new CPPASTName(info.getMethodName()
.toCharArray());
MethodContext context = NodeHelper.findMethodContext(container.getNodesToWrite().get(0), getIndex());
// Create Declaration in Class
if (context.getType() == ContextType.METHOD) {
if (context.getType() == ContextType.METHOD && !context.isInline()) {
createMethodDeclaration(astMethodName, context, collector);
}
// Create Method Definition
@ -329,6 +350,13 @@ public class ExtractFunctionRefactoring extends CRefactoring {
implementationFile, collector);
createMethodCalls(astMethodName, implementationFile, context, collector);
}
finally {
unlockIndex();
}
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
@ -476,7 +504,7 @@ public class ExtractFunctionRefactoring extends CRefactoring {
} else {
// Save Name Sequenz Number
IASTName name = (IASTName) node;
TrailName trailName = new TrailName();
TrailName trailName = new TrailName(name);
int actCount = trailCounter.getObject().intValue();
if (nameTrail.containsKey(name.getRawSignature())) {
Integer value = nameTrail.get(name.getRawSignature());
@ -486,7 +514,6 @@ public class ExtractFunctionRefactoring extends CRefactoring {
nameTrail.put(name.getRawSignature(), trailCounter.getObject());
}
trailName.setNameNumber(actCount);
trailName.setRealName(name);
if (info.getReturnVariable() != null
&& info.getReturnVariable().getName().getRawSignature().equals(
@ -494,33 +521,6 @@ public class ExtractFunctionRefactoring extends CRefactoring {
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;
}
@ -536,9 +536,9 @@ public class ExtractFunctionRefactoring extends CRefactoring {
return trail;
}
protected boolean isStatementInTrail(IASTStatement stmt, final Vector<IASTNode> trail) {
protected boolean isStatementInTrail(IASTStatement stmt, final Vector<IASTNode> trail, IIndex index) {
final Container<Boolean> same = new Container<Boolean>(Boolean.TRUE);
final TrailNodeEqualityChecker equalityChecker = new TrailNodeEqualityChecker(names, namesCounter);
final TrailNodeEqualityChecker equalityChecker = new TrailNodeEqualityChecker(names, namesCounter, index);
stmt.accept(new CPPASTAllVisitor() {
@Override
@ -578,9 +578,9 @@ public class ExtractFunctionRefactoring extends CRefactoring {
private boolean isMethodAllreadyDefined(
IASTSimpleDeclaration methodDeclaration,
ICPPASTCompositeTypeSpecifier classDeclaration) {
ICPPASTCompositeTypeSpecifier classDeclaration, IIndex index) {
TrailNodeEqualityChecker equalityChecker = new TrailNodeEqualityChecker(
names, namesCounter);
names, namesCounter, index);
IBinding bind = classDeclaration.getName().resolveBinding();
IASTStandardFunctionDeclarator declarator = (IASTStandardFunctionDeclarator) methodDeclaration
@ -647,18 +647,19 @@ public class ExtractFunctionRefactoring extends CRefactoring {
ICPPASTQualifiedName qname = new CPPASTQualifiedName();
if (context.getType() == ContextType.METHOD) {
if(context.getMethodQName() != null) {
for (int i = 0; i < (context.getMethodQName().getNames().length - 1); i++) {
qname.addName(new CPPASTName(context.getMethodQName().getNames()[i].toCharArray()));
}
}
}
qname.addName(astMethodName);
IASTFunctionDefinition func = new CPPASTFunctionDefinition();
func.setParent(unit);
ICPPASTSimpleDeclSpecifier dummyDeclSpecifier = new CPPASTSimpleDeclSpecifier();
func.setDeclSpecifier(dummyDeclSpecifier);
dummyDeclSpecifier.setType(IASTSimpleDeclSpecifier.t_void);
IASTDeclSpecifier returnType = getReturnType();
func.setDeclSpecifier(returnType);
IASTStandardFunctionDeclarator createdFunctionDeclarator = extractedFunctionConstructionHelper
.createFunctionDeclarator(qname, info.getDeclarator(), info
@ -688,8 +689,6 @@ public class ExtractFunctionRefactoring extends CRefactoring {
subRW = rewriter.insertBefore(insertpoint.getParent(), insertpoint, func, group);
}
subRW.replace(dummyDeclSpecifier, getReturnType(), group);
extractedFunctionConstructionHelper.constructMethodBody(compound,
container.getNodesToWrite(), subRW, group);

View file

@ -63,7 +63,7 @@ final class SimilarFinderVisitor extends CPPASTVisitor {
boolean isAllreadyInMainRefactoring = isInSelection(stmt);
if( (!isAllreadyInMainRefactoring)
&& this.refactoring.isStatementInTrail(stmt, trail)){
&& this.refactoring.isStatementInTrail(stmt, trail, this.refactoring.getIndex())){
stmtToReplace.add(stmt);
similarContainer.add(stmt);
++i;
@ -99,7 +99,6 @@ final class SimilarFinderVisitor extends CPPASTVisitor {
}
if(similarOnReturnWays){
System.out.println(6);
IASTNode call = refactoring.getMethodCall(name,
this.refactoring.nameTrail, this.refactoring.names,
this.refactoring.container, similarContainer);

View file

@ -11,24 +11,26 @@
*******************************************************************************/
package org.eclipse.cdt.internal.ui.refactoring.extractfunction;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTName;
import org.eclipse.cdt.core.dom.ast.IASTNode;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPBinding;
import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTName;
import org.eclipse.cdt.internal.core.dom.parser.ASTNode;
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
class TrailName extends CPPASTName {
class TrailName extends ASTNode{
private int nameNumber;
private IASTNode declaration = null;
private IASTName realName = null;
private boolean isGloballyQualified = false;
@Override
public String getRawSignature() {
return realName.getRawSignature();
public TrailName(IASTName realName) {
super();
this.realName = realName;
}
public int getNameNumber() {
@ -39,14 +41,6 @@ class TrailName extends CPPASTName {
this.nameNumber = nameNumber;
}
public IASTNode getDeclaration() {
return declaration;
}
public void setDeclaration(IASTNode declaration) {
this.declaration = declaration;
}
public IASTDeclSpecifier getDeclSpecifier() {
return ASTHelper.getDeclarationSpecifier(declaration);
}
@ -55,20 +49,19 @@ class TrailName extends CPPASTName {
return realName;
}
public void setRealName(IASTName realName) {
this.realName = realName;
}
public boolean isGloballyQualified() {
return isGloballyQualified;
IBinding bind = realName.resolveBinding();
try {
if (bind instanceof ICPPBinding) {
ICPPBinding cppBind = (ICPPBinding) bind;
return cppBind.isGloballyQualified();
}
} catch (DOMException e) {
}
return false;
}
public void setGloballyQualified(boolean isGloballyQualified) {
this.isGloballyQualified = isGloballyQualified;
}
@Override
public char[] toCharArray() {
return realName.toCharArray();
public IASTNode copy() {
throw new UnsupportedOperationException();
}
}

View file

@ -18,7 +18,9 @@ import java.util.List;
import java.util.Map;
import org.eclipse.core.runtime.Assert;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.cdt.core.dom.ast.DOMException;
import org.eclipse.cdt.core.dom.ast.IASTASMDeclaration;
import org.eclipse.cdt.core.dom.ast.IASTBinaryExpression;
import org.eclipse.cdt.core.dom.ast.IASTCompositeTypeSpecifier;
@ -28,6 +30,7 @@ import org.eclipse.cdt.core.dom.ast.IASTDeclarator;
import org.eclipse.cdt.core.dom.ast.IASTElaboratedTypeSpecifier;
import org.eclipse.cdt.core.dom.ast.IASTExpression;
import org.eclipse.cdt.core.dom.ast.IASTFieldReference;
import org.eclipse.cdt.core.dom.ast.IASTFileLocation;
import org.eclipse.cdt.core.dom.ast.IASTInitializer;
import org.eclipse.cdt.core.dom.ast.IASTLiteralExpression;
import org.eclipse.cdt.core.dom.ast.IASTName;
@ -41,6 +44,7 @@ import org.eclipse.cdt.core.dom.ast.IASTStatement;
import org.eclipse.cdt.core.dom.ast.IASTTypeIdExpression;
import org.eclipse.cdt.core.dom.ast.IASTUnaryExpression;
import org.eclipse.cdt.core.dom.ast.IBinding;
import org.eclipse.cdt.core.dom.ast.IType;
import org.eclipse.cdt.core.dom.ast.c.ICASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.c.ICASTPointer;
import org.eclipse.cdt.core.dom.ast.c.ICASTSimpleDeclSpecifier;
@ -59,24 +63,28 @@ import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTemplateDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTTypenameExpression;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTUsingDeclaration;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPASTVisibilityLabel;
import org.eclipse.cdt.core.dom.ast.cpp.ICPPVariable;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTDeclSpecifier;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTExplicitTemplateInstantiation;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTPointer;
import org.eclipse.cdt.core.dom.ast.gnu.cpp.IGPPASTSimpleDeclSpecifier;
import org.eclipse.cdt.core.index.IIndex;
import org.eclipse.cdt.core.index.IIndexName;
import org.eclipse.cdt.internal.ui.refactoring.Container;
import org.eclipse.cdt.internal.ui.refactoring.EqualityChecker;
import org.eclipse.cdt.internal.ui.refactoring.utils.ASTHelper;
public class TrailNodeEqualityChecker implements EqualityChecker<IASTNode> {
private final Map<String, Integer> names;
private final Container<Integer> namesCounter;
private IIndex index;
public TrailNodeEqualityChecker(Map<String, Integer> names, Container<Integer> namesCounter) {
public TrailNodeEqualityChecker(Map<String, Integer> names, Container<Integer> namesCounter, IIndex index) {
super();
this.names = names;
this.namesCounter = namesCounter;
this.index = index;
}
public boolean isEquals(IASTNode trailNode, IASTNode node) {
@ -165,13 +173,12 @@ public class TrailNodeEqualityChecker implements EqualityChecker<IASTNode> {
ICPPASTNamedTypeSpecifier decl = (ICPPASTNamedTypeSpecifier) node;
boolean isSame = isDeclSpecifierEquals(trailDecl, decl)
return isDeclSpecifierEquals(trailDecl, decl)
&& isSameNamedTypeSpecifierName(trailDecl, decl)
&& trailDecl.isTypename() == decl.isTypename()
&& trailDecl.isExplicit() == decl.isExplicit()
&& trailDecl.isFriend() == decl.isFriend()
&& trailDecl.isVirtual() == decl.isVirtual();
return isSame;
} else if (trailNode instanceof IASTNamedTypeSpecifier) {
IASTNamedTypeSpecifier trailDecl = (IASTNamedTypeSpecifier) trailNode;
IASTNamedTypeSpecifier decl = (IASTNamedTypeSpecifier) node;
@ -409,52 +416,68 @@ public class TrailNodeEqualityChecker implements EqualityChecker<IASTNode> {
return false;
}
IBinding bind = name.resolveBinding();
IASTName[] declNames = name.getTranslationUnit().getDeclarationsInAST(bind);
if(declNames.length > 0){
IASTNode tmpNode = ASTHelper.getDeclarationForNode(declNames[0]);
if(tmpNode != null){
if(trailName.isGloballyQualified()) {
//global Node
if(tmpNode.equals(trailName.getDeclaration())){
IBinding realBind = trailName.getRealName().resolveBinding();
IBinding nameBind = name.resolveBinding();
try {
index.acquireReadLock();
IIndexName[] realDecs = index.findDeclarations(realBind);
IIndexName[] nameDecs = index.findDeclarations(nameBind);
if(realDecs.length == nameDecs.length) {
for(int i = 0; i < realDecs.length; ++i) {
IASTFileLocation rfl = realDecs[i].getFileLocation();
IASTFileLocation nfl = nameDecs[i].getFileLocation();
if(rfl.getNodeOffset() == nfl.getNodeOffset() && rfl.getFileName().equals(nfl.getFileName())) {
continue;
}else {
return false;
}
}
return true;
}else {
return false;
}
} catch (InterruptedException e) {}
catch (CoreException e) {}
finally {
index.releaseReadLock();
}
}else {
//localNode
IASTDeclSpecifier decl = ASTHelper.getDeclarationSpecifier(tmpNode);
IASTDeclSpecifier trailDecl = trailName.getDeclSpecifier();
IASTDeclarator declarator = ASTHelper.getDeclaratorForNode(declNames[0]);
IASTDeclarator trailDeclarator = ASTHelper.getDeclaratorForNode(trailName.getDeclaration());
IASTPointerOperator[] pointerOperators1 = declarator.getPointerOperators();
IASTPointerOperator[] pointerOperators2 = trailDeclarator.getPointerOperators();
if(trailDecl != null && decl != null
&& decl.getStorageClass() == trailDecl.getStorageClass()
&& ASTHelper.samePointers(pointerOperators1, pointerOperators2, this)){
if (decl instanceof IASTSimpleDeclSpecifier
&& trailDecl instanceof IASTSimpleDeclSpecifier) {
IASTSimpleDeclSpecifier simpleDecl = (IASTSimpleDeclSpecifier) decl;
IASTSimpleDeclSpecifier simpleTrailDecl = (IASTSimpleDeclSpecifier) trailDecl;
if(simpleDecl.getType() == simpleTrailDecl.getType()){
IType oType = getType(trailName.getRealName().resolveBinding());
IType nType = getType(name.resolveBinding());
if(oType.isSameType(nType)) {
return true;
}
} else if (decl instanceof IASTNamedTypeSpecifier
&& trailDecl instanceof IASTNamedTypeSpecifier) {
IASTNamedTypeSpecifier namedDecl = (IASTNamedTypeSpecifier) decl;
IASTNamedTypeSpecifier trailNamedDecl = (IASTNamedTypeSpecifier) trailDecl;
if(namedDecl.getName().getRawSignature().equals(trailNamedDecl.getName().getRawSignature())){
return true;
}
}
}
}
}
}
return false;
}
private IType getType(IBinding binding) {
try {
if (binding instanceof ICPPVariable) {
ICPPVariable var = (ICPPVariable) binding;
return var.getType();
}
} catch (DOMException e) {
return new NullType();
}
return new NullType();
}
private class NullType implements IType{
@Override
public Object clone() {
try {
return super.clone();
} catch (CloneNotSupportedException e) {
return null;
}
}
public boolean isSameType(IType type) {
return false;
}
}
}

View file

@ -117,13 +117,20 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring {
@Override
public RefactoringStatus checkFinalConditions(IProgressMonitor pm) throws CoreException,
OperationCanceledException {
RefactoringStatus finalStatus = super.checkFinalConditions(pm);
RefactoringStatus finalStatus = null;
try {
lockIndex();
finalStatus = super.checkFinalConditions(pm);
if(!context.isImplementationInHeader()) {
definitionInsertLocation = findInsertLocation();
if(file.equals(definitionInsertLocation.getInsertFile())) {
finalStatus.addInfo(Messages.GenerateGettersAndSettersRefactoring_NoImplFile);
}
}
} catch (InterruptedException e) {}
finally {
unlockIndex();
}
return finalStatus;
}
@ -206,6 +213,8 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring {
@Override
protected void collectModifications(IProgressMonitor pm,ModificationCollector collector) throws CoreException, OperationCanceledException {
try {
lockIndex();
ArrayList<IASTNode> getterAndSetters = new ArrayList<IASTNode>();
ArrayList<IASTFunctionDefinition> definitions = new ArrayList<IASTFunctionDefinition>();
for(GetterSetterInsertEditProvider currentProvider : context.selectedFunctions){
@ -222,6 +231,10 @@ public class GenerateGettersAndSettersRefactoring extends CRefactoring {
ICPPASTCompositeTypeSpecifier classDefinition = (ICPPASTCompositeTypeSpecifier) context.existingFields.get(context.existingFields.size()-1).getParent();
AddDeclarationNodeToClassChange.createChange(classDefinition, VisibilityEnum.v_public, getterAndSetters, false, collector);
} catch (InterruptedException e) {}
finally {
unlockIndex();
}
}

View file

@ -37,7 +37,6 @@ import org.eclipse.cdt.internal.core.dom.parser.cpp.CPPASTTranslationUnit;
import org.eclipse.cdt.internal.core.dom.parser.cpp.semantics.CPPVisitor;
import org.eclipse.cdt.internal.ui.refactoring.MethodContext;
import org.eclipse.cdt.internal.ui.refactoring.MethodContext.ContextType;
/**
* General class for common Node operations.
@ -150,15 +149,15 @@ public class NodeHelper {
private static void getMethodContexWithIndex(IIndex index,
IASTTranslationUnit translationUnit, MethodContext context,
IASTName name) throws CoreException {
if(name instanceof ICPPASTQualifiedName){
ICPPASTQualifiedName qname =( ICPPASTQualifiedName )name;
context.setMethodQName(qname);
IBinding bind = qname.resolveBinding();
IBinding bind = name.resolveBinding();
if (bind instanceof ICPPMethod) {
context.setType(MethodContext.ContextType.METHOD);
IIndexName[] decl;
decl = index.findDeclarations(bind);
String tuFileLoc = translationUnit.getFileLocation().getFileName();
if(decl.length == 0) {
context.setMethodDeclarationName(name);
}
for (IIndexName tmpname : decl) {
IASTTranslationUnit locTu = translationUnit;
if(!tuFileLoc.equals(tmpname.getFileLocation().getFileName())) {
@ -167,17 +166,15 @@ public class NodeHelper {
IASTName declName = DeclarationFinder.findDeclarationInTranslationUnit(locTu, tmpname);
if(declName != null) {
IASTNode methoddefinition = declName.getParent().getParent();
if (methoddefinition instanceof IASTSimpleDeclaration) {
if (methoddefinition instanceof IASTSimpleDeclaration || methoddefinition instanceof IASTFunctionDefinition) {
context.setMethodDeclarationName(declName);
}
}
}
}
}else {
if (name.getParent().getParent().getParent() instanceof ICPPASTCompositeTypeSpecifier) {
context.setType(ContextType.METHOD);
context.setMethodDeclarationName(name);
}
if(name instanceof ICPPASTQualifiedName){
ICPPASTQualifiedName qname =( ICPPASTQualifiedName )name;
context.setMethodQName(qname);
}
}