Search in sources :

Example 6 with JCAssign

use of com.sun.tools.javac.tree.JCTree.JCAssign in project ceylon-compiler by ceylon.

the class StatementTransformer method transform.

public JCStatement transform(Tree.TryCatchStatement t) {
    Tree.TryClause tryClause = t.getTryClause();
    at(tryClause);
    JCBlock tryBlock = transform(tryClause.getBlock());
    Tree.ResourceList resList = tryClause.getResourceList();
    if (resList != null) {
        ArrayList<Tree.Resource> resources = new ArrayList<Tree.Resource>(resList.getResources());
        Collections.reverse(resources);
        for (Tree.Resource res : resources) {
            List<JCStatement> stats = List.nil();
            Tree.Expression resExpr;
            String resVarName;
            if (res.getExpression() != null) {
                resExpr = res.getExpression();
                resVarName = naming.newTemp("try");
            } else if (res.getVariable() != null) {
                Tree.Variable var = res.getVariable();
                resExpr = var.getSpecifierExpression().getExpression();
                resVarName = var.getIdentifier().getText();
            } else {
                throw new BugException(res, "missing resource expression");
            }
            boolean isDestroyable = typeFact().getDestroyableType().isSupertypeOf(resExpr.getTypeModel());
            Type resVarType = resExpr.getTypeModel();
            Type resVarExpectedType = isDestroyable ? typeFact().getDestroyableType() : typeFact().getObtainableType();
            // CloseableType $var = resource-expression
            JCExpression expr = expressionGen().transformExpression(resExpr);
            JCExpression javaType = makeJavaType(resVarType);
            JCVariableDecl var = makeVar(FINAL, resVarName, javaType, expr);
            stats = stats.append(var);
            if (!isDestroyable) {
                JCExpression resVar0 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
                JCMethodInvocation openCall = make().Apply(null, makeQualIdent(resVar0, "obtain"), List.<JCExpression>nil());
                stats = stats.append(make().Exec(openCall));
            }
            // Exception $tpmex = null;
            String innerExTmpVarName = naming.newTemp("ex");
            JCExpression innerExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl innerExTmpVar = makeVar(innerExTmpVarName, innerExType, makeNull());
            stats = stats.append(innerExTmpVar);
            // $tmpex = ex;
            List<JCStatement> innerCatchStats = List.nil();
            Name innerCatchVarName = naming.tempName("ex");
            JCAssign exTmpAssign = make().Assign(makeUnquotedIdent(innerExTmpVarName), make().Ident(innerCatchVarName));
            innerCatchStats = innerCatchStats.append(make().Exec(exTmpAssign));
            // throw ex;
            JCThrow innerCatchThrow = make().Throw(make().Ident(innerCatchVarName));
            innerCatchStats = innerCatchStats.append(innerCatchThrow);
            JCBlock innerCatchBlock = make().Block(0, innerCatchStats);
            // $var.close() /// ((Closeable)$var).close()
            JCExpression exarg = makeUnquotedIdent(innerExTmpVarName);
            JCExpression resVar1 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
            JCMethodInvocation closeCall = make().Apply(null, makeQualIdent(resVar1, isDestroyable ? "destroy" : "release"), List.<JCExpression>of(exarg));
            JCBlock closeTryBlock = make().Block(0, List.<JCStatement>of(make().Exec(closeCall)));
            // try { $var.close() } catch (Exception closex) { $tmpex.addSuppressed(closex); }
            Name closeCatchVarName = naming.tempName("closex");
            JCExpression closeCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl closeCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), closeCatchVarName, closeCatchExType, null);
            JCExpression addarg = make().Ident(closeCatchVarName);
            JCMethodInvocation addSuppressedCall = make().Apply(null, makeQualIdent(makeUnquotedIdent(innerExTmpVarName), "addSuppressed"), List.<JCExpression>of(addarg));
            JCCatch closeCatch = make().Catch(closeCatchVar, make().Block(0, List.<JCStatement>of(make().Exec(addSuppressedCall))));
            JCTry closeTry = at(res).Try(closeTryBlock, List.<JCCatch>of(closeCatch), null);
            // $var.close() /// ((Closeable)$var).close()
            JCExpression exarg2 = makeUnquotedIdent(innerExTmpVarName);
            JCExpression resVar2 = expressionGen().applyErasureAndBoxing(makeUnquotedIdent(resVarName), resVarType, true, BoxingStrategy.BOXED, resVarExpectedType);
            JCMethodInvocation closeCall2 = make().Apply(null, makeQualIdent(resVar2, isDestroyable ? "destroy" : "release"), List.<JCExpression>of(exarg2));
            // if ($tmpex != null) { ... } else { ... }
            JCBinary closeCatchCond = make().Binary(JCTree.NE, makeUnquotedIdent(innerExTmpVarName), makeNull());
            JCIf closeCatchIf = make().If(closeCatchCond, closeTry, make().Exec(closeCall2));
            // try { .... } catch (Exception ex) { $tmpex=ex; throw ex; }
            // finally { try { $var.close() } catch (Exception closex) { } }
            JCExpression innerCatchExType = makeJavaType(typeFact().getThrowableType(), JT_CATCH);
            JCVariableDecl innerCatchVar = make().VarDef(make().Modifiers(Flags.FINAL), innerCatchVarName, innerCatchExType, null);
            JCCatch innerCatch = make().Catch(innerCatchVar, innerCatchBlock);
            JCBlock innerFinallyBlock = make().Block(0, List.<JCStatement>of(closeCatchIf));
            JCTry innerTry = at(res).Try(tryBlock, List.<JCCatch>of(innerCatch), innerFinallyBlock);
            stats = stats.append(innerTry);
            tryBlock = at(res).Block(0, stats);
        }
    }
    final List<JCCatch> catches;
    if (usePolymorphicCatches(t.getCatchClauses())) {
        catches = transformCatchesPolymorphic(t.getCatchClauses());
    } else {
        catches = transformCatchesIfElseIf(t.getCatchClauses());
    }
    final JCBlock finallyBlock;
    Tree.FinallyClause finallyClause = t.getFinallyClause();
    if (finallyClause != null) {
        at(finallyClause);
        finallyBlock = transform(finallyClause.getBlock());
    } else {
        finallyBlock = null;
    }
    if (!catches.isEmpty() || finallyBlock != null) {
        return at(t).Try(tryBlock, catches, finallyBlock);
    } else {
        return tryBlock;
    }
}
Also used : Variable(com.redhat.ceylon.compiler.typechecker.tree.Tree.Variable) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ArrayList(java.util.ArrayList) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) CName(com.redhat.ceylon.compiler.java.codegen.Naming.CName) Name(com.sun.tools.javac.util.Name) OptionName(com.sun.tools.javac.main.OptionName) JCIf(com.sun.tools.javac.tree.JCTree.JCIf) Expression(com.redhat.ceylon.compiler.typechecker.tree.Tree.Expression) CustomTree(com.redhat.ceylon.compiler.typechecker.tree.CustomTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) JCThrow(com.sun.tools.javac.tree.JCTree.JCThrow) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCTry(com.sun.tools.javac.tree.JCTree.JCTry) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCCatch(com.sun.tools.javac.tree.JCTree.JCCatch)

