Search in sources :

Example 1 with JCBinary

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

the class HandleCleanup method handle.

@Override
public void handle(AnnotationValues<Cleanup> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleFlagUsage(annotationNode, ConfigurationKeys.CLEANUP_FLAG_USAGE, "@Cleanup");
    if (inNetbeansEditor(annotationNode))
        return;
    deleteAnnotationIfNeccessary(annotationNode, Cleanup.class);
    String cleanupName = annotation.getInstance().value();
    if (cleanupName.length() == 0) {
        annotationNode.addError("cleanupName cannot be the empty string.");
        return;
    }
    if (annotationNode.up().getKind() != Kind.LOCAL) {
        annotationNode.addError("@Cleanup is legal only on local variable declarations.");
        return;
    }
    JCVariableDecl decl = (JCVariableDecl) annotationNode.up().get();
    if (decl.init == null) {
        annotationNode.addError("@Cleanup variable declarations need to be initialized.");
        return;
    }
    JavacNode ancestor = annotationNode.up().directUp();
    JCTree blockNode = ancestor.get();
    final List<JCStatement> statements;
    if (blockNode instanceof JCBlock) {
        statements = ((JCBlock) blockNode).stats;
    } else if (blockNode instanceof JCCase) {
        statements = ((JCCase) blockNode).stats;
    } else if (blockNode instanceof JCMethodDecl) {
        statements = ((JCMethodDecl) blockNode).body.stats;
    } else {
        annotationNode.addError("@Cleanup is legal only on a local variable declaration inside a block.");
        return;
    }
    boolean seenDeclaration = false;
    ListBuffer<JCStatement> newStatements = new ListBuffer<JCStatement>();
    ListBuffer<JCStatement> tryBlock = new ListBuffer<JCStatement>();
    for (JCStatement statement : statements) {
        if (!seenDeclaration) {
            if (statement == decl)
                seenDeclaration = true;
            newStatements.append(statement);
        } else {
            tryBlock.append(statement);
        }
    }
    if (!seenDeclaration) {
        annotationNode.addError("LOMBOK BUG: Can't find this local variable declaration inside its parent.");
        return;
    }
    doAssignmentCheck(annotationNode, tryBlock.toList(), decl.name);
    JavacTreeMaker maker = annotationNode.getTreeMaker();
    JCFieldAccess cleanupMethod = maker.Select(maker.Ident(decl.name), annotationNode.toName(cleanupName));
    List<JCStatement> cleanupCall = List.<JCStatement>of(maker.Exec(maker.Apply(List.<JCExpression>nil(), cleanupMethod, List.<JCExpression>nil())));
    JCExpression preventNullAnalysis = preventNullAnalysis(maker, annotationNode, maker.Ident(decl.name));
    JCBinary isNull = maker.Binary(CTC_NOT_EQUAL, preventNullAnalysis, maker.Literal(CTC_BOT, null));
    JCIf ifNotNullCleanup = maker.If(isNull, maker.Block(0, cleanupCall), null);
    Context context = annotationNode.getContext();
    JCBlock finalizer = recursiveSetGeneratedBy(maker.Block(0, List.<JCStatement>of(ifNotNullCleanup)), ast, context);
    newStatements.append(setGeneratedBy(maker.Try(setGeneratedBy(maker.Block(0, tryBlock.toList()), ast, context), List.<JCCatch>nil(), finalizer), ast, context));
    if (blockNode instanceof JCBlock) {
        ((JCBlock) blockNode).stats = newStatements.toList();
    } else if (blockNode instanceof JCCase) {
        ((JCCase) blockNode).stats = newStatements.toList();
    } else if (blockNode instanceof JCMethodDecl) {
        ((JCMethodDecl) blockNode).body.stats = newStatements.toList();
    } else
        throw new AssertionError("Should not get here");
    ancestor.rebuild();
}
Also used : Context(com.sun.tools.javac.util.Context) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCIf(com.sun.tools.javac.tree.JCTree.JCIf) JCCase(com.sun.tools.javac.tree.JCTree.JCCase)

Example 2 with JCBinary

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

the class HandleEqualsAndHashCode method generateCompareFloatOrDouble.

public JCStatement generateCompareFloatOrDouble(JCExpression thisDotField, JCExpression otherDotField, JavacTreeMaker maker, JavacNode node, boolean isDouble) {
    /* if (Float.compare(fieldName, other.fieldName) != 0) return false; */
    JCExpression clazz = genJavaLangTypeRef(node, isDouble ? "Double" : "Float");
    List<JCExpression> args = List.of(thisDotField, otherDotField);
    JCBinary compareCallEquals0 = maker.Binary(CTC_NOT_EQUAL, maker.Apply(List.<JCExpression>nil(), maker.Select(clazz, node.toName("compare")), args), maker.Literal(0));
    return maker.If(compareCallEquals0, returnBool(maker, false), null);
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary)

