Search in sources :

Example 56 with CtMethod

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

the class SpoonArchitectureEnforcerTest method testSrcMainJava.

// this test contains all the architectural rules that are valid for the whole src/main/java
// we put them in the same test in order to only build the full model once
@Test
public void testSrcMainJava() throws Exception {
    Launcher spoon = new Launcher();
    spoon.getEnvironment().setCommentEnabled(true);
    spoon.addInputResource("src/main/java/");
    // contract: all non-trivial public methods should be documented with proper API Javadoc
    spoon.buildModel();
    List<String> notDocumented = new ArrayList<>();
    for (CtMethod method : spoon.getModel().getElements(new TypeFilter<>(CtMethod.class))) {
        // now we see whether this should be documented
        if (// public methods should be documented
        method.hasModifier(ModifierKind.PUBLIC) && // all kinds of setters can be undocumented
        !method.getSimpleName().startsWith("get") && !method.getSimpleName().startsWith("set") && !method.getSimpleName().startsWith("is") && !method.getSimpleName().startsWith("add") && !method.getSimpleName().startsWith("remove") && // only the top declarations should be documented (not the overriding methods which are lower in the hierarchy)
        method.getTopDefinitions().size() == 0 && (// all interface methods and abstract class methods must be documented
        method.hasModifier(ModifierKind.ABSTRACT) || // 4) you commit your changes and create the corresponding pull requests
        method.filterChildren(new TypeFilter<>(CtCodeElement.class)).list().size() > // means that only large methods must be documented
        35)) {
            // is it really well documented?
            if (method.getDocComment().length() <= 15) {
                // the Javadoc must be at least at least 15 characters (still pretty short...)
                notDocumented.add(method.getParent(CtType.class).getQualifiedName() + "#" + method.getSignature());
            }
        }
    }
    if (notDocumented.size() > 0) {
        fail(notDocumented.size() + " public methods should be documented with proper API documentation: \n" + StringUtils.join(notDocumented, "\n"));
    }
    // contract: Spoon's code never uses TreeSet constructor, because they implicitly depend on Comparable (no static check, only dynamic checks)
    List<CtConstructorCall> treeSetWithoutComparators = spoon.getFactory().Package().getRootPackage().filterChildren(new AbstractFilter<CtConstructorCall>() {

        @Override
        public boolean matches(CtConstructorCall element) {
            return element.getType().getActualClass().equals(TreeSet.class) && element.getArguments().size() == 0;
        }
    }).list();
    assertEquals(0, treeSetWithoutComparators.size());
}
Also used : CtCodeElement(spoon.reflect.code.CtCodeElement) AbstractFilter(spoon.reflect.visitor.filter.AbstractFilter) CtConstructorCall(spoon.reflect.code.CtConstructorCall) TreeSet(java.util.TreeSet) ArrayList(java.util.ArrayList) Launcher(spoon.Launcher) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 57 with CtMethod

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

the class SpoonArchitectureEnforcerTest method testGoodTestClassNames.

@Test
public void testGoodTestClassNames() throws Exception {
    // contract: to be run by Maven surefire, all test classes must be called Test* or *Test
    // reference: "By default, the Surefire Plugin will automatically include all test classes with the following wildcard patterns:"
    // "**/Test*.java" and "**/*Test.java"
    // http://maven.apache.org/surefire/maven-surefire-plugin/examples/inclusion-exclusion.html
    SpoonAPI spoon = new Launcher();
    spoon.addInputResource("src/test/java/");
    spoon.buildModel();
    for (CtMethod<?> meth : spoon.getModel().getElements(new TypeFilter<CtMethod>(CtMethod.class) {

        @Override
        public boolean matches(CtMethod element) {
            return super.matches(element) && element.getAnnotation(Test.class) != null;
        }
    })) {
        assertTrue("naming contract violated for " + meth.getParent(CtClass.class).getSimpleName(), meth.getParent(CtClass.class).getSimpleName().startsWith("Test") || meth.getParent(CtClass.class).getSimpleName().endsWith("Test"));
    }
    // contract: the Spoon test suite does not depend on Junit 3 classes and methods
    // otherwise, intellij automatically selects the junit3 runner, finds nothing
    // and crashes with a dirty exception
    assertEquals(0, spoon.getModel().getElements(new TypeFilter<CtTypeReference>(CtTypeReference.class) {

        @Override
        public boolean matches(CtTypeReference element) {
            CtMethod parent = element.getParent(CtMethod.class);
            return "junit.framework.TestCase".equals(element.getQualifiedName());
        }
    }).size());
}
Also used : CtClass(spoon.reflect.declaration.CtClass) Test(org.junit.Test) CtTypeReference(spoon.reflect.reference.CtTypeReference) Launcher(spoon.Launcher) SpoonAPI(spoon.SpoonAPI) CtMethod(spoon.reflect.declaration.CtMethod) Test(org.junit.Test)

