Search in sources :

Example 6 with CtField

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

the class PotentialVariableDeclarationFunction method apply.

@Override
public void apply(CtElement input, CtConsumer<Object> outputConsumer) {
    isTypeOnTheWay = false;
    isInStaticScope = false;
    // Search previous siblings for element which may represents the declaration of this local variable
    CtQuery siblingsQuery = input.getFactory().createQuery().map(new SiblingsFunction().mode(SiblingsFunction.Mode.PREVIOUS)).select(new TypeFilter<>(CtVariable.class));
    if (variableName != null) {
        // variable name is defined so we have to search only for variables with that name
        siblingsQuery = siblingsQuery.select(new NamedElementFilter<>(CtNamedElement.class, variableName));
    }
    CtElement scopeElement = input;
    // Search input and then all parents until first CtPackage for element which may represents the declaration of this local variable
    while (scopeElement != null && !(scopeElement instanceof CtPackage) && scopeElement.isParentInitialized()) {
        CtElement parent = scopeElement.getParent();
        if (parent instanceof CtType<?>) {
            isTypeOnTheWay = true;
            // visit each CtField of `parent` CtType
            CtQuery q = parent.map(new AllTypeMembersFunction(CtField.class));
            q.forEach((CtField<?> field) -> {
                if (isInStaticScope && field.hasModifier(ModifierKind.STATIC) == false) {
                    /*
						 * the variable reference is used in static scope,
						 * but the field is not static - ignore it
						 */
                    return;
                }
                // else send field as potential variable declaration
                if (sendToOutput(field, outputConsumer)) {
                    // and terminate the internal query q if outer query is already terminated
                    q.terminate();
                }
            });
            if (query.isTerminated()) {
                return;
            }
        } else if (parent instanceof CtBodyHolder || parent instanceof CtStatementList) {
            // visit all previous CtVariable siblings of scopeElement element in parent BodyHolder or Statement list
            siblingsQuery.setInput(scopeElement).forEach(outputConsumer);
            if (query.isTerminated()) {
                return;
            }
            // visit parameters of CtCatch and CtExecutable (method, lambda)
            if (parent instanceof CtCatch) {
                CtCatch ctCatch = (CtCatch) parent;
                if (sendToOutput(ctCatch.getParameter(), outputConsumer)) {
                    return;
                }
            } else if (parent instanceof CtExecutable) {
                CtExecutable<?> exec = (CtExecutable<?>) parent;
                for (CtParameter<?> param : exec.getParameters()) {
                    if (sendToOutput(param, outputConsumer)) {
                        return;
                    }
                }
            }
        }
        if (parent instanceof CtModifiable) {
            isInStaticScope = isInStaticScope || ((CtModifiable) parent).hasModifier(ModifierKind.STATIC);
        }
        scopeElement = parent;
    }
}
Also used : CtElement(spoon.reflect.declaration.CtElement) CtQuery(spoon.reflect.visitor.chain.CtQuery) CtExecutable(spoon.reflect.declaration.CtExecutable) CtBodyHolder(spoon.reflect.code.CtBodyHolder) CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) CtVariable(spoon.reflect.declaration.CtVariable) CtPackage(spoon.reflect.declaration.CtPackage) CtStatementList(spoon.reflect.code.CtStatementList) CtCatch(spoon.reflect.code.CtCatch) CtModifiable(spoon.reflect.declaration.CtModifiable)

Example 7 with CtField

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

the class CtTypeImpl method addTypeMemberAt.

