From 36908e15a1cfee16a449d24c57eb21e8cf172fcb Mon Sep 17 00:00:00 2001 From: leventov Date: Fri, 22 Apr 2016 01:47:53 +0100 Subject: [PATCH] Fix bugs with creating CtTypeAccess without cloning reference, that leads to problems with replace() in graph --- .../spoon/reflect/factory/CodeFactory.java | 16 ++++++++++ .../support/compiler/jdt/JDTTreeBuilder.java | 31 ++++++++++++------- 2 files changed, 36 insertions(+), 11 deletions(-) diff --git a/src/main/java/spoon/reflect/factory/CodeFactory.java b/src/main/java/spoon/reflect/factory/CodeFactory.java index c9a19c799ab..44dc1934668 100644 --- a/src/main/java/spoon/reflect/factory/CodeFactory.java +++ b/src/main/java/spoon/reflect/factory/CodeFactory.java @@ -92,11 +92,27 @@ public CtBinaryOperator createBinaryOperator(CtExpression left, CtExpr /** * Creates a accessed type. + * + *

This method sets a clone of the given {@code accessedType} object to the + * {@linkplain CtTypeAccess#getAccessedType() accessedType} field of the returned {@link CtTypeAccess}. If the + * given {@code accessedType} is unique and cloning is not needed, use + * {@link #createTypeAccessWithoutCloningReference(CtTypeReference)} instead of this method.

* @param accessedType a type reference to the accessed type. * @param the type of the expression. * @return a accessed type expression. */ public CtTypeAccess createTypeAccess(CtTypeReference accessedType) { + CtTypeReference accessedTypeClone = factory.Core().clone(accessedType); + return createTypeAccessWithoutCloningReference(accessedTypeClone); + } + + /** + * Creates a accessed type, see {@link #createTypeAccess(CtTypeReference)} for details. + * @param accessedType a type reference to the accessed type. + * @param the type of the expression. + * @return a accessed type expression. + */ + public CtTypeAccess createTypeAccessWithoutCloningReference(CtTypeReference accessedType) { final CtTypeAccess typeAccess = factory.Core().createTypeAccess(); typeAccess.setAccessedType(accessedType); return typeAccess; diff --git a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java index 3ab88a61f5f..b94df1cbff2 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java @@ -3099,7 +3099,8 @@ public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedT if (skipTypeInAnnotation) { return true; } - final CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(parameterizedQualifiedTypeReference.resolvedType)); + final CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(parameterizedQualifiedTypeReference.resolvedType)); context.enter(typeAccess, parameterizedQualifiedTypeReference); return true; } @@ -3109,7 +3110,8 @@ public boolean visit(ParameterizedQualifiedTypeReference parameterizedQualifiedT if (skipTypeInAnnotation) { return true; } - final CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(parameterizedQualifiedTypeReference.resolvedType)); + final CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(parameterizedQualifiedTypeReference.resolvedType)); context.enter(typeAccess, parameterizedQualifiedTypeReference); return true; } @@ -3119,7 +3121,8 @@ public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeRef if (skipTypeInAnnotation) { return true; } - final CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(parameterizedSingleTypeReference.resolvedType)); + final CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(parameterizedSingleTypeReference.resolvedType)); context.enter(typeAccess, parameterizedSingleTypeReference); return true; } @@ -3129,7 +3132,8 @@ public boolean visit(ParameterizedSingleTypeReference parameterizedSingleTypeRef if (skipTypeInAnnotation) { return true; } - final CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(parameterizedSingleTypeReference.resolvedType)); + final CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(parameterizedSingleTypeReference.resolvedType)); context.enter(typeAccess, parameterizedSingleTypeReference); return super.visit(parameterizedSingleTypeReference, scope); } @@ -3304,7 +3308,8 @@ public boolean onAccess(char[][] tokens, int index) { context.enter(va, qualifiedNameReference); return false; } else if (qualifiedNameReference.binding instanceof TypeBinding) { - CtTypeAccess ta = factory.Code().createTypeAccess(references.getTypeReference((TypeBinding) qualifiedNameReference.binding)); + CtTypeAccess ta = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference((TypeBinding) qualifiedNameReference.binding)); context.enter(ta, qualifiedNameReference); return false; } else if (qualifiedNameReference.binding instanceof ProblemBinding) { @@ -3312,7 +3317,7 @@ public boolean onAccess(char[][] tokens, int index) { if (context.stack.peek().element instanceof CtInvocation) { final CtTypeReference typeReference = factory.Core().createTypeReference(); typeReference.setSimpleName(qualifiedNameReference.toString()); - final CtTypeAccess ta = factory.Code().createTypeAccess(typeReference); + final CtTypeAccess ta = factory.Code().createTypeAccessWithoutCloningReference(typeReference); context.enter(ta, qualifiedNameReference); return false; } else if (context.stack.peek().element instanceof CtAssignment && context.assigned) { @@ -3354,7 +3359,8 @@ public boolean visit(QualifiedTypeReference arg0, BlockScope arg1) { if (skipTypeInAnnotation) { return true; } - final CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(arg0.resolvedType)); + final CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(arg0.resolvedType)); context.enter(typeAccess, arg0); return true; // do nothing by default, keep traversing } @@ -3415,7 +3421,8 @@ public boolean visit(SingleNameReference singleNameReference, BlockScope scope) } va.setVariable(references.getVariableReference((VariableBinding) singleNameReference.binding)); } else if (singleNameReference.binding instanceof TypeBinding) { - CtTypeAccess ta = factory.Code().createTypeAccess(references.getTypeReference((TypeBinding) singleNameReference.binding)); + CtTypeAccess ta = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference((TypeBinding) singleNameReference.binding)); context.enter(ta, singleNameReference); } else if (singleNameReference.binding instanceof ProblemBinding) { if (context.stack.peek().element instanceof CtInvocation @@ -3471,7 +3478,7 @@ public boolean visit(QualifiedSuperReference qualifiedSuperReference, BlockScope CtTypeReference typeRefOfSuper = references.getTypeReference(qualifiedSuperReference.qualification.resolvedType); final CtSuperAccess superAccess = factory.Core().createSuperAccess(); - CtTypeAccess typeAccess = factory.Code().createTypeAccess(typeRefOfSuper); + CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference(typeRefOfSuper); superAccess.setTarget(typeAccess); context.enter(superAccess, qualifiedSuperReference); @@ -3514,7 +3521,8 @@ public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) if (skipTypeInAnnotation) { return true; } - final CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(singleTypeReference.resolvedType)); + final CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(singleTypeReference.resolvedType)); context.enter(typeAccess, singleTypeReference); return true; // do nothing by default, keep traversing } @@ -3524,7 +3532,8 @@ public boolean visit(SingleTypeReference singleTypeReference, ClassScope scope) if (skipTypeInAnnotation) { return true; } - CtTypeAccess typeAccess = factory.Code().createTypeAccess(references.getTypeReference(singleTypeReference.resolvedType)); + CtTypeAccess typeAccess = factory.Code().createTypeAccessWithoutCloningReference( + references.getTypeReference(singleTypeReference.resolvedType)); context.enter(typeAccess, singleTypeReference); return true; // do nothing by default, keep traversing }