From 1102f312ae3e4b58cbf54a504ae2fcf72f495c9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Simon=20Lars=C3=A9n?= Date: Tue, 11 May 2021 15:02:23 +0200 Subject: [PATCH] ix: Fix unqualified type becoming qualified in union type catch (#3918) --- .../support/compiler/jdt/JDTTreeBuilder.java | 9 +++-- .../spoon/test/trycatch/TryCatchTest.java | 37 +++++++++++++++++++ ...erWithQualifiedAndUnqualifiedTypeRefs.java | 11 ++++++ ...ltipleUnqualifiedTypesInSingleCatcher.java | 11 ++++++ 4 files changed, 65 insertions(+), 3 deletions(-) create mode 100644 src/test/java/spoon/test/trycatch/testclasses/CatcherWithQualifiedAndUnqualifiedTypeRefs.java create mode 100644 src/test/java/spoon/test/trycatch/testclasses/MultipleUnqualifiedTypesInSingleCatcher.java diff --git a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java index 5e2e5e7c030..9c1b67a8b84 100644 --- a/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/JDTTreeBuilder.java @@ -1608,15 +1608,18 @@ public boolean visit(SingleTypeReference singleTypeReference, BlockScope scope) return true; } if (context.stack.peekFirst().node instanceof UnionTypeReference) { + CtTypeReference typeReference; + if (singleTypeReference.resolvedType == null) { - CtTypeReference typeReference = factory.Type().createReference(singleTypeReference.toString()); + typeReference = factory.Type().createReference(singleTypeReference.toString()); CtReference ref = references.getDeclaringReferenceFromImports(singleTypeReference.getLastToken()); references.setPackageOrDeclaringType(typeReference, ref); - context.enter(typeReference, singleTypeReference); } else { - context.enter(references.getTypeReference(singleTypeReference.resolvedType), singleTypeReference); + typeReference = references.getTypeReference(singleTypeReference.resolvedType); } + context.enter(typeReference, singleTypeReference); + typeReference.setSimplyQualified(true); return true; } else if (context.stack.peekFirst().element instanceof CtCatch) { context.enter(helper.createCatchVariable(singleTypeReference, scope), singleTypeReference); diff --git a/src/test/java/spoon/test/trycatch/TryCatchTest.java b/src/test/java/spoon/test/trycatch/TryCatchTest.java index 0376a7e8ec1..e57b82da879 100644 --- a/src/test/java/spoon/test/trycatch/TryCatchTest.java +++ b/src/test/java/spoon/test/trycatch/TryCatchTest.java @@ -45,7 +45,10 @@ import java.util.List; import java.util.Set; +import static org.hamcrest.CoreMatchers.equalTo; +import static org.hamcrest.MatcherAssert.assertThat; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; @@ -349,4 +352,38 @@ public void testCatchUnqualifiedReferenceIsMarkedSimplyQualified() throws Except CtTypeReference catchParamType = targetCatch.getParameter().getType(); assertTrue(catchParamType.isSimplyQualified()); } + + @Test + public void testCatchUnqualifiedReferenceMarkedSimplyQualifiedWhenMultipleTypesAreSpecified() throws Exception { + // contract: Unqualified type references should have implicit packages when there are + // multiple types in a single catcher + + CtClass clazz = build( + "spoon.test.trycatch.testclasses", "MultipleUnqualifiedTypesInSingleCatcher"); + List catches = clazz.getElements(e -> true); + assertEquals(1, catches.size()); + + CtCatch targetCatch = catches.get(0); + List> paramTypes = targetCatch.getParameter().getMultiTypes(); + assertThat(paramTypes.size(), equalTo(2)); + assertTrue("first type reference is fully qualified", paramTypes.get(0).isSimplyQualified()); + assertTrue("second type reference is fully qualified", paramTypes.get(1).isSimplyQualified()); + } + + @Test + public void testCatchWithQualifiedAndUnqualifiedTypeReferencesInSameCatcher() throws Exception { + // contract: It should be possible for qualified and unqualified type references to exist in + // the same catcher + + CtClass clazz = build( + "spoon.test.trycatch.testclasses", "CatcherWithQualifiedAndUnqualifiedTypeRefs"); + List catches = clazz.getElements(e -> true); + assertEquals(1, catches.size()); + + CtCatch targetCatch = catches.get(0); + List> paramTypes = targetCatch.getParameter().getMultiTypes(); + assertThat(paramTypes.size(), equalTo(2)); + assertTrue("first type reference should be unqualified", paramTypes.get(0).isSimplyQualified()); + assertFalse("second type reference should be qualified", paramTypes.get(1).isSimplyQualified()); + } } diff --git a/src/test/java/spoon/test/trycatch/testclasses/CatcherWithQualifiedAndUnqualifiedTypeRefs.java b/src/test/java/spoon/test/trycatch/testclasses/CatcherWithQualifiedAndUnqualifiedTypeRefs.java new file mode 100644 index 00000000000..c53dd740e18 --- /dev/null +++ b/src/test/java/spoon/test/trycatch/testclasses/CatcherWithQualifiedAndUnqualifiedTypeRefs.java @@ -0,0 +1,11 @@ +package spoon.test.trycatch.testclasses; + +public class CatcherWithQualifiedAndUnqualifiedTypeRefs { + public static void main(String[] args) { + try { + throw new InterruptedException(); + } catch (InterruptedException | java.lang.RuntimeException e) { + // pass + } + } +} diff --git a/src/test/java/spoon/test/trycatch/testclasses/MultipleUnqualifiedTypesInSingleCatcher.java b/src/test/java/spoon/test/trycatch/testclasses/MultipleUnqualifiedTypesInSingleCatcher.java new file mode 100644 index 00000000000..59495bc5d2d --- /dev/null +++ b/src/test/java/spoon/test/trycatch/testclasses/MultipleUnqualifiedTypesInSingleCatcher.java @@ -0,0 +1,11 @@ +package spoon.test.trycatch.testclasses; + +class MultipleUnqualifiedTypesInSingleCatcher { + public static void main(String[] args) { + try { + throw new InterruptedException(); + } catch (InterruptedException | RuntimeException e) { + // pass + } + } +} \ No newline at end of file