@Override
public <C extends CtType<T>> C addTypeMemberAt(int position, CtTypeMember member) {
    if (member == null) {
        return (C) this;
    }
    if (this.typeMembers == CtElementImpl.<CtTypeMember>emptyList()) {
        this.typeMembers = new ArrayList<>();
    }
    if (!this.typeMembers.stream().anyMatch(m -> m == member)) {
        member.setParent(this);
        CtRole role;
        if (member instanceof CtMethod) {
            role = METHOD;
        } else if (member instanceof CtConstructor) {
            role = CONSTRUCTOR;
        } else if (member instanceof CtField) {
            role = FIELD;
        } else if (member instanceof CtAnonymousExecutable) {
            role = ANNONYMOUS_EXECUTABLE;
        } else {
            role = NESTED_TYPE;
        }
        getFactory().getEnvironment().getModelChangeListener().onListAdd(this, role, this.typeMembers, position, member);
        if (position < typeMembers.size()) {
            this.typeMembers.add(position, member);
        } else {
            this.typeMembers.add(member);
        }
    }
    return (C) this;
}
Also used : CtPackageReference(spoon.reflect.reference.CtPackageReference) Arrays(java.util.Arrays) CtRole(spoon.reflect.path.CtRole) CtType(spoon.reflect.declaration.CtType) QualifiedNameBasedSortedSet(spoon.support.util.QualifiedNameBasedSortedSet) SnippetCompilationHelper(spoon.support.compiler.SnippetCompilationHelper) CtExecutable(spoon.reflect.declaration.CtExecutable) Query(spoon.reflect.visitor.Query) ClassTypingContext(spoon.support.visitor.ClassTypingContext) CtField(spoon.reflect.declaration.CtField) CtTypeParameterReference(spoon.reflect.reference.CtTypeParameterReference) SpoonException(spoon.SpoonException) ParentNotInitializedException(spoon.reflect.declaration.ParentNotInitializedException) Collection(java.util.Collection) Set(java.util.Set) ANNONYMOUS_EXECUTABLE(spoon.reflect.path.CtRole.ANNONYMOUS_EXECUTABLE) CtModifiable(spoon.reflect.declaration.CtModifiable) AllTypeMembersFunction(spoon.reflect.visitor.filter.AllTypeMembersFunction) CtIntersectionTypeReference(spoon.reflect.reference.CtIntersectionTypeReference) NamedElementFilter(spoon.reflect.visitor.filter.NamedElementFilter) List(java.util.List) Annotation(java.lang.annotation.Annotation) CtBlock(spoon.reflect.code.CtBlock) UnsettableProperty(spoon.support.UnsettableProperty) CtFormalTypeDeclarer(spoon.reflect.declaration.CtFormalTypeDeclarer) INTERFACE(spoon.reflect.path.CtRole.INTERFACE) CtMethod(spoon.reflect.declaration.CtMethod) SignatureBasedSortedSet(spoon.support.util.SignatureBasedSortedSet) EarlyTerminatingScanner(spoon.reflect.visitor.EarlyTerminatingScanner) TYPE_TYPE_PARAMETERS_CONTAINER_DEFAULT_CAPACITY(spoon.reflect.ModelElementContainerDefaultCapacities.TYPE_TYPE_PARAMETERS_CONTAINER_DEFAULT_CAPACITY) CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtExtendedModifier(spoon.support.reflect.CtExtendedModifier) CtPackage(spoon.reflect.declaration.CtPackage) TYPE_PARAMETER(spoon.reflect.path.CtRole.TYPE_PARAMETER) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) Refactoring(spoon.refactoring.Refactoring) CtExecutableReference(spoon.reflect.reference.CtExecutableReference) CtModifierHandler(spoon.support.reflect.CtModifierHandler) CtArrayTypeReference(spoon.reflect.reference.CtArrayTypeReference) FIELD(spoon.reflect.path.CtRole.FIELD) IS_SHADOW(spoon.reflect.path.CtRole.IS_SHADOW) DerivedProperty(spoon.support.DerivedProperty) CtLineElementComparator(spoon.support.comparator.CtLineElementComparator) CtShadowable(spoon.reflect.declaration.CtShadowable) CtConstructor(spoon.reflect.declaration.CtConstructor) CONSTRUCTOR(spoon.reflect.path.CtRole.CONSTRUCTOR) MetamodelPropertyField(spoon.reflect.annotations.MetamodelPropertyField) CtAnonymousExecutable(spoon.reflect.declaration.CtAnonymousExecutable) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) ReferenceTypeFilter(spoon.reflect.visitor.filter.ReferenceTypeFilter) METHOD(spoon.reflect.path.CtRole.METHOD) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtAnnotation(spoon.reflect.declaration.CtAnnotation) CtConsumer(spoon.reflect.visitor.chain.CtConsumer) ModifierKind(spoon.reflect.declaration.ModifierKind) CtFieldReference(spoon.reflect.reference.CtFieldReference) NESTED_TYPE(spoon.reflect.path.CtRole.NESTED_TYPE) Comparator(java.util.Comparator) Collections(java.util.Collections) CtAnnotationType(spoon.reflect.declaration.CtAnnotationType) CtField(spoon.reflect.declaration.CtField) CtRole(spoon.reflect.path.CtRole) CtAnonymousExecutable(spoon.reflect.declaration.CtAnonymousExecutable) CtMethod(spoon.reflect.declaration.CtMethod) CtConstructor(spoon.reflect.declaration.CtConstructor)

Example 8 with CtField

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

the class AnnotationTest method testAnnotationTypeAndFieldOnField.