Example 3 with JCBinary

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

the class HandleGetter method createLazyGetterBody.

public List<JCStatement> createLazyGetterBody(JavacTreeMaker maker, JavacNode fieldNode, JCTree source) {
    /*
		java.lang.Object value = this.fieldName.get();
		if (value == null) {
			synchronized (this.fieldName) {
				value = this.fieldName.get();
				if (value == null) {
					final RawValueType actualValue = INITIALIZER_EXPRESSION;
					[IF PRIMITIVE]
					value = actualValue;
					[ELSE]
					value = actualValue == null ? this.fieldName : actualValue;
					[END IF]
					this.fieldName.set(value);
				}
			}
		}
		[IF PRIMITIVE]
		return (BoxedValueType) value;
		[ELSE]
		return (BoxedValueType) (value == this.fieldName ? null : value);
		[END IF]
		*/
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    JCVariableDecl field = (JCVariableDecl) fieldNode.get();
    JCExpression copyOfRawFieldType = copyType(maker, field);
    JCExpression copyOfBoxedFieldType = null;
    field.type = null;
    boolean isPrimitive = false;
    if (field.vartype instanceof JCPrimitiveTypeTree) {
        String boxed = TYPE_MAP.get(typeTag(field.vartype));
        if (boxed != null) {
            isPrimitive = true;
            field.vartype = genJavaLangTypeRef(fieldNode, boxed);
            copyOfBoxedFieldType = genJavaLangTypeRef(fieldNode, boxed);
        }
    }
    if (copyOfBoxedFieldType == null)
        copyOfBoxedFieldType = copyType(maker, field);
    Name valueName = fieldNode.toName("value");
    Name actualValueName = fieldNode.toName("actualValue");
    /* java.lang.Object value = this.fieldName.get();*/
    {
        JCExpression valueVarType = genJavaLangTypeRef(fieldNode, "Object");
        statements.append(maker.VarDef(maker.Modifiers(0), valueName, valueVarType, callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD))));
    }
    /* if (value == null) { */
    {
        JCSynchronized synchronizedStatement;
        /* synchronized (this.fieldName) { */
        {
            ListBuffer<JCStatement> synchronizedStatements = new ListBuffer<JCStatement>();
            /* value = this.fieldName.get(); */
            {
                JCExpressionStatement newAssign = maker.Exec(maker.Assign(maker.Ident(valueName), callGet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD))));
                synchronizedStatements.append(newAssign);
            }
            /* if (value == null) { */
            {
                ListBuffer<JCStatement> innerIfStatements = new ListBuffer<JCStatement>();
                /* final RawValueType actualValue = INITIALIZER_EXPRESSION; */
                {
                    innerIfStatements.append(maker.VarDef(maker.Modifiers(Flags.FINAL), actualValueName, copyOfRawFieldType, field.init));
                }
                /* [IF primitive] value = actualValue; */
                {
                    if (isPrimitive) {
                        JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), maker.Ident(actualValueName)));
                        innerIfStatements.append(statement);
                    }
                }
                /* [ELSE] value = actualValue == null ? this.fieldName : actualValue; */
                {
                    if (!isPrimitive) {
                        JCExpression actualValueIsNull = maker.Binary(CTC_EQUAL, maker.Ident(actualValueName), maker.Literal(CTC_BOT, null));
                        JCExpression thisDotFieldName = createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD);
                        JCExpression ternary = maker.Conditional(actualValueIsNull, thisDotFieldName, maker.Ident(actualValueName));
                        JCStatement statement = maker.Exec(maker.Assign(maker.Ident(valueName), ternary));
                        innerIfStatements.append(statement);
                    }
                }
                /* this.fieldName.set(value); */
                {
                    JCStatement statement = callSet(fieldNode, createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Ident(valueName));
                    innerIfStatements.append(statement);
                }
                JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null));
                JCIf ifStatement = maker.If(isNull, maker.Block(0, innerIfStatements.toList()), null);
                synchronizedStatements.append(ifStatement);
            }
            synchronizedStatement = maker.Synchronized(createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD), maker.Block(0, synchronizedStatements.toList()));
        }
        JCBinary isNull = maker.Binary(CTC_EQUAL, maker.Ident(valueName), maker.Literal(CTC_BOT, null));
        JCIf ifStatement = maker.If(isNull, maker.Block(0, List.<JCStatement>of(synchronizedStatement)), null);
        statements.append(ifStatement);
    }
    /* [IF PRIMITIVE] return (BoxedValueType) value; */
    {
        if (isPrimitive) {
            statements.append(maker.Return(maker.TypeCast(copyOfBoxedFieldType, maker.Ident(valueName))));
        }
    }
    /* [ELSE] return (BoxedValueType) (value == this.fieldName ? null : value); */
    {
        if (!isPrimitive) {
            JCExpression valueEqualsSelf = maker.Binary(CTC_EQUAL, maker.Ident(valueName), createFieldAccessor(maker, fieldNode, FieldAccess.ALWAYS_FIELD));
            JCExpression ternary = maker.Conditional(valueEqualsSelf, maker.Literal(CTC_BOT, null), maker.Ident(valueName));
            JCExpression typeCast = maker.TypeCast(copyOfBoxedFieldType, maker.Parens(ternary));
            statements.append(maker.Return(typeCast));
        }
    }
    // update the field type and init last
    /*	private final java.util.concurrent.atomic.AtomicReference<Object> fieldName = new java.util.concurrent.atomic.AtomicReference<Object>(); */
    {
        field.vartype = recursiveSetGeneratedBy(maker.TypeApply(chainDotsString(fieldNode, AR), List.<JCExpression>of(genJavaLangTypeRef(fieldNode, "Object"))), source, fieldNode.getContext());
        field.init = recursiveSetGeneratedBy(maker.NewClass(null, NIL_EXPRESSION, copyType(maker, field), NIL_EXPRESSION, null), source, fieldNode.getContext());
    }
    return statements.toList();
}
Also used : ListBuffer(com.sun.tools.javac.util.ListBuffer) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary) JCSynchronized(com.sun.tools.javac.tree.JCTree.JCSynchronized) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCIf(com.sun.tools.javac.tree.JCTree.JCIf)

