Search in sources :

Example 66 with CtStatement

use of spoon.reflect.code.CtStatement in project spoon by INRIA.

the class TemplateMatcher method matchCollections.

@SuppressWarnings("unchecked")
private boolean matchCollections(Collection<?> target, Collection<?> template) {
    final List<Object> teList = new ArrayList<>(template);
    final List<Object> taList = new ArrayList<>(target);
    // inMulti keeps the multiElement templateVariable we are at
    CtElement inMulti = nextListStatement(teList, null);
    // multi keeps the values to assign to inMulti
    List<Object> multi = new ArrayList<>();
    if (null == inMulti) {
        // the sizes should then be the same
        if (teList.size() != taList.size()) {
            return false;
        }
        for (int te = 0, ta = 0; (te < teList.size()) && (ta < taList.size()); te++, ta++) {
            if (!helperMatch(taList.get(ta), teList.get(te))) {
                return false;
            }
        }
        return true;
    }
    for (int te = 0, ta = 0; (te < teList.size()) && (ta < taList.size()); te++, ta++) {
        if (isCurrentTemplate(teList.get(te), inMulti)) {
            // te index points to template parameter, which accepts multiple statements
            if (te + 1 >= teList.size()) {
                // it is the last parameter of template list. Add all remaining target list items
                multi.addAll(taList.subList(te, taList.size()));
                // create statement list and add match
                CtStatementList tpl = templateType.getFactory().Core().createStatementList();
                tpl.setStatements((List<CtStatement>) (List<?>) multi);
                if (!invokeCallBack(tpl, inMulti)) {
                    return false;
                }
                boolean ret = addMatch(inMulti, multi);
                return ret;
            }
            // there is next template parameter. Move to it
            te++;
            // adds all target list items, which are not matching to next template parameter, to the actual template parameter
            while ((te < teList.size()) && (ta < taList.size()) && !helperMatch(taList.get(ta), teList.get(te))) {
                multi.add(taList.get(ta));
                ta++;
            }
            // we have found first target parameter, which fits to next template parameter
            // create statement list for previous parameter and add it's match
            CtStatementList tpl = templateType.getFactory().Core().createStatementList();
            tpl.setStatements((List<CtStatement>) (List<?>) multi);
            if (!invokeCallBack(tpl, inMulti)) {
                return false;
            }
            addMatch(inMulti, tpl);
            // update inMulti
            inMulti = nextListStatement(teList, inMulti);
            multi = new ArrayList<>();
        } else {
            // parameter on te index is not a multivalue statement
            if (!helperMatch(taList.get(ta), teList.get(te))) {
                return false;
            }
            if (!(ta + 1 < taList.size()) && (inMulti != null)) {
                /*
					 * there is no next target item in taList,
					 * but there is still some template parameter,
					 * which expects one
					 */
                CtStatementList tpl = templateType.getFactory().Core().createStatementList();
                for (Object o : multi) {
                    tpl.addStatement((CtStatement) o);
                }
                // so it returns empty statement list
                if (!invokeCallBack(tpl, inMulti)) {
                    return false;
                }
                addMatch(inMulti, tpl);
                // update inMulti
                inMulti = nextListStatement(teList, inMulti);
                multi = new ArrayList<>();
            }
        }
    }
    return true;
}
Also used : CtStatement(spoon.reflect.code.CtStatement) CtElement(spoon.reflect.declaration.CtElement) ArrayList(java.util.ArrayList) CtStatementList(spoon.reflect.code.CtStatementList) CtStatementList(spoon.reflect.code.CtStatementList) ArrayList(java.util.ArrayList) List(java.util.List)

Example 67 with CtStatement

use of spoon.reflect.code.CtStatement in project spoon by INRIA.

the class TemplateMatcher method helperMatch.

/**
 * Detects whether `template` AST node and `target` AST node are matching.
 * This method is called for each node of to be matched template
 * and for appropriate node of `target`
 *
 * @param target actually checked AST node from target model
 * @param template actually checked AST node from template
 *
 * @return true if template matches this node, false if it does not matches
 *
 * note: Made private to hide the Objects.
 */
