Search in sources :

Example 26 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class StringLiteralTest method testSnippetFullClass.

@SuppressWarnings("unused")
@Test
public void testSnippetFullClass() {
    Factory factory = createFactory();
    CtClass<?> clazz = factory.Code().createCodeSnippetStatement("class StringValueUTF {\n" + "	String f0 = \"toto\";\n" + "	String f1 = \"\\n\";\n" + "	char c1 = '\\n';\n" + "	String f2 = \"\\u20ac\";\n" + "	char c2 = '\\u20ac';\n" + "	String f3 = \"€\";\n" + "	char c3 = '€';\n" + "	String f4 = \"\\t\";\n" + "	char c4 = '\\t';\n" + "	String f5 = \"	\";\n" + "	char c5 = '	';\n" + "	String f6 = \"€\\u20ac\";\n" + "}").compile();
    CtField<?> f0 = (CtField<?>) clazz.getFields().toArray()[0];
    CtField<?> f1 = (CtField<?>) clazz.getFields().toArray()[1];
    CtField<?> c1 = (CtField<?>) clazz.getFields().toArray()[2];
    CtField<?> f2 = (CtField<?>) clazz.getFields().toArray()[3];
    CtField<?> c2 = (CtField<?>) clazz.getFields().toArray()[4];
    CtField<?> f3 = (CtField<?>) clazz.getFields().toArray()[5];
    CtField<?> c3 = (CtField<?>) clazz.getFields().toArray()[6];
    CtField<?> f4 = (CtField<?>) clazz.getFields().toArray()[7];
    CtField<?> c4 = (CtField<?>) clazz.getFields().toArray()[8];
    CtField<?> f5 = (CtField<?>) clazz.getFields().toArray()[9];
    CtField<?> c5 = (CtField<?>) clazz.getFields().toArray()[10];
    CtField<?> f6 = (CtField<?>) clazz.getFields().toArray()[11];
    assertEquals("java.lang.String f0 = \"toto\";", f0.toString());
    assertEquals("java.lang.String f1 = \"\\n\";", f1.toString());
    assertEquals("char c1 = '\\n';", c1.toString());
    assertEquals("java.lang.String f2 = \"\\u20ac\";", f2.toString());
    assertEquals("char c2 = '\\u20ac';", c2.toString());
    assertEquals("java.lang.String f3 = \"€\";", f3.toString());
    assertEquals("char c3 = '€';", c3.toString());
    assertEquals("java.lang.String f4 = \"\\t\";", f4.toString());
    assertEquals("char c4 = '\\t';", c4.toString());
    assertEquals("java.lang.String f5 = \"	\";", f5.toString());
    assertEquals("char c5 = '	';", c5.toString());
// spoon cannot handle unicode and unicode in the same literal
// assertEquals("java.lang.String f6 = \"€\\u20ac\";", f6.toString());
}
Also used : CtField(spoon.reflect.declaration.CtField) Factory(spoon.reflect.factory.Factory) ModelUtils.createFactory(spoon.testing.utils.ModelUtils.createFactory) Test(org.junit.Test)

Example 27 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class ContextBuilder method getVariableDeclaration.

