Search in sources :

Example 11 with JCVariableDecl

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

the class HandleEqualsAndHashCode method createCanEqual.

public JCMethodDecl createCanEqual(JavacNode typeNode, JCTree source, List<JCAnnotation> onParam) {
    /* protected boolean canEqual(final java.lang.Object other) {
		 *     return other instanceof Outer.Inner.MyType;
		 * }
		 */
    JavacTreeMaker maker = typeNode.getTreeMaker();
    JCModifiers mods = maker.Modifiers(Flags.PROTECTED, List.<JCAnnotation>nil());
    JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
    Name canEqualName = typeNode.toName("canEqual");
    JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
    Name otherName = typeNode.toName("other");
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, typeNode.getContext());
    List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(flags, onParam), otherName, objectType, null));
    JCBlock body = maker.Block(0, List.<JCStatement>of(maker.Return(maker.TypeTest(maker.Ident(otherName), createTypeReference(typeNode, false)))));
    return recursiveSetGeneratedBy(maker.MethodDef(mods, canEqualName, returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Also used : JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name)

Example 12 with JCVariableDecl

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

the class HandleFieldDefaults method setFieldDefaultsForField.

public void setFieldDefaultsForField(JavacNode fieldNode, AccessLevel level, boolean makeFinal) {
    JCVariableDecl field = (JCVariableDecl) fieldNode.get();
    if (level != null && level != AccessLevel.NONE) {
        if ((field.mods.flags & (Flags.PUBLIC | Flags.PRIVATE | Flags.PROTECTED)) == 0) {
            if (!hasAnnotationAndDeleteIfNeccessary(PackagePrivate.class, fieldNode)) {
                if ((field.mods.flags & Flags.STATIC) == 0) {
                    field.mods.flags |= toJavacModifier(level);
                }
            }
        }
    }
    if (makeFinal && (field.mods.flags & Flags.FINAL) == 0) {
        if (!hasAnnotationAndDeleteIfNeccessary(NonFinal.class, fieldNode)) {
            if ((field.mods.flags & Flags.STATIC) == 0) {
                field.mods.flags |= Flags.FINAL;
            }
        }
    }
    fieldNode.rebuild();
}
Also used : PackagePrivate(lombok.experimental.PackagePrivate) NonFinal(lombok.experimental.NonFinal) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 13 with JCVariableDecl

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

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

the class HandleGetter method createGetter.

public JCMethodDecl createGetter(long access, JavacNode field, JavacTreeMaker treeMaker, JCTree source, boolean lazy, List<JCAnnotation> onMethod) {
    JCVariableDecl fieldNode = (JCVariableDecl) field.get();
    // Remember the type; lazy will change it
    JCExpression methodType = copyType(treeMaker, fieldNode);
    // Generate the methodName; lazy will change the field type
    Name methodName = field.toName(toGetterName(field));
    List<JCStatement> statements;
    JCTree toClearOfMarkers = null;
    if (lazy && !inNetbeansEditor(field)) {
        toClearOfMarkers = fieldNode.init;
        statements = createLazyGetterBody(treeMaker, field, source);
    } else {
        statements = createSimpleGetterBody(treeMaker, field);
    }
    JCBlock methodBody = treeMaker.Block(0, statements);
    List<JCTypeParameter> methodGenericParams = List.nil();
    List<JCVariableDecl> parameters = List.nil();
    List<JCExpression> throwsClauses = List.nil();
    JCExpression annotationMethodDefaultValue = null;
    List<JCAnnotation> nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    List<JCAnnotation> nullables = findAnnotations(field, NULLABLE_PATTERN);
    List<JCAnnotation> delegates = findDelegatesAndRemoveFromField(field);
    List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod).appendList(nonNulls).appendList(nullables);
    if (isFieldDeprecated(field)) {
        annsOnMethod = annsOnMethod.prepend(treeMaker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
    }
    JCMethodDecl decl = recursiveSetGeneratedBy(treeMaker.MethodDef(treeMaker.Modifiers(access, annsOnMethod), methodName, methodType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source, field.getContext());
    if (toClearOfMarkers != null)
        recursiveSetGeneratedBy(toClearOfMarkers, null, null);
    decl.mods.annotations = decl.mods.annotations.appendList(delegates);
    copyJavadoc(field, decl, CopyJavadoc.GETTER);
    return decl;
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JCTree(com.sun.tools.javac.tree.JCTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 15 with JCVariableDecl

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

the class HandleHelper method handle.

@Override
public void handle(AnnotationValues<Helper> annotation, JCAnnotation ast, JavacNode annotationNode) {
    handleExperimentalFlagUsage(annotationNode, ConfigurationKeys.HELPER_FLAG_USAGE, "@Helper");
    deleteAnnotationIfNeccessary(annotationNode, Helper.class);
    JavacNode annotatedType = annotationNode.up();
    JavacNode containingBlock = annotatedType == null ? null : annotatedType.directUp();
    List<JCStatement> origStatements = getStatementsFromJcNode(containingBlock == null ? null : containingBlock.get());
    if (annotatedType == null || annotatedType.getKind() != Kind.TYPE || origStatements == null) {
        annotationNode.addError("@Helper is legal only on method-local classes.");
        return;
    }
    JCClassDecl annotatedType_ = (JCClassDecl) annotatedType.get();
    Iterator<JCStatement> it = origStatements.iterator();
    while (it.hasNext()) {
        if (it.next() == annotatedType_) {
            break;
        }
    }
    java.util.List<String> knownMethodNames = new ArrayList<String>();
    for (JavacNode ch : annotatedType.down()) {
        if (ch.getKind() != Kind.METHOD)
            continue;
        String n = ch.getName();
        if (n == null || n.isEmpty() || n.charAt(0) == '<')
            continue;
        knownMethodNames.add(n);
    }
    Collections.sort(knownMethodNames);
    final String[] knownMethodNames_ = knownMethodNames.toArray(new String[knownMethodNames.size()]);
    final Name helperName = annotationNode.toName("$" + annotatedType_.name);
    final boolean[] helperUsed = new boolean[1];
    final JavacTreeMaker maker = annotationNode.getTreeMaker();
    TreeVisitor<Void, Void> visitor = new TreeScanner<Void, Void>() {

        @Override
        public Void visitMethodInvocation(MethodInvocationTree node, Void p) {
            JCMethodInvocation jcmi = (JCMethodInvocation) node;
            apply(jcmi);
            return super.visitMethodInvocation(node, p);
        }

        private void apply(JCMethodInvocation jcmi) {
            if (!(jcmi.meth instanceof JCIdent))
                return;
            JCIdent jci = (JCIdent) jcmi.meth;
            if (Arrays.binarySearch(knownMethodNames_, jci.name.toString()) < 0)
                return;
            jcmi.meth = maker.Select(maker.Ident(helperName), jci.name);
            helperUsed[0] = true;
        }
    };
    while (it.hasNext()) {
        JCStatement stat = it.next();
        stat.accept(visitor, null);
    }
    if (!helperUsed[0]) {
        annotationNode.addWarning("No methods of this helper class are ever used.");
        return;
    }
    ListBuffer<JCStatement> newStatements = new ListBuffer<JCStatement>();
    boolean mark = false;
    for (JCStatement stat : origStatements) {
        newStatements.append(stat);
        if (mark || stat != annotatedType_)
            continue;
        mark = true;
        JCExpression init = maker.NewClass(null, List.<JCExpression>nil(), maker.Ident(annotatedType_.name), List.<JCExpression>nil(), null);
        JCExpression varType = maker.Ident(annotatedType_.name);
        JCVariableDecl decl = maker.VarDef(maker.Modifiers(Flags.FINAL), helperName, varType, init);
        newStatements.append(decl);
    }
    setStatementsOfJcNode(containingBlock.get(), newStatements.toList());
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCIdent(com.sun.tools.javac.tree.JCTree.JCIdent) JavacTreeMaker(lombok.javac.JavacTreeMaker) ListBuffer(com.sun.tools.javac.util.ListBuffer) ArrayList(java.util.ArrayList) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) TreeScanner(com.sun.source.util.TreeScanner) MethodInvocationTree(com.sun.source.tree.MethodInvocationTree)

Aggregations

JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)98 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)56 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)36 JCTree (com.sun.tools.javac.tree.JCTree)31 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)31 Name (com.sun.tools.javac.util.Name)31 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)27 JavacNode (lombok.javac.JavacNode)27 ListBuffer (com.sun.tools.javac.util.ListBuffer)25 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)24 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)22 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)18 JavacTreeMaker (lombok.javac.JavacTreeMaker)18 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)13 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)12 Type (com.redhat.ceylon.model.typechecker.model.Type)11 SyntheticName (com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName)9 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)9 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)8 Type (com.sun.tools.javac.code.Type)7