Example 7 with JCAssign

use of com.sun.tools.javac.tree.JCTree.JCAssign in project robolectric by robolectric.

the class RobolectricShadow method matchClass.

@Override
public Description matchClass(ClassTree classTree, VisitorState state) {
    List<Optional<SuggestedFix>> fixes = new ArrayList<>();
    if (implementsClassMatcher.matches(classTree, state)) {
        boolean inSdk = true;
        JavacTrees trees = JavacTrees.instance(state.context);
        for (AnnotationTree annotationTree : classTree.getModifiers().getAnnotations()) {
            JCIdent ident = (JCIdent) annotationTree.getAnnotationType();
            String annotationClassName = ident.sym.getQualifiedName().toString();
            if ("org.robolectric.annotation.Implements".equals(annotationClassName)) {
                for (ExpressionTree expressionTree : annotationTree.getArguments()) {
                    JCAssign jcAnnotation = (JCAssign) expressionTree;
                    if ("isInAndroidSdk".equals(state.getSourceForNode(jcAnnotation.lhs)) && "false".equals(state.getSourceForNode(jcAnnotation.rhs))) {
                        // shadows of classes not in the public Android SDK can keep their public methods.
                        inSdk = false;
                    }
                }
            }
        }
        if (inSdk) {
            new ImplementationMethodScanner(state, fixes, trees).scan(state.getPath(), null);
        }
    }
    SuggestedFix.Builder builder = SuggestedFix.builder();
    for (Optional<SuggestedFix> fix : fixes) {
        fix.ifPresent(builder::merge);
    }
    if (builder.isEmpty()) {
        return Description.NO_MATCH;
    } else {
        return describeMatch(classTree, builder.build());
    }
}
Also used : JavacTrees(com.sun.tools.javac.api.JavacTrees) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) Optional(java.util.Optional) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ArrayList(java.util.ArrayList) AnnotationTree(com.sun.source.tree.AnnotationTree) SuggestedFix(com.google.errorprone.fixes.SuggestedFix) ExpressionTree(com.sun.source.tree.ExpressionTree)