@Test
public void testAnnotationTypeAndFieldOnField() throws IOException {
    // contract: annotation on field with an annotation type which supports type and field, should be attached both on type and field
    // see: https://docs.oracle.com/javase/specs/jls/se9/html/jls-9.html#jls-9.7.3
    // in this case, we want to print it only once before the type
    final Launcher launcher = new Launcher();
    launcher.addInputResource("./src/test/java/spoon/test/annotation/testclasses/typeandfield");
    launcher.getEnvironment().setNoClasspath(true);
    launcher.setSourceOutputDirectory("./target/spooned-typeandfield");
    launcher.run();
    CtType type = launcher.getFactory().Type().get(SimpleClass.class);
    CtField field = type.getField("mandatoryField");
    assertEquals(1, field.getAnnotations().size());
    CtAnnotation annotation = field.getAnnotations().get(0);
    assertEquals("spoon.test.annotation.testclasses.typeandfield.AnnotTypeAndField", annotation.getAnnotationType().getQualifiedName());
    CtTypeReference fieldType = field.getType();
    assertEquals(1, fieldType.getAnnotations().size());
    CtAnnotation anotherAnnotation = fieldType.getAnnotations().get(0);
    assertEquals(annotation, anotherAnnotation);
    assertEquals("java.lang.String", field.getType().getQualifiedName());
    assertEquals(1, field.getType().getAnnotations().size());
    List<String> lines = Files.readAllLines(new File("./target/spooned-typeandfield/spoon/test/annotation/testclasses/typeandfield/SimpleClass.java").toPath());
    String fileContent = StringUtils.join(lines, "\n");
    assertTrue("Content :" + fileContent, fileContent.contains("@spoon.test.annotation.testclasses.typeandfield.AnnotTypeAndField"));
    assertTrue("Content :" + fileContent, fileContent.contains("public java.lang.String mandatoryField;"));
}
Also used : CtAnnotation(spoon.reflect.declaration.CtAnnotation) CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) CtTypeReference(spoon.reflect.reference.CtTypeReference) Launcher(spoon.Launcher) File(java.io.File) Test(org.junit.Test)

Example 9 with CtField

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

the class SpoonArchitectureEnforcerTest method statelessFactory.

@Test
public void statelessFactory() throws Exception {
    // the factories must be stateless
    SpoonAPI spoon = new Launcher();
    spoon.addInputResource("src/main/java/spoon/reflect/factory");
    spoon.buildModel();
    for (CtType t : spoon.getFactory().Package().getRootPackage().getElements(new AbstractFilter<CtType>() {

        @Override
        public boolean matches(CtType element) {
            return super.matches(element) && element.getSimpleName().contains("Factory");
        }
    })) {
        for (Object o : t.getFields()) {
            CtField f = (CtField) o;
            if (f.getSimpleName().equals("factory")) {
                continue;
            }
            if (f.hasModifier(ModifierKind.FINAL) || f.hasModifier(ModifierKind.TRANSIENT)) {
                continue;
            }
            fail("architectural constraint: a factory must be stateless");
        }
    }
}
Also used : CtType(spoon.reflect.declaration.CtType) CtField(spoon.reflect.declaration.CtField) Launcher(spoon.Launcher) SpoonAPI(spoon.SpoonAPI) Test(org.junit.Test)

Example 10 with CtField

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

the class ReplaceScanner method createInvocation.

private <T> CtInvocation<?> createInvocation(Factory factory, CtMethod<T> candidate, List<CtExpression<?>> invArgs, CtInvocation getter, Class getterTypeClass) {
    CtInvocation<?> invocation;
    Type type;
    if (getterTypeClass.equals(Collection.class) || getterTypeClass.equals(List.class)) {
        invocation = factory.Code().createInvocation(null, this.list, invArgs);
        type = Type.LIST;
    } else if (getterTypeClass.equals(Map.class)) {
        invocation = factory.Code().createInvocation(null, this.map, invArgs);
        type = Type.MAP;
    } else if (getterTypeClass.equals(Set.class)) {
        invocation = factory.Code().createInvocation(null, this.set, invArgs);
        type = Type.SET;
    } else {
        invocation = factory.Code().createInvocation(null, this.element, invArgs);
        type = Type.ELEMENT;
    }
    // Listener
    final String name = getter.getExecutable().getSimpleName().substring(3);
    final String listenerName = getter.getExecutable().getDeclaringType().getSimpleName() + name + "ReplaceListener";
    CtClass listener;
    if (listeners.containsKey(listenerName)) {
        listener = listeners.get(listenerName);
    } else {
        final CtTypeReference getterType = getGetterType(factory, getter);
        listener = createListenerClass(factory, listenerName, getterType, type);
        final CtMethod setter = getSetter(name, getter.getTarget().getType().getDeclaration());
        final CtField field = updateField(listener, setter.getDeclaringType().getReference());
        updateConstructor(listener, setter.getDeclaringType().getReference());
        updateSetter(factory, (CtMethod<?>) listener.getMethodsByName("set").get(0), getterType, field, setter);
        // Add auto-generated comment.
        final CtComment comment = factory.Core().createComment();
        comment.setCommentType(CtComment.CommentType.INLINE);
        comment.setContent("auto-generated, see " + ReplacementVisitorGenerator.class.getName());
        listener.addComment(comment);
        listeners.put(listenerName, listener);
    }
    invocation.addArgument(getConstructorCall(listener, factory.Code().createVariableRead(candidate.getParameters().get(0).getReference(), false)));
    return invocation;
}
Also used : CtClass(spoon.reflect.declaration.CtClass) CtComment(spoon.reflect.code.CtComment) CtType(spoon.reflect.declaration.CtType) CtTypeReference(spoon.reflect.reference.CtTypeReference) CtField(spoon.reflect.declaration.CtField) Collection(java.util.Collection) ArrayList(java.util.ArrayList) List(java.util.List) HashMap(java.util.HashMap) Map(java.util.Map) CtMethod(spoon.reflect.declaration.CtMethod)

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