diff --git a/src/main/java/spoon/reflect/factory/TypeFactory.java b/src/main/java/spoon/reflect/factory/TypeFactory.java index ce339ad6f2e..f84f4440147 100644 --- a/src/main/java/spoon/reflect/factory/TypeFactory.java +++ b/src/main/java/spoon/reflect/factory/TypeFactory.java @@ -16,10 +16,7 @@ */ package spoon.reflect.factory; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; - +import spoon.reflect.code.CtNewClass; import spoon.reflect.declaration.CtElement; import spoon.reflect.declaration.CtPackage; import spoon.reflect.declaration.CtType; @@ -27,6 +24,11 @@ import spoon.reflect.reference.CtArrayTypeReference; import spoon.reflect.reference.CtTypeParameterReference; import spoon.reflect.reference.CtTypeReference; +import spoon.reflect.visitor.filter.TypeFilter; + +import java.util.ArrayList; +import java.util.Date; +import java.util.List; /** * The {@link CtType} sub-factory. @@ -174,7 +176,7 @@ public CtTypeReference createReference(String qualifiedName) { * @return a found type or null if does not exist */ @SuppressWarnings("unchecked") - public CtType get(String qualifiedName) { + public CtType get(final String qualifiedName) { int inertTypeIndex = qualifiedName.lastIndexOf(CtType.INNERTTYPE_SEPARATOR); if (inertTypeIndex > 0) { String s = qualifiedName.substring(0, inertTypeIndex); @@ -182,7 +184,25 @@ public CtType get(String qualifiedName) { if (t == null) { return null; } - return t.getNestedType(qualifiedName.substring(inertTypeIndex + 1)); + String className = qualifiedName.substring(inertTypeIndex + 1); + try { + // If the class name can't be parsed in integer, the method throws an exception. + // If the class name is an integer, the class is an anonymous class, otherwise, + // it is a standard class. + Integer.parseInt(className); + final List anonymousClasses = t.getElements(new TypeFilter(CtNewClass.class) { + @Override + public boolean matches(CtNewClass element) { + return super.matches(element) && element.getAnonymousClass().getQualifiedName().equals(qualifiedName); + } + }); + if (anonymousClasses.size() == 0) { + return null; + } + return anonymousClasses.get(0).getAnonymousClass(); + } catch (NumberFormatException e) { + return t.getNestedType(className); + } } int packageIndex = qualifiedName.lastIndexOf(CtPackage.PACKAGE_SEPARATOR); diff --git a/src/test/java/spoon/test/secondaryclasses/ClassesTest.java b/src/test/java/spoon/test/secondaryclasses/ClassesTest.java index 44ad22e625d..097f8579f50 100644 --- a/src/test/java/spoon/test/secondaryclasses/ClassesTest.java +++ b/src/test/java/spoon/test/secondaryclasses/ClassesTest.java @@ -1,29 +1,32 @@ package spoon.test.secondaryclasses; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; -import static spoon.test.TestUtils.build; - -import java.awt.event.ActionListener; -import java.util.List; - import org.junit.Test; - import spoon.reflect.code.CtBlock; import spoon.reflect.code.CtNewClass; +import spoon.reflect.code.CtVariableRead; import spoon.reflect.declaration.CtClass; import spoon.reflect.declaration.CtField; import spoon.reflect.declaration.CtNamedElement; import spoon.reflect.declaration.CtType; +import spoon.reflect.declaration.CtVariable; import spoon.reflect.factory.Factory; import spoon.reflect.reference.CtTypeReference; import spoon.reflect.visitor.filter.AbstractFilter; import spoon.reflect.visitor.filter.NameFilter; import spoon.reflect.visitor.filter.TypeFilter; import spoon.test.secondaryclasses.AnonymousClass.I; +import spoon.test.secondaryclasses.testclasses.Pozole; + +import java.awt.event.ActionListener; +import java.util.List; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertNull; +import static org.junit.Assert.assertTrue; +import static spoon.test.TestUtils.build; +import static spoon.test.TestUtils.buildClass; public class ClassesTest { @@ -131,4 +134,15 @@ public void testInnerClassContruction() throws Exception { assertEquals(0, f.getEnvironment().getErrorCount()); } + @Test + public void testAnonymousClassInStaticField() throws Exception { + final CtType type = buildClass(Pozole.class); + + final CtNewClass anonymousClass = type.getField("CONFLICT_HOOK").getElements(new TypeFilter<>(CtNewClass.class)).get(1); + final CtVariableRead ctVariableRead = anonymousClass.getElements(new TypeFilter<>(CtVariableRead.class)).get(2); + final CtVariable declaration = ctVariableRead.getVariable().getDeclaration(); + + assertNotNull(declaration); + assertEquals("int i", declaration.toString()); + } } diff --git a/src/test/java/spoon/test/secondaryclasses/testclasses/Pozole.java b/src/test/java/spoon/test/secondaryclasses/testclasses/Pozole.java new file mode 100644 index 00000000000..b15443b5f4e --- /dev/null +++ b/src/test/java/spoon/test/secondaryclasses/testclasses/Pozole.java @@ -0,0 +1,79 @@ +/* + * Copyright (C) 2006-2015 INRIA and contributors + * Spoon - http://spoon.gforge.inria.fr/ + * + * This software is governed by the CeCILL-C License under French law and + * abiding by the rules of distribution of free software. You can use, modify + * and/or redistribute the software under the terms of the CeCILL-C license as + * circulated by CEA, CNRS and INRIA at http://www.cecill.info. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the CeCILL-C License for more details. + * + * The fact that you are presently reading this means that you have had + * knowledge of the CeCILL-C license and that you accept its terms. + */ + +package spoon.test.secondaryclasses.testclasses; + +import javax.swing.JFrame; +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.Rectangle; +import java.awt.geom.AffineTransform; +import java.awt.image.ColorModel; + +public class Pozole { + private static final Object CONFLICT_HOOK = new JFrame(new GraphicsConfiguration() { + @Override + public GraphicsDevice getDevice() { + return null; + } + + @Override + public ColorModel getColorModel() { + return null; + } + + @Override + public ColorModel getColorModel(int i) { + return new ColorModel(i) { + @Override + public int getRed(int i) { + return i; + } + + @Override + public int getGreen(int i) { + return 0; + } + + @Override + public int getBlue(int i) { + return 0; + } + + @Override + public int getAlpha(int i) { + return 0; + } + }; + } + + @Override + public AffineTransform getDefaultTransform() { + return null; + } + + @Override + public AffineTransform getNormalizingTransform() { + return null; + } + + @Override + public Rectangle getBounds() { + return null; + } + }); +}