Example 58 with CtMethod

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

the class ReplaceScanner method getTypeFromTypeParameterReference.

private CtTypeReference getTypeFromTypeParameterReference(CtTypeParameterReference ctTypeParameterRef) {
    final CtMethod parentMethod = ctTypeParameterRef.getParent(CtMethod.class);
    for (CtTypeParameter formal : parentMethod.getFormalCtTypeParameters()) {
        if (formal.getSimpleName().equals(ctTypeParameterRef.getSimpleName())) {
            return ((CtTypeParameterReference) formal).getBoundingType();
        }
    }
    final CtInterface parentInterface = ctTypeParameterRef.getParent(CtInterface.class);
    for (CtTypeParameter formal : parentInterface.getFormalCtTypeParameters()) {
        if (formal.getSimpleName().equals(ctTypeParameterRef.getSimpleName())) {
            return formal.getReference().getBoundingType();
        }
    }
    throw new SpoonException("Can't get the type of the CtTypeParameterReference " + ctTypeParameterRef);
}
Also used : CtTypeParameterReference(spoon.reflect.reference.CtTypeParameterReference) CtInterface(spoon.reflect.declaration.CtInterface) CtTypeParameter(spoon.reflect.declaration.CtTypeParameter) SpoonException(spoon.SpoonException) CtMethod(spoon.reflect.declaration.CtMethod)

Example 59 with CtMethod

use of spoon.reflect.declaration.CtMethod 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)

Example 60 with CtMethod

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

the class Substitution method insertAllMethods.

/**
 * Inserts all the methods from a given template by substituting all the
 * template parameters by their values. Members annotated with
 * {@link spoon.template.Local} or {@link Parameter} are not inserted.
 *
 * @param targetType
 * 		the target type
 * @param template
 * 		the source template
 * @param sourceClass
 * 		the model of source template
 */
static void insertAllMethods(CtType<?> targetType, Template<?> template, CtClass<?> sourceClass) {
    Set<CtMethod<?>> methodsOfTemplate = sourceClass.getFactory().Type().get(Template.class).getMethods();
    // insert all the methods
    for (CtMethod<?> m : sourceClass.getMethods()) {
        if (m.getAnnotation(Local.class) != null) {
            continue;
        }
        if (m.getAnnotation(Parameter.class) != null) {
            continue;
        }
        boolean isOverridingTemplateItf = false;
        for (CtMethod m2 : methodsOfTemplate) {
            if (m.isOverriding(m2)) {
                isOverridingTemplateItf = true;
            }
        }
        if (isOverridingTemplateItf) {
            continue;
        }
        insertMethod(targetType, template, m);
    }
}
Also used : CtMethod(spoon.reflect.declaration.CtMethod)

Aggregations

CtMethod (spoon.reflect.declaration.CtMethod)240 Test (org.junit.Test)163 Factory (spoon.reflect.factory.Factory)77 Launcher (spoon.Launcher)73 CtClass (spoon.reflect.declaration.CtClass)47 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)47 CtType (spoon.reflect.declaration.CtType)45 AbstractTest (fr.inria.AbstractTest)36 ArrayList (java.util.ArrayList)35 List (java.util.List)33 CtTypeReference (spoon.reflect.reference.CtTypeReference)31 CtInvocation (spoon.reflect.code.CtInvocation)26 CtStatement (spoon.reflect.code.CtStatement)26 AmplificationHelper (fr.inria.diversify.utils.AmplificationHelper)19 Collectors (java.util.stream.Collectors)19 CtLiteral (spoon.reflect.code.CtLiteral)18 CtElement (spoon.reflect.declaration.CtElement)18 CtIf (spoon.reflect.code.CtIf)16 CtAnnotation (spoon.reflect.declaration.CtAnnotation)16 CtField (spoon.reflect.declaration.CtField)16