Search in sources :

Example 6 with CtStatementList

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

the class JDTCommentBuilder method insertCommentInAST.

/**
 * Inserts the comment into the AST.
 * @param comment the comment to insert
 */
private void insertCommentInAST(final CtComment comment) {
    CtElement commentParent = findCommentParent(comment);
    if (commentParent == null) {
        File file = spoonUnit.getFile();
        if (file != null && file.getName().equals(DefaultJavaPrettyPrinter.JAVA_PACKAGE_DECLARATION)) {
            spoonUnit.getDeclaredPackage().addComment(comment);
        } else if (file != null && file.getName().equals(DefaultJavaPrettyPrinter.JAVA_MODULE_DECLARATION)) {
            spoonUnit.getDeclaredModule().addComment(comment);
        } else {
            comment.setCommentType(CtComment.CommentType.FILE);
            addCommentToNear(comment, new ArrayList<CtElement>(spoonUnit.getDeclaredTypes()));
        }
        return;
    }
    // visitor that inserts the comment in the element
    CtInheritanceScanner insertionVisitor = new CtInheritanceScanner() {

        private boolean isScanned = false;

        @Override
        public void scan(CtElement e) {
            if (e == null) {
                return;
            }
            // Do not visit the AST, only the first element
            if (!isScanned) {
                isScanned = true;
                if (e.getPosition().getSourceStart() == comment.getPosition().getSourceStart()) {
                    e.addComment(comment);
                    return;
                }
                super.scan(e);
            }
        }

        @Override
        public <R> void visitCtStatementList(CtStatementList e) {
            addCommentToNear(comment, new ArrayList<CtElement>(e.getStatements()));
            try {
                comment.getParent();
            } catch (ParentNotInitializedException ex) {
                e.addStatement(comment);
            }
        }

        @Override
        public <T> void visitCtMethod(CtMethod<T> e) {
            e.addComment(comment);
        }

        @Override
        public <T> void visitCtConstructor(CtConstructor<T> e) {
            e.addComment(comment);
        }

        @Override
        public <T> void visitCtConditional(CtConditional<T> e) {
            List<CtElement> elements = new ArrayList<>();
            elements.add(e.getElseExpression());
            elements.add(e.getThenExpression());
            elements.add(e.getCondition());
            addCommentToNear(comment, elements);
        }

        @Override
        public <T> void visitCtBinaryOperator(CtBinaryOperator<T> e) {
            List<CtElement> elements = new ArrayList<>();
            elements.add(e.getLeftHandOperand());
            elements.add(e.getRightHandOperand());
            addCommentToNear(comment, elements);
        }

        @Override
        public <T> void visitCtClass(CtClass<T> e) {
            if (comment.getPosition().getLine() <= e.getPosition().getLine()) {
                e.addComment(comment);
                return;
            }
            final List<CtElement> elements = new ArrayList<>();
            for (CtTypeMember typeMember : e.getTypeMembers()) {
                if (typeMember instanceof CtField || typeMember instanceof CtMethod || typeMember instanceof CtConstructor) {
                    elements.add(typeMember);
                }
            }
            addCommentToNear(comment, elements);
            try {
                comment.getParent();
            } catch (ParentNotInitializedException ex) {
                e.addComment(comment);
            }
        }

        @Override
        public <T> void visitCtInterface(CtInterface<T> e) {
            final List<CtElement> elements = new ArrayList<>();
            for (CtTypeMember typeMember : e.getTypeMembers()) {
                if (typeMember instanceof CtField || typeMember instanceof CtMethod) {
                    elements.add(typeMember);
                }
            }
            addCommentToNear(comment, elements);
            try {
                comment.getParent();
            } catch (ParentNotInitializedException ex) {
                e.addComment(comment);
            }
        }

        @Override
        public <T> void visitCtField(CtField<T> e) {
            e.addComment(comment);
        }

        @Override
        public <E> void visitCtSwitch(CtSwitch<E> e) {
            List<CtCase<? super E>> cases = e.getCases();
            CtCase previous = null;
            for (int i = 0; i < cases.size(); i++) {
                CtCase<? super E> ctCase = cases.get(i);
                if (previous == null) {
                    if (comment.getPosition().getSourceStart() < ctCase.getPosition().getSourceStart() && e.getPosition().getSourceStart() < comment.getPosition().getSourceStart()) {
                        ctCase.addComment(comment);
                        return;
                    }
                } else {
                    if (previous.getPosition().getSourceEnd() < comment.getPosition().getSourceStart() && ctCase.getPosition().getSourceStart() > comment.getPosition().getSourceStart()) {
                        addCommentToNear(comment, new ArrayList<CtElement>(previous.getStatements()));
                        try {
                            comment.getParent();
                        } catch (ParentNotInitializedException ex) {
                            previous.addStatement(comment);
                        }
                        return;
                    }
                }
                previous = ctCase;
            }
            if (previous.getPosition().getSourceEnd() < comment.getPosition().getSourceStart()) {
                addCommentToNear(comment, new ArrayList<CtElement>(previous.getStatements()));
                try {
                    comment.getParent();
                } catch (ParentNotInitializedException ex) {
                    previous.addStatement(comment);
                }
                return;
            }
            try {
                comment.getParent();
            } catch (ParentNotInitializedException ex) {
                e.addComment(comment);
            }
        }

        @Override
        public void visitCtIf(CtIf e) {
            if (!(e.getThenStatement() instanceof CtBlock)) {
                if (comment.getPosition().getSourceEnd() <= e.getThenStatement().getPosition().getSourceStart()) {
                    e.getThenStatement().addComment(comment);
                    return;
                }
            }
            if (e.getElseStatement() != null) {
                SourcePosition thenPosition = e.getThenStatement().getPosition() == null ? ((CtBlock) e.getThenStatement()).getStatement(0).getPosition() : e.getThenStatement().getPosition();
                SourcePosition elsePosition = e.getElseStatement().getPosition() == null ? ((CtBlock) e.getElseStatement()).getStatement(0).getPosition() : e.getElseStatement().getPosition();
                if (comment.getPosition().getSourceStart() > thenPosition.getSourceEnd() && comment.getPosition().getSourceEnd() < elsePosition.getSourceStart()) {
                    e.getElseStatement().addComment(comment);
                }
            }
            try {
                comment.getParent();
            } catch (ParentNotInitializedException ex) {
                e.addComment(comment);
            }
        }

        @Override
        public void scanCtStatement(CtStatement s) {
            if (!(s instanceof CtStatementList || s instanceof CtSwitch)) {
                s.addComment(comment);
            }
        }

        @Override
        public void visitCtAnonymousExecutable(CtAnonymousExecutable e) {
            e.addComment(comment);
        }

        @Override
        public <T> void visitCtNewArray(CtNewArray<T> e) {
            addCommentToNear(comment, new ArrayList<CtElement>(e.getElements()));
            try {
                comment.getParent();
            } catch (ParentNotInitializedException ex) {
                e.addComment(comment);
            }
        }

        @Override
        public <T> void visitCtParameter(CtParameter<T> e) {
            e.addComment(comment);
        }

        @Override
        public void visitCtCatch(CtCatch e) {
            if (comment.getPosition().getLine() <= e.getPosition().getLine()) {
                e.addComment(comment);
                return;
            }
        }

        @Override
        public void visitCtModule(CtModule module) {
            addCommentToNear(comment, new ArrayList<>(module.getModuleDirectives()));
        }
    };
    insertionVisitor.scan(commentParent);
    try {
        comment.getParent();
    } catch (ParentNotInitializedException e) {
        LOGGER.error(comment + " is not added into the AST", e);
    }
}
Also used : CtConditional(spoon.reflect.code.CtConditional) ParentNotInitializedException(spoon.reflect.declaration.ParentNotInitializedException) CtSwitch(spoon.reflect.code.CtSwitch) ArrayList(java.util.ArrayList) CtParameter(spoon.reflect.declaration.CtParameter) CtNewArray(spoon.reflect.code.CtNewArray) CtStatement(spoon.reflect.code.CtStatement) CtField(spoon.reflect.declaration.CtField) SourcePosition(spoon.reflect.cu.SourcePosition) CtInheritanceScanner(spoon.reflect.visitor.CtInheritanceScanner) CtStatementList(spoon.reflect.code.CtStatementList) CtInterface(spoon.reflect.declaration.CtInterface) CtBinaryOperator(spoon.reflect.code.CtBinaryOperator) CtElement(spoon.reflect.declaration.CtElement) CtIf(spoon.reflect.code.CtIf) CtConstructor(spoon.reflect.declaration.CtConstructor) CtModule(spoon.reflect.declaration.CtModule) CtClass(spoon.reflect.declaration.CtClass) CtTypeMember(spoon.reflect.declaration.CtTypeMember) CtBlock(spoon.reflect.code.CtBlock) CtCase(spoon.reflect.code.CtCase) CtCatch(spoon.reflect.code.CtCatch) File(java.io.File) CtAnonymousExecutable(spoon.reflect.declaration.CtAnonymousExecutable) CtMethod(spoon.reflect.declaration.CtMethod)