@SuppressWarnings("unchecked")
private <T, U extends CtVariable<T>> U getVariableDeclaration(final String name, final Class<U> clazz) {
    final CoreFactory coreFactory = jdtTreeBuilder.getFactory().Core();
    final TypeFactory typeFactory = jdtTreeBuilder.getFactory().Type();
    final ClassFactory classFactory = jdtTreeBuilder.getFactory().Class();
    final InterfaceFactory interfaceFactory = jdtTreeBuilder.getFactory().Interface();
    final FieldFactory fieldFactory = jdtTreeBuilder.getFactory().Field();
    final ReferenceBuilder referenceBuilder = jdtTreeBuilder.getReferencesBuilder();
    final Environment environment = jdtTreeBuilder.getFactory().getEnvironment();
    // there is some extra work to do if we are looking for CtFields (and subclasses)
    final boolean lookingForFields = clazz == null || coreFactory.createField().getClass().isAssignableFrom(clazz);
    // try to find the variable on stack beginning with the most recent element
    for (final ASTPair astPair : stack) {
        // the variable may have been declared directly by one of these elements
        final ScopeRespectingVariableScanner<U> scanner = new ScopeRespectingVariableScanner(name, clazz);
        astPair.element.accept(scanner);
        if (scanner.getResult() != null) {
            return scanner.getResult();
        }
        // the variable may have been declared in a super class/interface
        if (lookingForFields && astPair.node instanceof TypeDeclaration) {
            final TypeDeclaration nodeDeclaration = (TypeDeclaration) astPair.node;
            final Deque<ReferenceBinding> referenceBindings = new ArrayDeque<>();
            // add super class if any
            if (nodeDeclaration.superclass != null && nodeDeclaration.superclass.resolvedType instanceof ReferenceBinding) {
                referenceBindings.push((ReferenceBinding) nodeDeclaration.superclass.resolvedType);
            }
            // add interfaces if any
            if (nodeDeclaration.superInterfaces != null) {
                for (final TypeReference tr : nodeDeclaration.superInterfaces) {
                    if (tr.resolvedType instanceof ReferenceBinding) {
                        referenceBindings.push((ReferenceBinding) tr.resolvedType);
                    }
                }
            }
            while (!referenceBindings.isEmpty()) {
                final ReferenceBinding referenceBinding = referenceBindings.pop();
                for (final FieldBinding fieldBinding : referenceBinding.fields()) {
                    if (name.equals(new String(fieldBinding.readableName()))) {
                        final String qualifiedNameOfParent = new String(referenceBinding.readableName());
                        final CtType parentOfField = referenceBinding.isClass() ? classFactory.create(qualifiedNameOfParent) : interfaceFactory.create(qualifiedNameOfParent);
                        U field = (U) fieldFactory.create(parentOfField, EnumSet.noneOf(ModifierKind.class), referenceBuilder.getTypeReference(fieldBinding.type), name);
                        return field.setExtendedModifiers(JDTTreeBuilderQuery.getModifiers(fieldBinding.modifiers, true, false));
                    }
                }
                // add super class if any
                final ReferenceBinding superclass = referenceBinding.superclass();
                if (superclass != null) {
                    referenceBindings.push(superclass);
                }
                // add interfaces if any
                final ReferenceBinding[] interfaces = referenceBinding.superInterfaces();
                if (interfaces != null) {
                    for (ReferenceBinding rb : interfaces) {
                        referenceBindings.push(rb);
                    }
                }
            }
        }
    }
    // the variable may have been imported statically from another class/interface
    if (lookingForFields) {
        final CtReference potentialReferenceToField = referenceBuilder.getDeclaringReferenceFromImports(name.toCharArray());
        if (potentialReferenceToField != null && potentialReferenceToField instanceof CtTypeReference) {
            final CtTypeReference typeReference = (CtTypeReference) potentialReferenceToField;
            try {
                final Class classOfType = typeReference.getActualClass();
                if (classOfType != null) {
                    final CtType declaringTypeOfField = typeReference.isInterface() ? interfaceFactory.get(classOfType) : classFactory.get(classOfType);
                    final CtField field = declaringTypeOfField.getField(name);
                    if (field != null) {
                        return (U) field;
                    }
                }
            } catch (final SpoonClassNotFoundException scnfe) {
                // field that has been imported statically from another class (or interface).
                if (environment.getNoClasspath()) {
                    // assume a constant value according to JLS.
                    if (name.toUpperCase().equals(name)) {
                        final CtType parentOfField = classFactory.create(typeReference.getQualifiedName());
                        // it is the best thing we can do
                        final CtField field = coreFactory.createField();
                        field.setParent(parentOfField);
                        field.setSimpleName(name);
                        // it is the best thing we can do
                        field.setType(typeFactory.nullType());
                        return (U) field;
                    }
                }
            }
        }
    }
    return null;
}
Also used : FieldFactory(spoon.reflect.factory.FieldFactory) ClassFactory(spoon.reflect.factory.ClassFactory) ReferenceBinding(org.eclipse.jdt.internal.compiler.lookup.ReferenceBinding) CtReference(spoon.reflect.reference.CtReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtField(spoon.reflect.declaration.CtField) SpoonClassNotFoundException(spoon.support.SpoonClassNotFoundException) TypeReference(org.eclipse.jdt.internal.compiler.ast.TypeReference) CtTypeReference(spoon.reflect.reference.CtTypeReference) InterfaceFactory(spoon.reflect.factory.InterfaceFactory) CoreFactory(spoon.reflect.factory.CoreFactory) ArrayDeque(java.util.ArrayDeque) CtType(spoon.reflect.declaration.CtType) FieldBinding(org.eclipse.jdt.internal.compiler.lookup.FieldBinding) Environment(spoon.compiler.Environment) TypeFactory(spoon.reflect.factory.TypeFactory) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration)

