diff --git a/src/main/java/spoon/support/compiler/jdt/ContextBuilder.java b/src/main/java/spoon/support/compiler/jdt/ContextBuilder.java index 8805373ba4d..9161ec2f644 100644 --- a/src/main/java/spoon/support/compiler/jdt/ContextBuilder.java +++ b/src/main/java/spoon/support/compiler/jdt/ContextBuilder.java @@ -257,7 +257,11 @@ private > U getVariableDeclaration( if (name.equals(new String(fieldBinding.readableName()))) { final String qualifiedNameOfParent = getNormalQualifiedName(referenceBinding); - final CtType parentOfField = referenceBinding.isClass() + CtType parentOfField = typeFactory.get(qualifiedNameOfParent); + if (parentOfField != null) { + return (U) parentOfField.getField(name); + } + parentOfField = referenceBinding.isClass() ? classFactory.create(qualifiedNameOfParent) : interfaceFactory.create(qualifiedNameOfParent); diff --git a/src/test/java/spoon/test/type/TypeTest.java b/src/test/java/spoon/test/type/TypeTest.java index 765b7c5fb1f..8625becf176 100644 --- a/src/test/java/spoon/test/type/TypeTest.java +++ b/src/test/java/spoon/test/type/TypeTest.java @@ -37,6 +37,7 @@ import spoon.reflect.code.CtLocalVariable; import spoon.reflect.code.CtNewClass; import spoon.reflect.code.CtTypeAccess; +import spoon.reflect.cu.SourcePosition; import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtMethod; import spoon.reflect.declaration.CtType; @@ -56,6 +57,7 @@ import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertFalse; +import static org.junit.jupiter.api.Assertions.assertNotEquals; import static org.junit.jupiter.api.Assertions.assertNotNull; import static org.junit.jupiter.api.Assertions.assertSame; import static org.junit.jupiter.api.Assertions.assertTrue; @@ -417,4 +419,15 @@ public void testBinaryOpStringsType() { List concats = model.getElements(new TypeFilter<>(CtBinaryOperator.class)); concats.forEach(c -> assertEquals("java.lang.String", c.getType().toString())); } + + @ModelTest( + value = {"./src/test/resources/noclasspath/issue5208/"}, + noClasspath = true + ) + void testClassNotReplacedInNoClasspathMode(Factory factory) { + // contract: ClassT1 is not replaced once present when looking up the ClassT1#classT3 field from ClassT2 + CtType type = factory.Type().get("p20.ClassT1"); + assertNotNull(type); + assertNotEquals(SourcePosition.NOPOSITION, type.getPosition()); + } } diff --git a/src/test/resources/noclasspath/issue5208/p20/ClassT1.java b/src/test/resources/noclasspath/issue5208/p20/ClassT1.java new file mode 100644 index 00000000000..ba3b1c398bc --- /dev/null +++ b/src/test/resources/noclasspath/issue5208/p20/ClassT1.java @@ -0,0 +1,11 @@ +package p20; +public abstract class ClassT1 { + ClassT3 classT3; + + public ClassT1(){ + this.classT3 = new ClassT3(this); + } + + void fun2(ClassT3 classT3){ + } +} \ No newline at end of file diff --git a/src/test/resources/noclasspath/issue5208/p20/ClassT2.java b/src/test/resources/noclasspath/issue5208/p20/ClassT2.java new file mode 100644 index 00000000000..1d012664781 --- /dev/null +++ b/src/test/resources/noclasspath/issue5208/p20/ClassT2.java @@ -0,0 +1,10 @@ +package p20; +import p8.GlobalExecutor; + +public class ClassT2 extends ClassT1 { + public void fun(){ + GlobalExecutor.executeByCommon(() -> { + fun2(classT3); + }); + } +} \ No newline at end of file diff --git a/src/test/resources/noclasspath/issue5208/p20/ClassT3.java b/src/test/resources/noclasspath/issue5208/p20/ClassT3.java new file mode 100644 index 00000000000..893541a672f --- /dev/null +++ b/src/test/resources/noclasspath/issue5208/p20/ClassT3.java @@ -0,0 +1,9 @@ +package p20; + +public class ClassT3 { + final ClassT1 classT1; + + public ClassT3(ClassT1 classT1) { + this.classT1 = classT1; + } +} \ No newline at end of file