Example 7 with CtStatementList

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

the class PositionBuilder method buildPositionCtElement.

SourcePosition buildPositionCtElement(CtElement e, ASTNode node) {
    CoreFactory cf = this.jdtTreeBuilder.getFactory().Core();
    CompilationUnit cu = this.jdtTreeBuilder.getFactory().CompilationUnit().getOrCreate(new String(this.jdtTreeBuilder.getContextBuilder().compilationunitdeclaration.getFileName()));
    CompilationResult cr = this.jdtTreeBuilder.getContextBuilder().compilationunitdeclaration.compilationResult;
    int[] lineSeparatorPositions = cr.lineSeparatorPositions;
    char[] contents = cr.compilationUnit.getContents();
    int sourceStart = node.sourceStart;
    int sourceEnd = node.sourceEnd;
    if ((node instanceof Annotation)) {
        Annotation ann = (Annotation) node;
        int declEnd = ann.declarationSourceEnd;
        if (declEnd > 0) {
            sourceEnd = declEnd;
        }
    } else if ((node instanceof Expression)) {
        Expression expression = (Expression) node;
        int statementEnd = expression.statementEnd;
        if (statementEnd > 0) {
            sourceEnd = statementEnd;
        }
    }
    if (node instanceof AbstractVariableDeclaration) {
        AbstractVariableDeclaration variableDeclaration = (AbstractVariableDeclaration) node;
        int modifiersSourceStart = variableDeclaration.modifiersSourceStart;
        int declarationSourceStart = variableDeclaration.declarationSourceStart;
        int declarationSourceEnd = variableDeclaration.declarationSourceEnd;
        int declarationEnd = variableDeclaration.declarationEnd;
        Annotation[] annotations = variableDeclaration.annotations;
        if (annotations != null && annotations.length > 0) {
            if (annotations[0].sourceStart() == sourceStart) {
                modifiersSourceStart = annotations[annotations.length - 1].sourceEnd() + 2;
            }
        }
        if (modifiersSourceStart == 0) {
            modifiersSourceStart = declarationSourceStart;
        }
        int modifiersSourceEnd;
        if (variableDeclaration.type != null) {
            modifiersSourceEnd = variableDeclaration.type.sourceStart() - 2;
        } else {
            // variable that has no type such as TypeParameter
            modifiersSourceEnd = declarationSourceStart - 1;
        }
        // when no modifier
        if (modifiersSourceStart > modifiersSourceEnd) {
            modifiersSourceEnd = modifiersSourceStart - 1;
        }
        return cf.createDeclarationSourcePosition(cu, sourceStart, sourceEnd, modifiersSourceStart, modifiersSourceEnd, declarationSourceStart, declarationSourceEnd, lineSeparatorPositions);
    } else if (node instanceof TypeDeclaration) {
        TypeDeclaration typeDeclaration = (TypeDeclaration) node;
        int declarationSourceStart = typeDeclaration.declarationSourceStart;
        int declarationSourceEnd = typeDeclaration.declarationSourceEnd;
        int modifiersSourceStart = typeDeclaration.modifiersSourceStart;
        int bodyStart = typeDeclaration.bodyStart;
        int bodyEnd = typeDeclaration.bodyEnd;
        Annotation[] annotations = typeDeclaration.annotations;
        if (annotations != null && annotations.length > 0) {
            if (annotations[0].sourceStart() == declarationSourceStart) {
                modifiersSourceStart = findNextNonWhitespace(contents, annotations[annotations.length - 1].declarationSourceEnd + 1);
            }
        }
        if (modifiersSourceStart == 0) {
            modifiersSourceStart = declarationSourceStart;
        }
        // look for start of first keyword before the type keyword e.g. "class". `sourceStart` points at first char of type name
        int modifiersSourceEnd = findPrevNonWhitespace(contents, findPrevWhitespace(contents, findPrevNonWhitespace(contents, sourceStart - 1)));
        if (modifiersSourceEnd < modifiersSourceStart) {
            // there is no modifier
            modifiersSourceEnd = modifiersSourceStart - 1;
        }
        return cf.createBodyHolderSourcePosition(cu, sourceStart, sourceEnd, modifiersSourceStart, modifiersSourceEnd, declarationSourceStart, declarationSourceEnd, bodyStart - 1, bodyEnd, lineSeparatorPositions);
    } else if (node instanceof AbstractMethodDeclaration) {
        AbstractMethodDeclaration methodDeclaration = (AbstractMethodDeclaration) node;
        int bodyStart = methodDeclaration.bodyStart;
        int bodyEnd = methodDeclaration.bodyEnd;
        int declarationSourceStart = methodDeclaration.declarationSourceStart;
        int declarationSourceEnd = methodDeclaration.declarationSourceEnd;
        int modifiersSourceStart = methodDeclaration.modifiersSourceStart;
        if (modifiersSourceStart == 0) {
            modifiersSourceStart = declarationSourceStart;
        }
        if (node instanceof AnnotationMethodDeclaration && bodyStart == bodyEnd) {
            // The ";" at the end of annotation method declaration is not part of body
            // let it behave same like in abstract MethodDeclaration
            bodyEnd--;
        }
        Javadoc javadoc = methodDeclaration.javadoc;
        if (javadoc != null && javadoc.sourceEnd() > declarationSourceStart) {
            modifiersSourceStart = javadoc.sourceEnd() + 1;
        }
        Annotation[] annotations = methodDeclaration.annotations;
        if (annotations != null && annotations.length > 0) {
            if (annotations[0].sourceStart() == declarationSourceStart) {
                modifiersSourceStart = annotations[annotations.length - 1].sourceEnd() + 2;
            }
        }
        int modifiersSourceEnd = sourceStart - 1;
        if (methodDeclaration instanceof MethodDeclaration && ((MethodDeclaration) methodDeclaration).returnType != null) {
            modifiersSourceEnd = ((MethodDeclaration) methodDeclaration).returnType.sourceStart() - 2;
        }
        TypeParameter[] typeParameters = methodDeclaration.typeParameters();
        if (typeParameters != null && typeParameters.length > 0) {
            modifiersSourceEnd = typeParameters[0].declarationSourceStart - 3;
        }
        if (getModifiers(methodDeclaration.modifiers, false, true).isEmpty()) {
            modifiersSourceStart = modifiersSourceEnd + 1;
        }
        sourceEnd = sourceStart + methodDeclaration.selector.length - 1;
        if (e instanceof CtStatementList) {
            return cf.createSourcePosition(cu, bodyStart - 1, bodyEnd + 1, lineSeparatorPositions);
        } else {
            if (bodyStart == 0) {
                return SourcePosition.NOPOSITION;
            } else {
                if (bodyStart < bodyEnd) {
                    // include brackets if they are there
                    if (contents[bodyStart - 1] == '{') {
                        bodyStart--;
                        if (contents[bodyEnd + 1] == '}') {
                            bodyEnd++;
                        } else {
                            throw new SpoonException("Missing body end in\n" + new String(contents, sourceStart, sourceEnd - sourceStart));
                        }
                    }
                }
                return cf.createBodyHolderSourcePosition(cu, sourceStart, sourceEnd, modifiersSourceStart, modifiersSourceEnd, declarationSourceStart, declarationSourceEnd, bodyStart, bodyEnd, lineSeparatorPositions);
            }
        }
    }
    return cf.createSourcePosition(cu, sourceStart, sourceEnd, lineSeparatorPositions);
}
Also used : CompilationUnit(spoon.reflect.cu.CompilationUnit) TypeParameter(org.eclipse.jdt.internal.compiler.ast.TypeParameter) AnnotationMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) SpoonException(spoon.SpoonException) AnnotationMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration) MethodDeclaration(org.eclipse.jdt.internal.compiler.ast.MethodDeclaration) Javadoc(org.eclipse.jdt.internal.compiler.ast.Javadoc) CoreFactory(spoon.reflect.factory.CoreFactory) AbstractVariableDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration) Annotation(org.eclipse.jdt.internal.compiler.ast.Annotation) Expression(org.eclipse.jdt.internal.compiler.ast.Expression) CtStatementList(spoon.reflect.code.CtStatementList) CompilationResult(org.eclipse.jdt.internal.compiler.CompilationResult) TypeDeclaration(org.eclipse.jdt.internal.compiler.ast.TypeDeclaration) AbstractMethodDeclaration(org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)

