Search in sources :

Example 1 with JCExpressionStatement

use of com.sun.tools.javac.tree.JCTree.JCExpressionStatement 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 2 with JCExpressionStatement

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

the class DoubleCheckedLocking method handleLocal.

/**
 * Report a diagnostic for an instance of DCL on a local variable. A match is only reported if a
 * non-volatile field is written to the variable after acquiring the lock and before the second
 * null-check on the local.
 *
 * <p>e.g.
 *
 * <pre>{@code
 * if ($X == null) {
 *   synchronized (...) {
 *     $X = myNonVolatileField;
 *     if ($X == null) {
 *       ...
 *     }
 *     ...
 *   }
 * }
 * }</pre>
 */
private Description handleLocal(DCLInfo info, VisitorState state) {
    JCExpressionStatement expr = getChild(info.synchTree().getBlock(), JCExpressionStatement.class);
    if (expr == null) {
        return Description.NO_MATCH;
    }
    if (expr.getStartPosition() > ((JCTree) info.innerIf()).getStartPosition()) {
        return Description.NO_MATCH;
    }
    if (!(expr.getExpression() instanceof JCAssign)) {
        return Description.NO_MATCH;
    }
    JCAssign assign = (JCAssign) expr.getExpression();
    if (!Objects.equals(ASTHelpers.getSymbol(assign.getVariable()), info.sym())) {
        return Description.NO_MATCH;
    }
    Symbol sym = ASTHelpers.getSymbol(assign.getExpression());
    if (!(sym instanceof VarSymbol)) {
        return Description.NO_MATCH;
    }
    VarSymbol fvar = (VarSymbol) sym;
    if (fvar.getKind() != ElementKind.FIELD) {
        return Description.NO_MATCH;
    }
    return handleField(info.outerIf(), fvar, state);
}
Also used : JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) Symbol(com.sun.tools.javac.code.Symbol) VarSymbol(com.sun.tools.javac.code.Symbol.VarSymbol) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement)

Example 3 with JCExpressionStatement

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

the class AttributeDefinitionBuilder method generateDefaultSetterBlock.

public JCTree.JCBlock generateDefaultSetterBlock() {
    JCExpression fld = fld();
    JCExpressionStatement assign = owner.make().Exec(owner.make().Assign(fld, owner.makeQuotedIdent(attrName)));
    List<JCStatement> stmts = List.<JCTree.JCStatement>of(assign);
    if (late) {
        JCExpressionStatement makeInit = null;
        if (lateWithInit)
            makeInit = owner.make().Exec(owner.make().Assign(makeInitFlagExpr(true), owner.make().Literal(true)));
        if (variable) {
            if (makeInit != null)
                stmts = List.<JCStatement>of(assign, makeInit);
        // else stmts is already assign
        } else {
            List<JCStatement> then = List.<JCStatement>of(owner.make().Return(null));
            if (makeInit != null)
                then = then.prepend(makeInit);
            then = then.prepend(assign);
            stmts = List.of(owner.make().If(makeInitFlagExpr(false), owner.make().Block(0, then), null), owner.make().Throw(owner.makeNewClass(owner.make().Type(owner.syms().ceylonInitializationErrorType), List.<JCExpression>of(owner.make().Literal("Re-initialization of 'late' attribute")))));
        }
    }
    if (hasInitFlag() && isDeferredInitError()) {
        JCStatement rethrow = owner.make().Exec(owner.utilInvocation().rethrow(owner.makeUnquotedIdent(Naming.getToplevelAttributeSavedExceptionName())));
        // rethrow the init exception if we have one
        JCIf ifThrow = owner.make().If(owner.make().Binary(JCTree.NE, owner.makeUnquotedIdent(Naming.getToplevelAttributeSavedExceptionName()), owner.makeNull()), rethrow, null);
        stmts = stmts.prepend(ifThrow);
    }
    return owner.make().Block(0L, stmts);
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCIf(com.sun.tools.javac.tree.JCTree.JCIf) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement)

Example 4 with JCExpressionStatement

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

the class ClassTransformer method serializationReferences.

/**
 * <p>Generates the {@code $deserialize$()} method to deserialize
 * the classes state, which:</p>
 * <ul>
 * <li>invokes {@code super.$deserialize$()}, if the super class is also
 *     serializable,</li>
 * <li>assigns each reified type argument in the
 *     class by invoking {@code dted.getTypeArgument()},</li>
 * <li>assigns each field in the
 *     class by invoking {@code dted.getValue()}.</li>
 * </ul>
 */