Example 8 with JCAssign

use of com.sun.tools.javac.tree.JCTree.JCAssign in project lombok by rzwitserloot.

the class JavacHandlerUtil method unboxAndRemoveAnnotationParameter.

static List<JCAnnotation> unboxAndRemoveAnnotationParameter(JCAnnotation ast, String parameterName, String errorName, JavacNode annotationNode) {
    ListBuffer<JCExpression> params = new ListBuffer<JCExpression>();
    ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
    outer: for (JCExpression param : ast.args) {
        boolean allowRaw;
        String nameOfParam = "value";
        JCExpression valueOfParam = null;
        if (param instanceof JCAssign) {
            JCAssign assign = (JCAssign) param;
            if (assign.lhs instanceof JCIdent) {
                JCIdent ident = (JCIdent) assign.lhs;
                nameOfParam = ident.name.toString();
            }
            valueOfParam = assign.rhs;
        }
        /* strip trailing underscores */
        {
            int lastIdx;
            for (lastIdx = nameOfParam.length(); lastIdx > 0; lastIdx--) {
                if (nameOfParam.charAt(lastIdx - 1) != '_')
                    break;
            }
            allowRaw = lastIdx < nameOfParam.length();
            nameOfParam = nameOfParam.substring(0, lastIdx);
        }
        if (!parameterName.equals(nameOfParam)) {
            params.append(param);
            continue outer;
        }
        int endPos = Javac.getEndPosition(param.pos(), (JCCompilationUnit) annotationNode.top().get());
        annotationNode.getAst().removeFromDeferredDiagnostics(param.pos, endPos);
        if (valueOfParam instanceof JCAnnotation) {
            String dummyAnnotationName = ((JCAnnotation) valueOfParam).annotationType.toString();
            dummyAnnotationName = dummyAnnotationName.replace("_", "").replace("$", "").replace("x", "").replace("X", "");
            if (dummyAnnotationName.length() > 0) {
                if (allowRaw) {
                    result.append((JCAnnotation) valueOfParam);
                } else {
                    addError(errorName, annotationNode);
                    continue outer;
                }
            } else {
                for (JCExpression expr : ((JCAnnotation) valueOfParam).args) {
                    if (expr instanceof JCAssign && ((JCAssign) expr).lhs instanceof JCIdent) {
                        JCIdent id = (JCIdent) ((JCAssign) expr).lhs;
                        if ("value".equals(id.name.toString())) {
                            expr = ((JCAssign) expr).rhs;
                        } else {
                            addError(errorName, annotationNode);
                        }
                    }
                    if (expr instanceof JCAnnotation) {
                        result.append((JCAnnotation) expr);
                    } else if (expr instanceof JCNewArray) {
                        for (JCExpression expr2 : ((JCNewArray) expr).elems) {
                            if (expr2 instanceof JCAnnotation) {
                                result.append((JCAnnotation) expr2);
                            } else {
                                addError(errorName, annotationNode);
                                continue outer;
                            }
                        }
                    } else {
                        addError(errorName, annotationNode);
                        continue outer;
                    }
                }
            }
        } else if (valueOfParam instanceof JCNewArray) {
            JCNewArray arr = (JCNewArray) valueOfParam;
            if (arr.elems.isEmpty()) {
            // Just remove it, this is always fine.
            } else if (allowRaw) {
                for (JCExpression jce : arr.elems) {
                    if (jce instanceof JCAnnotation)
                        result.append((JCAnnotation) jce);
                    else
                        addError(errorName, annotationNode);
                }
            } else {
                addError(errorName, annotationNode);
            }
        } else {
            addError(errorName, annotationNode);
        }
    }
    ast.args = params.toList();
    return result.toList();
}
Also used : JCCompilationUnit(com.sun.tools.javac.tree.JCTree.JCCompilationUnit) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 9 with JCAssign