Example 28 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class FieldReferenceFunction method apply.

@Override
public void apply(CtElement fieldOrScope, CtConsumer<Object> outputConsumer) {
    CtElement scope;
    CtField<?> field = this.field;
    if (field == null) {
        if (fieldOrScope instanceof CtField) {
            field = (CtField<?>) fieldOrScope;
        } else {
            throw new SpoonException("The input of FieldReferenceFunction must be a CtField but is " + fieldOrScope.getClass().getSimpleName());
        }
        scope = field.getFactory().getModel().getUnnamedModule();
    } else {
        scope = fieldOrScope;
    }
    scope.filterChildren(new DirectReferenceFilter<CtFieldReference<?>>(field.getReference())).forEach(outputConsumer);
}
Also used : SpoonException(spoon.SpoonException) CtElement(spoon.reflect.declaration.CtElement) CtField(spoon.reflect.declaration.CtField)

Example 29 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class MetamodelTest method testRoleOnField.

@Test
public void testRoleOnField() {
    // contract: all non-final fields must be annotated with {@link spoon.reflect.annotations.MetamodelPropertyField}
    SpoonAPI implementations = new Launcher();
    implementations.addInputResource("src/main/java/spoon/support/reflect");
    implementations.buildModel();
    Factory factory = implementations.getFactory();
    CtTypeReference metamodelPropertyField = factory.Type().get(MetamodelPropertyField.class).getReference();
    final List<String> result = new ArrayList();
    List<CtField> fieldWithoutAnnotation = (List<CtField>) implementations.getModel().getElements(new TypeFilter<CtField>(CtField.class) {

        @Override
        public boolean matches(CtField candidate) {
            if (candidate.hasModifier(ModifierKind.FINAL) || candidate.hasModifier(ModifierKind.STATIC) || candidate.hasModifier(ModifierKind.TRANSIENT)) {
                return false;
            }
            if (// not a role
            "parent".equals(candidate.getSimpleName()) || "metadata".equals(candidate.getSimpleName()) || // cache field
            "valueOfMethod".equals(candidate.getSimpleName())) {
                return false;
            }
            CtClass parent = candidate.getParent(CtClass.class);
            return parent != null && (parent.isSubtypeOf(candidate.getFactory().createCtTypeReference(CtReference.class)) || parent.isSubtypeOf(candidate.getFactory().createCtTypeReference(CtElement.class)));
        }
    }).stream().map(x -> {
        result.add(x.toString());
        return x;
    }).filter(f -> f.getAnnotation(metamodelPropertyField) == null).collect(Collectors.toList());
    assertTrue(result.contains("@spoon.reflect.annotations.MetamodelPropertyField(role = spoon.reflect.path.CtRole.IS_SHADOW)\nboolean isShadow;"));
    assertTrue(result.contains("@spoon.reflect.annotations.MetamodelPropertyField(role = spoon.reflect.path.CtRole.TYPE)\nspoon.reflect.reference.CtTypeReference<T> type;"));
    assertTrue(result.size() > 100);
    Assert.assertEquals(Collections.emptyList(), fieldWithoutAnnotation);
    final CtTypeReference propertySetter = factory.Type().get(PropertySetter.class).getReference();
    final CtTypeReference propertyGetter = factory.Type().get(PropertyGetter.class).getReference();
    List<CtField> fields = factory.getModel().getElements(new AnnotationFilter<CtField>(MetamodelPropertyField.class));
    for (CtField field : fields) {
        CtClass parent = field.getParent(CtClass.class);
        CtExpression roleExpression = field.getAnnotation(metamodelPropertyField).getValue("role");
        List<String> roles = new ArrayList<>();
        if (roleExpression instanceof CtFieldRead) {
            roles.add(((CtFieldRead) roleExpression).getVariable().getSimpleName());
        } else if (roleExpression instanceof CtNewArray) {
            List<CtFieldRead> elements = ((CtNewArray) roleExpression).getElements();
            for (int i = 0; i < elements.size(); i++) {
                CtFieldRead ctFieldRead = elements.get(i);
                roles.add(ctFieldRead.getVariable().getSimpleName());
            }
        }
        CtQuery superQuery = parent.map(new SuperInheritanceHierarchyFunction());
        List<CtMethod> methods = superQuery.map((CtType type) -> type.getMethodsAnnotatedWith(propertyGetter, propertySetter)).list();
        boolean setterFound = false;
        boolean getterFound = false;
        for (CtMethod method : methods) {
            CtAnnotation getterAnnotation = method.getAnnotation(propertyGetter);
            CtAnnotation setterAnnotation = method.getAnnotation(propertySetter);
            if (getterAnnotation != null) {
                getterFound |= roles.contains(((CtFieldRead) getterAnnotation.getValue("role")).getVariable().getSimpleName());
            }
            if (setterAnnotation != null) {
                setterFound |= roles.contains(((CtFieldRead) setterAnnotation.getValue("role")).getVariable().getSimpleName());
            }
        }
        assertTrue(roles + " must have a getter in " + parent.getQualifiedName(), getterFound);
        assertTrue(roles + " must have a setter in " + parent.getQualifiedName(), setterFound);
    }
}
Also used : Arrays(java.util.Arrays) Launcher(spoon.Launcher) IsEqual.equalTo(org.hamcrest.core.IsEqual.equalTo) CtRole(spoon.reflect.path.CtRole) ArrayList(java.util.ArrayList) CtType(spoon.reflect.declaration.CtType) CtElement(spoon.reflect.declaration.CtElement) SpoonAPI(spoon.SpoonAPI) CtExpression(spoon.reflect.code.CtExpression) CtNewArray(spoon.reflect.code.CtNewArray) Metamodel(spoon.Metamodel) MatcherAssert.assertThat(org.hamcrest.MatcherAssert.assertThat) CtQuery(spoon.reflect.visitor.chain.CtQuery) TypeFilter(spoon.reflect.visitor.filter.TypeFilter) CtField(spoon.reflect.declaration.CtField) CtReference(spoon.reflect.reference.CtReference) MetamodelPropertyField(spoon.reflect.annotations.MetamodelPropertyField) SuperInheritanceHierarchyFunction(spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction) Set(java.util.Set) Assert.assertTrue(org.junit.Assert.assertTrue) Test(org.junit.Test) Factory(spoon.reflect.factory.Factory) PropertySetter(spoon.reflect.annotations.PropertySetter) Collectors(java.util.stream.Collectors) CtTypeReference(spoon.reflect.reference.CtTypeReference) List(java.util.List) CtAnnotation(spoon.reflect.declaration.CtAnnotation) AnnotationFilter(spoon.reflect.visitor.filter.AnnotationFilter) CtClass(spoon.reflect.declaration.CtClass) ModifierKind(spoon.reflect.declaration.ModifierKind) CtFieldRead(spoon.reflect.code.CtFieldRead) Assert(org.junit.Assert) Collections(java.util.Collections) PropertyGetter(spoon.reflect.annotations.PropertyGetter) CtMethod(spoon.reflect.declaration.CtMethod) ArrayList(java.util.ArrayList) Factory(spoon.reflect.factory.Factory) TypeFilter(spoon.reflect.visitor.filter.TypeFilter) CtNewArray(spoon.reflect.code.CtNewArray) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtField(spoon.reflect.declaration.CtField) PropertyGetter(spoon.reflect.annotations.PropertyGetter) ArrayList(java.util.ArrayList) List(java.util.List) SpoonAPI(spoon.SpoonAPI) SuperInheritanceHierarchyFunction(spoon.reflect.visitor.filter.SuperInheritanceHierarchyFunction) CtAnnotation(spoon.reflect.declaration.CtAnnotation) CtFieldRead(spoon.reflect.code.CtFieldRead) CtExpression(spoon.reflect.code.CtExpression) PropertySetter(spoon.reflect.annotations.PropertySetter) CtQuery(spoon.reflect.visitor.chain.CtQuery) MetamodelPropertyField(spoon.reflect.annotations.MetamodelPropertyField) CtClass(spoon.reflect.declaration.CtClass) CtType(spoon.reflect.declaration.CtType) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 30 with CtField