private boolean helperMatch(Object target, Object template) {
    if ((target == null) && (template == null)) {
        return true;
    }
    if ((target == null) || (template == null)) {
        return false;
    }
    if (containsSame(variables, template) || containsSame(typeVariables, template)) {
        /*
			 * we are just matching a template parameter.
			 * Check that defined ParameterMatcher matches the target too
			 */
        boolean add = invokeCallBack(target, template);
        if (add) {
            // ParameterMatcher matches the target too, add that match
            return addMatch(template, target);
        }
        return false;
    }
    if (target.getClass() != template.getClass()) {
        return false;
    }
    if ((template instanceof CtTypeReference) && template.equals(templateType.getReference())) {
        return true;
    }
    if ((template instanceof CtPackageReference) && template.equals(templateType.getPackage())) {
        return true;
    }
    if (template instanceof CtReference) {
        CtReference tRef = (CtReference) template;
        /*
			 * Check whether name of a template reference matches with name of target reference
			 * after replacing of variables in template name
			 */
        boolean ok = matchNames(tRef.getSimpleName(), ((CtReference) target).getSimpleName());
        if (ok && !template.equals(target)) {
            boolean remove = !invokeCallBack(target, template);
            if (remove) {
                matches.remove(tRef.getSimpleName());
                return false;
            }
            return true;
        }
    }
    if (template instanceof CtNamedElement) {
        CtNamedElement named = (CtNamedElement) template;
        boolean ok = matchNames(named.getSimpleName(), ((CtNamedElement) target).getSimpleName());
        if (ok && !template.equals(target)) {
            boolean remove = !invokeCallBack(target, template);
            if (remove) {
                matches.remove(named.getSimpleName());
                return false;
            }
        }
    }
    if (template instanceof Collection) {
        return matchCollections((Collection<?>) target, (Collection<?>) template);
    }
    if (template instanceof Map) {
        if (template.equals(target)) {
            return true;
        }
        Map<?, ?> temMap = (Map<?, ?>) template;
        Map<?, ?> tarMap = (Map<?, ?>) target;
        if (!temMap.keySet().equals(tarMap.keySet())) {
            return false;
        }
        return matchCollections(tarMap.values(), temMap.values());
    }
    if (template instanceof CtBlock<?>) {
        final List<CtStatement> statements = ((CtBlock) template).getStatements();
        if (statements.size() == 1 && statements.get(0) instanceof CtInvocation) {
            final CtInvocation ctStatement = (CtInvocation) statements.get(0);
            if ("S".equals(ctStatement.getExecutable().getSimpleName()) && CtBlock.class.equals(ctStatement.getType().getActualClass())) {
                return true;
            }
        }
    }
    if (target instanceof CtElement) {
        for (Field f : RtHelper.getAllFields(target.getClass())) {
            f.setAccessible(true);
            if (Modifier.isStatic(f.getModifiers())) {
                continue;
            }
            if (f.getName().equals("parent")) {
                continue;
            }
            if (f.getName().equals("position")) {
                continue;
            }
            if (f.getName().equals("docComment")) {
                continue;
            }
            if (f.getName().equals("factory")) {
                continue;
            }
            if (f.getName().equals("comments")) {
                continue;
            }
            if (f.getName().equals("metadata")) {
                continue;
            }
            try {
                if (!helperMatch(f.get(target), f.get(template))) {
                    return false;
                }
            } catch (IllegalAccessException ignore) {
            }
        }
        return true;
    } else if (target instanceof String) {
        return matchNames((String) template, (String) target);
    } else {
        return target.equals(template);
    }
}
Also used : CtElement(spoon.reflect.declaration.CtElement) CtField(spoon.reflect.declaration.CtField) Field(java.lang.reflect.Field) CtInvocation(spoon.reflect.code.CtInvocation) CtPackageReference(spoon.reflect.reference.CtPackageReference) CtBlock(spoon.reflect.code.CtBlock) CtReference(spoon.reflect.reference.CtReference) CtStatement(spoon.reflect.code.CtStatement) CtTypeReference(spoon.reflect.reference.CtTypeReference) Collection(java.util.Collection) CtNamedElement(spoon.reflect.declaration.CtNamedElement) HashMap(java.util.HashMap) Map(java.util.Map)

Example 68 with CtStatement

use of spoon.reflect.code.CtStatement in project spoon by INRIA.

the class VisitorPartialEvaluator method visitCtBlock.