Example 8 with CtStatementList

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

the class CtStatementImpl method insertBefore.

/**
 * insert `statement` just before target
 */
public static void insertBefore(CtStatement target, CtStatement statement) throws ParentNotInitializedException {
    CtStatementList sts = target.getFactory().Core().createStatementList();
    sts.addStatement(statement);
    insertBefore(target, sts);
}
Also used : CtStatementList(spoon.reflect.code.CtStatementList)

Example 9 with CtStatementList

use of spoon.reflect.code.CtStatementList 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 10 with CtStatementList

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

the class TypedStatementListTemplateParameter method getSubstitution.

public CtStatementList getSubstitution(CtType<?> targetType) {
    CtClass<?> c;
    CtBlock<?> b;
    c = targetType.getFactory().Class().get(this.getClass());
    if (c == null) {
        c = targetType.getFactory().Class().get(this.getClass());
    }
    CtStatementList l = targetType.getFactory().Core().createStatementList();
    if (this instanceof Template) {
        b = Substitution.substitute(targetType, (Template<?>) this, c.getMethod("statements").getBody());
    } else {
        b = c.getMethod("statements").getBody().clone();
    }
    l.setStatements(b.getStatements());
    return l;
}
Also used : CtStatementList(spoon.reflect.code.CtStatementList)