use of com.sun.tools.javac.tree.JCTree.JCAssign in project lombok by rzwitserloot.

the class JavacHandlerUtil method addAnnotation.

private static void addAnnotation(JCModifiers mods, JavacNode node, int pos, JCTree source, Context context, String annotationTypeFqn, JCExpression arg) {
    boolean isJavaLangBased;
    String simpleName;
    {
        int idx = annotationTypeFqn.lastIndexOf('.');
        simpleName = idx == -1 ? annotationTypeFqn : annotationTypeFqn.substring(idx + 1);
        isJavaLangBased = idx == 9 && annotationTypeFqn.regionMatches(0, "java.lang.", 0, 10);
    }
    for (JCAnnotation ann : mods.annotations) {
        JCTree annType = ann.getAnnotationType();
        if (annType instanceof JCIdent) {
            Name lastPart = ((JCIdent) annType).name;
            if (lastPart.contentEquals(simpleName))
                return;
        }
        if (annType instanceof JCFieldAccess) {
            if (annType.toString().equals(annotationTypeFqn))
                return;
        }
    }
    JavacTreeMaker maker = node.getTreeMaker();
    JCExpression annType = isJavaLangBased ? genJavaLangTypeRef(node, simpleName) : chainDotsString(node, annotationTypeFqn);
    annType.pos = pos;
    if (arg != null) {
        arg.pos = pos;
        if (arg instanceof JCAssign) {
            ((JCAssign) arg).lhs.pos = pos;
            ((JCAssign) arg).rhs.pos = pos;
        }
    }
    List<JCExpression> argList = arg != null ? List.of(arg) : List.<JCExpression>nil();
    JCAnnotation annotation = recursiveSetGeneratedBy(maker.Annotation(annType, argList), source, context);
    annotation.pos = pos;
    mods.annotations = mods.annotations.append(annotation);
}
Also used : JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) JCTree(com.sun.tools.javac.tree.JCTree) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) Name(com.sun.tools.javac.util.Name)

Example 10 with JCAssign

use of com.sun.tools.javac.tree.JCTree.JCAssign in project lombok by rzwitserloot.

the class JavacHandlerUtil method createAnnotation.