public <R> void visitCtBlock(CtBlock<R> block) {
    CtBlock<?> b = block.getFactory().Core().createBlock();
    for (CtStatement s : block.getStatements()) {
        CtElement res = evaluate(s);
        if (res != null) {
            if (res instanceof CtStatement) {
                b.addStatement((CtStatement) res);
            } else {
                // the context expectes statement. We cannot simplify in this case
                b.addStatement(s);
            }
        }
        // do not copy unreachable statements
        if (flowEnded) {
            break;
        }
    }
    setResult(b);
}
Also used : CtStatement(spoon.reflect.code.CtStatement) CtElement(spoon.reflect.declaration.CtElement)

Example 69 with CtStatement

use of spoon.reflect.code.CtStatement in project spoon by INRIA.

the class TemplateClassAccessTest method testClassAccessTest.

@Test
public void testClassAccessTest() throws Exception {
    // contract: the template engine supports class access substitution
    Launcher spoon = new Launcher();
    spoon.addTemplateResource(new FileSystemFile("./src/test/java/spoon/test/template/testclasses/ClassAccessTemplate.java"));
    spoon.buildModel();
    Factory factory = spoon.getFactory();
    CtClass<?> resultKlass = factory.Class().create("Result");
    CtStatement result = new ClassAccessTemplate(String.class).apply(resultKlass);
    assertEquals("java.lang.String.class.getName()", result.toString());
    // I do not know if it makes sense to use null. But this kind of null handling is probably the best
    CtStatement result2 = new ClassAccessTemplate(null).apply(resultKlass);
    assertEquals("null.getName()", result2.toString());
}
Also used : CtStatement(spoon.reflect.code.CtStatement) ClassAccessTemplate(spoon.test.template.testclasses.ClassAccessTemplate) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) FileSystemFile(spoon.support.compiler.FileSystemFile) Test(org.junit.Test)

Example 70 with CtStatement

use of spoon.reflect.code.CtStatement in project spoon by INRIA.

the class TemplateArrayAccessTest method testArrayAccess.

@Test
public void testArrayAccess() throws Exception {
    // contract: the template engine supports variable access, typed as Array substitution
    Launcher spoon = new Launcher();
    spoon.addTemplateResource(new FileSystemFile("./src/test/java/spoon/test/template/testclasses/SubstituteArrayAccessTemplate.java"));
    spoon.buildModel();
    Factory factory = spoon.getFactory();
    CtClass<?> resultKlass = factory.Class().create("Result");
    CtStatement result = new SubstituteArrayAccessTemplate(new String[] { "a", null, "b" }).apply(resultKlass);
    assertEquals("new java.lang.String[]{ \"a\", null, \"b\" }.toString()", result.toString());
}
Also used : CtStatement(spoon.reflect.code.CtStatement) Launcher(spoon.Launcher) Factory(spoon.reflect.factory.Factory) FileSystemFile(spoon.support.compiler.FileSystemFile) SubstituteArrayAccessTemplate(spoon.test.template.testclasses.SubstituteArrayAccessTemplate) Test(org.junit.Test)

Aggregations

CtStatement (spoon.reflect.code.CtStatement)84 Test (org.junit.Test)55 Factory (spoon.reflect.factory.Factory)35 CtMethod (spoon.reflect.declaration.CtMethod)23 Launcher (spoon.Launcher)20 CtBlock (spoon.reflect.code.CtBlock)17 CtIf (spoon.reflect.code.CtIf)11 CtExpression (spoon.reflect.code.CtExpression)10 ArrayList (java.util.ArrayList)9 CtElement (spoon.reflect.declaration.CtElement)9 TypeFilter (spoon.reflect.visitor.filter.TypeFilter)9 CtInvocation (spoon.reflect.code.CtInvocation)8 CtTypeReference (spoon.reflect.reference.CtTypeReference)7 CtCase (spoon.reflect.code.CtCase)6 CtStatementList (spoon.reflect.code.CtStatementList)6 STATEMENT (spoon.reflect.path.CtRole.STATEMENT)6 FileSystemFile (spoon.support.compiler.FileSystemFile)6 Adobada (spoon.test.delete.testclasses.Adobada)6 CtCodeSnippetStatement (spoon.reflect.code.CtCodeSnippetStatement)5 CtLocalVariable (spoon.reflect.code.CtLocalVariable)5