Aggregations

CtStatementList (spoon.reflect.code.CtStatementList)11 CtStatement (spoon.reflect.code.CtStatement)5 CtElement (spoon.reflect.declaration.CtElement)4 ArrayList (java.util.ArrayList)3 CtCatch (spoon.reflect.code.CtCatch)3 CtLocalVariable (spoon.reflect.code.CtLocalVariable)3 CtField (spoon.reflect.declaration.CtField)3 CtPackage (spoon.reflect.declaration.CtPackage)3 CtType (spoon.reflect.declaration.CtType)3 CtExpression (spoon.reflect.code.CtExpression)2 CtClass (spoon.reflect.declaration.CtClass)2 CtMethod (spoon.reflect.declaration.CtMethod)2 File (java.io.File)1 List (java.util.List)1 CompilationResult (org.eclipse.jdt.internal.compiler.CompilationResult)1 AbstractMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractMethodDeclaration)1 AbstractVariableDeclaration (org.eclipse.jdt.internal.compiler.ast.AbstractVariableDeclaration)1 Annotation (org.eclipse.jdt.internal.compiler.ast.Annotation)1 AnnotationMethodDeclaration (org.eclipse.jdt.internal.compiler.ast.AnnotationMethodDeclaration)1 Expression (org.eclipse.jdt.internal.compiler.ast.Expression)1