use of spoon.reflect.declaration.CtField in project spoon by INRIA.

the class NoClasspathTest method testInheritanceInNoClassPathWithClasses.

@Test
public void testInheritanceInNoClassPathWithClasses() throws IOException {
    // contract: when using noclasspath in combination with a source classpath
    // spoon is able to resolve the inheritance between classes contained in source cp
    String sourceInputDirPath = "./src/test/resources/spoon/test/inheritance";
    String targetBinPath = "./target/spoon-nocp-bin";
    Launcher spoon = new Launcher();
    spoon.getEnvironment().setShouldCompile(true);
    spoon.addInputResource(sourceInputDirPath);
    spoon.setBinaryOutputDirectory(targetBinPath);
    spoon.run();
    spoon = new Launcher();
    spoon.getEnvironment().setNoClasspath(true);
    spoon.getEnvironment().setSourceClasspath(new String[] { targetBinPath });
    spoon.addInputResource(sourceInputDirPath + "/AnotherClass.java");
    spoon.buildModel();
    CtType anotherclass = spoon.getFactory().Type().get("org.acme.AnotherClass");
    assertEquals(1, anotherclass.getFields().size());
    CtField field = (CtField) anotherclass.getFields().get(0);
    CtTypeReference myClassReference = spoon.getFactory().Type().createReference("fr.acme.MyClass");
    assertEquals(myClassReference, field.getType());
    assertNotNull(myClassReference.getActualClass());
    CtTypeReference myInterfaceReference = spoon.getFactory().Type().createReference("org.myorganization.MyInterface");
    assertTrue(myClassReference.isSubtypeOf(myInterfaceReference));
    assertTrue(field.getType().isSubtypeOf(myInterfaceReference));
}
Also used : CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) CtTypeReference(spoon.reflect.reference.CtTypeReference) Launcher(spoon.Launcher) Test(org.junit.Test)

Aggregations

CtField (spoon.reflect.declaration.CtField)39 Test (org.junit.Test)20 Launcher (spoon.Launcher)16 CtType (spoon.reflect.declaration.CtType)16 CtMethod (spoon.reflect.declaration.CtMethod)13 CtTypeReference (spoon.reflect.reference.CtTypeReference)12 ArrayList (java.util.ArrayList)8 CtElement (spoon.reflect.declaration.CtElement)8 CtClass (spoon.reflect.declaration.CtClass)6 CtTypeMember (spoon.reflect.declaration.CtTypeMember)6 Factory (spoon.reflect.factory.Factory)6 List (java.util.List)5 SpoonException (spoon.SpoonException)5 CtExecutable (spoon.reflect.declaration.CtExecutable)5 CtPackage (spoon.reflect.declaration.CtPackage)5 CtParameter (spoon.reflect.declaration.CtParameter)5 CtLocalVariable (spoon.reflect.code.CtLocalVariable)4 CtFieldReference (spoon.reflect.reference.CtFieldReference)4 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)4 Set (java.util.Set)3