private void serializationReferences(Class model, ClassDefinitionBuilder classBuilder) {
    MethodDefinitionBuilder mdb = MethodDefinitionBuilder.systemMethod(this, Unfix.$references$.toString());
    mdb.isOverride(true);
    mdb.ignoreModelAnnotations();
    mdb.modifiers(PUBLIC);
    mdb.resultType(null, make().TypeApply(naming.makeQuotedFQIdent("java.util.Collection"), List.<JCExpression>of(make().Type(syms().ceylonReachableReferenceType))));
    ListBuffer<JCStatement> stmts = ListBuffer.lb();
    // TODO this is all static information, but the method itself needs to be
    // callable virtually, so we should cache it somehow.
    SyntheticName r = naming.synthetic(Unfix.reference);
    if (extendsSerializable(model)) {
        // prepend the invocation of super.$serialize$()
        stmts.add(makeVar(r, make().TypeApply(naming.makeQuotedFQIdent("java.util.Collection"), List.<JCExpression>of(make().Type(syms().ceylonReachableReferenceType))), make().Apply(null, naming.makeQualIdent(naming.makeSuper(), Unfix.$references$.toString()), List.<JCExpression>nil())));
    } else {
        stmts.add(makeVar(r, make().TypeApply(naming.makeQuotedFQIdent("java.util.Collection"), List.<JCExpression>of(make().Type(syms().ceylonReachableReferenceType))), make().NewClass(null, null, make().TypeApply(naming.makeQuotedFQIdent("java.util.ArrayList"), List.<JCExpression>of(make().Type(syms().ceylonReachableReferenceType))), List.<JCExpression>nil(), null)));
    }
    if (model.isMember()) {
        JCExpressionStatement outer = make().Exec(make().Apply(null, naming.makeQualIdent(r.makeIdent(), "add"), List.<JCExpression>of(make().Apply(null, naming.makeQualIdent(make().Type(syms().ceylonOuterImplType), "get_"), List.<JCExpression>nil()))));
        stmts.add(outer);
    }
    for (Declaration member : model.getMembers()) {
        if (hasField(member)) {
            // Obtain a ValueDeclaration
            JCExpression valueDeclaration = expressionGen().makeMemberValueOrFunctionDeclarationLiteral(null, member, false);
            // Create a MemberImpl
            JCExpression mi = make().NewClass(null, null, make().QualIdent(syms().ceylonMemberImplType.tsym), List.of(valueDeclaration), null);
            JCExpressionStatement attribute = make().Exec(make().Apply(null, naming.makeQualIdent(r.makeIdent(), "add"), List.of(mi)));
            stmts.add(attribute);
        }
    }
    stmts.add(make().Return(r.makeIdent()));
    mdb.body(stmts.toList());
    classBuilder.method(mdb);
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement)

Example 5 with JCExpressionStatement

use of com.sun.tools.javac.tree.JCTree.JCExpressionStatement in project bazel by bazelbuild.

the class TreePruner method delegatingConstructor.

private static boolean delegatingConstructor(List<JCStatement> stats) {
    if (stats.isEmpty()) {
        return false;
    }
    JCStatement stat = stats.get(0);
    if (stat.getKind() != Kind.EXPRESSION_STATEMENT) {
        return false;
    }
    JCExpression expr = ((JCExpressionStatement) stat).getExpression();
    if (expr.getKind() != Kind.METHOD_INVOCATION) {
        return false;
    }
    JCExpression method = ((JCMethodInvocation) expr).getMethodSelect();
    Name name;
    switch(method.getKind()) {
        case IDENTIFIER:
            name = ((JCIdent) method).getName();
            break;
        case MEMBER_SELECT:
            name = ((JCFieldAccess) method).getIdentifier();
            break;
        default:
            return false;
    }
    return name.contentEquals("this") || name.contentEquals("super");
}
Also used : JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCExpressionStatement(com.sun.tools.javac.tree.JCTree.JCExpressionStatement) Name(com.sun.tools.javac.util.Name)

Aggregations

JCExpressionStatement (com.sun.tools.javac.tree.JCTree.JCExpressionStatement)15 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)7 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)7 JCTree (com.sun.tools.javac.tree.JCTree)5 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)5 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)5 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)4 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)3 JCCatch (com.sun.tools.javac.tree.JCTree.JCCatch)3 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)3 Element (javax.lang.model.element.Element)3 ExecutableElement (javax.lang.model.element.ExecutableElement)3 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)2 JCAssign (com.sun.tools.javac.tree.JCTree.JCAssign)2 JCBinary (com.sun.tools.javac.tree.JCTree.JCBinary)2 JCCompilationUnit (com.sun.tools.javac.tree.JCTree.JCCompilationUnit)2 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)2 JCIdent (com.sun.tools.javac.tree.JCTree.JCIdent)2 JCIf (com.sun.tools.javac.tree.JCTree.JCIf)2 JCTry (com.sun.tools.javac.tree.JCTree.JCTry)2