Example 4 with JCBinary

use of com.sun.tools.javac.tree.JCTree.JCBinary in project error-prone by google.

the class NarrowingCompoundAssignment method rewriteCompoundAssignment.

/**
 * Desugars a compound assignment, making the cast explicit.
 */
private static Optional<Fix> rewriteCompoundAssignment(CompoundAssignmentTree tree, VisitorState state) {
    CharSequence var = state.getSourceForNode(tree.getVariable());
    CharSequence expr = state.getSourceForNode(tree.getExpression());
    if (var == null || expr == null) {
        return Optional.absent();
    }
    switch(tree.getKind()) {
        case RIGHT_SHIFT_ASSIGNMENT:
            // narrowing the result of a signed right shift does not lose information
            return Optional.absent();
        default:
            break;
    }
    Kind regularAssignmentKind = regularAssignmentFromCompound(tree.getKind());
    String op = assignmentToString(regularAssignmentKind);
    // e.g. 's -= 1 - 2' -> 's = s - (1 - 2)'
    if (tree.getExpression() instanceof JCBinary) {
        Kind rhsKind = tree.getExpression().getKind();
        if (!OperatorPrecedence.from(rhsKind).isHigher(OperatorPrecedence.from(regularAssignmentKind))) {
            expr = String.format("(%s)", expr);
        }
    }
    // e.g. 's *= 42' -> 's = (short) (s * 42)'
    String castType = getType(tree.getVariable()).toString();
    String replacement = String.format("%s = (%s) (%s %s %s)", var, castType, var, op, expr);
    return Optional.of(SuggestedFix.replace(tree, replacement));
}
Also used : Kind(com.sun.source.tree.Tree.Kind) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary)

Example 5 with JCBinary

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

the class AbstractTransformer method convertToIntForHashAttribute.

/**
 * Turn this long value into an int value by applying (int)(e ^ (e >>> 32))
 */
public JCExpression convertToIntForHashAttribute(JCExpression value) {
    SyntheticName tempName = naming.temp("hash");
    JCExpression type = make().Type(syms().longType);
    JCBinary combine = make().Binary(JCTree.BITXOR, makeUnquotedIdent(tempName.asName()), make().Binary(JCTree.USR, makeUnquotedIdent(tempName.asName()), makeInteger(32)));
    return make().TypeCast(syms().intType, makeLetExpr(tempName, null, type, value, combine));
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCBinary(com.sun.tools.javac.tree.JCTree.JCBinary)

Aggregations

JCBinary (com.sun.tools.javac.tree.JCTree.JCBinary)10 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)7 JCTree (com.sun.tools.javac.tree.JCTree)5 JCIf (com.sun.tools.javac.tree.JCTree.JCIf)4 JCAssign (com.sun.tools.javac.tree.JCTree.JCAssign)3 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)3 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)3 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)3 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)3 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)3 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)3 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)2 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)2 Type (com.redhat.ceylon.model.typechecker.model.Type)2 JCArrayAccess (com.sun.tools.javac.tree.JCTree.JCArrayAccess)2 JCAssignOp (com.sun.tools.javac.tree.JCTree.JCAssignOp)2 JCCase (com.sun.tools.javac.tree.JCTree.JCCase)2 JCCatch (com.sun.tools.javac.tree.JCTree.JCCatch)2 JCCompilationUnit (com.sun.tools.javac.tree.JCTree.JCCompilationUnit)2 JCConditional (com.sun.tools.javac.tree.JCTree.JCConditional)2