/**
 * Creates an instance of {@code AnnotationValues} for the provided AST Node.
 *
 * @param type An annotation class type, such as {@code lombok.Getter.class}.
 * @param node A Lombok AST node representing an annotation in source code.
 */
public static <A extends Annotation> AnnotationValues<A> createAnnotation(Class<A> type, final JavacNode node) {
    Map<String, AnnotationValue> values = new HashMap<String, AnnotationValue>();
    JCAnnotation anno = (JCAnnotation) node.get();
    List<JCExpression> arguments = anno.getArguments();
    for (JCExpression arg : arguments) {
        String mName;
        JCExpression rhs;
        java.util.List<String> raws = new ArrayList<String>();
        java.util.List<Object> guesses = new ArrayList<Object>();
        java.util.List<Object> expressions = new ArrayList<Object>();
        final java.util.List<DiagnosticPosition> positions = new ArrayList<DiagnosticPosition>();
        if (arg instanceof JCAssign) {
            JCAssign assign = (JCAssign) arg;
            mName = assign.lhs.toString();
            rhs = assign.rhs;
        } else {
            rhs = arg;
            mName = "value";
        }
        if (rhs instanceof JCNewArray) {
            List<JCExpression> elems = ((JCNewArray) rhs).elems;
            for (JCExpression inner : elems) {
                raws.add(inner.toString());
                expressions.add(inner);
                guesses.add(calculateGuess(inner));
                positions.add(inner.pos());
            }
        } else {
            raws.add(rhs.toString());
            expressions.add(rhs);
            guesses.add(calculateGuess(rhs));
            positions.add(rhs.pos());
        }
        values.put(mName, new AnnotationValue(node, raws, expressions, guesses, true) {

            @Override
            public void setError(String message, int valueIdx) {
                if (valueIdx < 0)
                    node.addError(message);
                else
                    node.addError(message, positions.get(valueIdx));
            }

            @Override
            public void setWarning(String message, int valueIdx) {
                if (valueIdx < 0)
                    node.addWarning(message);
                else
                    node.addWarning(message, positions.get(valueIdx));
            }
        });
    }
    for (Method m : type.getDeclaredMethods()) {
        if (!Modifier.isPublic(m.getModifiers()))
            continue;
        String name = m.getName();
        if (!values.containsKey(name)) {
            values.put(name, new AnnotationValue(node, new ArrayList<String>(), new ArrayList<Object>(), new ArrayList<Object>(), false) {

                @Override
                public void setError(String message, int valueIdx) {
                    node.addError(message);
                }

                @Override
                public void setWarning(String message, int valueIdx) {
                    node.addWarning(message);
                }
            });
        }
    }
    return new AnnotationValues<A>(type, values, node);
}
Also used : HashMap(java.util.HashMap) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ArrayList(java.util.ArrayList) Method(java.lang.reflect.Method) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) DiagnosticPosition(com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition) AnnotationValues(lombok.core.AnnotationValues) AnnotationValue(lombok.core.AnnotationValues.AnnotationValue) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

JCAssign (com.sun.tools.javac.tree.JCTree.JCAssign)14 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)8 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)8 JCIdent (com.sun.tools.javac.tree.JCTree.JCIdent)6 Name (com.sun.tools.javac.util.Name)5 JCTree (com.sun.tools.javac.tree.JCTree)4 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)4 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)4 JCBinary (com.sun.tools.javac.tree.JCTree.JCBinary)3 JCCompilationUnit (com.sun.tools.javac.tree.JCTree.JCCompilationUnit)3 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)3 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)3 JCNewArray (com.sun.tools.javac.tree.JCTree.JCNewArray)3 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)3 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)3 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)2 AnnotationTree (com.sun.source.tree.AnnotationTree)2 ExpressionTree (com.sun.source.tree.ExpressionTree)2 Symbol (com.sun.tools.javac.code.Symbol)2 JCArrayAccess (com.sun.tools.javac.tree.JCTree.JCArrayAccess)2