diff --git a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java index 022ecdec797..322f22a7253 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java @@ -1509,7 +1509,7 @@ public boolean visit(QualifiedTypeReference qualifiedTypeReference, BlockScope s context.enter(reference, qualifiedTypeReference); return true; } else if (context.stack.peekFirst().element instanceof CtCatch) { - context.enter(helper.createCatchVariable(qualifiedTypeReference), qualifiedTypeReference); + context.enter(helper.createCatchVariable(qualifiedTypeReference, scope), qualifiedTypeReference); return true; } context.enter(factory.Code().createTypeAccessWithoutCloningReference(references.buildTypeReference(qualifiedTypeReference, scope)), qualifiedTypeReference); @@ -1593,7 +1593,7 @@ public boolean visit(UnionTypeReference unionTypeReference, BlockScope scope) { if (!(context.stack.peekFirst().node instanceof Argument)) { throw new SpoonException("UnionType is only supported for CtCatch."); } - context.enter(helper.createCatchVariable(unionTypeReference), unionTypeReference); + context.enter(helper.createCatchVariable(unionTypeReference, scope), unionTypeReference); return true; } @@ -1619,7 +1619,7 @@ public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) return true; } else if (context.stack.peekFirst().element instanceof CtCatch) { - context.enter(helper.createCatchVariable(singleTypeReference), singleTypeReference); + context.enter(helper.createCatchVariable(singleTypeReference, scope), singleTypeReference); return true; } CtTypeReference typeRef = references.buildTypeReference(singleTypeReference, scope); diff --git a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilderHelper.java b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilderHelper.java index 13740b1b5fa..173ed32da37 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilderHelper.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilderHelper.java @@ -33,6 +33,7 @@ import org.eclipse.jdt.internal.compiler.lookup.ProblemBinding; import org.eclipse.jdt.internal.compiler.lookup.ProblemReferenceBinding; import org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding; +import org.eclipse.jdt.internal.compiler.lookup.Scope; import org.eclipse.jdt.internal.compiler.lookup.TagBits; import org.eclipse.jdt.internal.compiler.lookup.TypeBinding; import org.eclipse.jdt.internal.compiler.lookup.VariableBinding; @@ -117,7 +118,7 @@ static String createQualifiedTypeName(char[][] typeName) { * Corresponds to the exception type declared in the catch. * @return a catch variable. */ - CtCatchVariable createCatchVariable(TypeReference typeReference) { + CtCatchVariable createCatchVariable(TypeReference typeReference, Scope scope) { final Argument jdtCatch = (Argument) jdtTreeBuilder.getContextBuilder().stack.peekFirst().node; final Set modifiers = getModifiers(jdtCatch.modifiers, false, false); @@ -127,12 +128,7 @@ CtCatchVariable createCatchVariable(TypeReference typeReference) { //do not set type of variable yet. It will be initialized later by visit of multiple types. Each call then ADDs one type return result; } else { - CtTypeReference ctTypeReference; - if (typeReference.resolvedType instanceof ProblemReferenceBinding) { - ctTypeReference = jdtTreeBuilder.getReferencesBuilder().buildTypeReference(typeReference, null); - } else { - ctTypeReference = jdtTreeBuilder.getReferencesBuilder().getTypeReference(typeReference.resolvedType); - } + CtTypeReference ctTypeReference = jdtTreeBuilder.getReferencesBuilder().buildTypeReference(typeReference, scope); return result.setType(ctTypeReference); } } diff --git a/src/test/java/spoon/test/trycatch/TryCatchTest.java b/src/test/java/spoon/test/trycatch/TryCatchTest.java index 0a252259d80..0376a7e8ec1 100644 --- a/src/test/java/spoon/test/trycatch/TryCatchTest.java +++ b/src/test/java/spoon/test/trycatch/TryCatchTest.java @@ -336,4 +336,17 @@ public void testCatchQualifiedReferenceNoClasspath() { assertEquals("CustomException", caughtType.getSimpleName()); assertEquals("some.neat.pkg.CustomException", caughtType.getQualifiedName()); } + + @Test + public void testCatchUnqualifiedReferenceIsMarkedSimplyQualified() throws Exception { + // contract: An unqualified type reference in a catch clause should have its package marked implicit + + CtClass clazz = build("spoon.test.trycatch.testclasses", "CatchWithUnqualifiedType"); + List catches = clazz.getElements(e -> true); + assertEquals(1, catches.size()); + + CtCatch targetCatch = catches.get(0); + CtTypeReference catchParamType = targetCatch.getParameter().getType(); + assertTrue(catchParamType.isSimplyQualified()); + } } diff --git a/src/test/java/spoon/test/trycatch/testclasses/CatchWithUnqualifiedType.java b/src/test/java/spoon/test/trycatch/testclasses/CatchWithUnqualifiedType.java new file mode 100644 index 00000000000..e05a6d30e66 --- /dev/null +++ b/src/test/java/spoon/test/trycatch/testclasses/CatchWithUnqualifiedType.java @@ -0,0 +1,12 @@ +package spoon.test.trycatch.testclasses; + +import java.io.IOException; + +public class CatchWithUnqualifiedType { + public static void main(String[] args) { + try { + throw new IOException(); + } catch (IOException e) { + } + } +}