Search in sources :

Example 6 with JCBlock

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

the class HandleDelegate method createDelegateMethod.

public JCMethodDecl createDelegateMethod(MethodSig sig, JavacNode annotation, Name delegateName, DelegateReceiver delegateReceiver) throws TypeNotConvertibleException, CantMakeDelegates {
    /* public <T, U, ...> ReturnType methodName(ParamType1 name1, ParamType2 name2, ...) throws T1, T2, ... {
		 *      (return) delegate.<T, U>methodName(name1, name2);
		 *  }
		 */
    checkConflictOfTypeVarNames(sig, annotation);
    JavacTreeMaker maker = annotation.getTreeMaker();
    com.sun.tools.javac.util.List<JCAnnotation> annotations;
    if (sig.isDeprecated) {
        annotations = com.sun.tools.javac.util.List.of(maker.Annotation(genJavaLangTypeRef(annotation, "Deprecated"), com.sun.tools.javac.util.List.<JCExpression>nil()));
    } else {
        annotations = com.sun.tools.javac.util.List.nil();
    }
    JCModifiers mods = maker.Modifiers(PUBLIC, annotations);
    JCExpression returnType = JavacResolution.typeToJCTree((Type) sig.type.getReturnType(), annotation.getAst(), true);
    boolean useReturn = sig.type.getReturnType().getKind() != TypeKind.VOID;
    ListBuffer<JCVariableDecl> params = sig.type.getParameterTypes().isEmpty() ? null : new ListBuffer<JCVariableDecl>();
    ListBuffer<JCExpression> args = sig.type.getParameterTypes().isEmpty() ? null : new ListBuffer<JCExpression>();
    ListBuffer<JCExpression> thrown = sig.type.getThrownTypes().isEmpty() ? null : new ListBuffer<JCExpression>();
    ListBuffer<JCTypeParameter> typeParams = sig.type.getTypeVariables().isEmpty() ? null : new ListBuffer<JCTypeParameter>();
    ListBuffer<JCExpression> typeArgs = sig.type.getTypeVariables().isEmpty() ? null : new ListBuffer<JCExpression>();
    Types types = Types.instance(annotation.getContext());
    for (TypeMirror param : sig.type.getTypeVariables()) {
        Name name = ((TypeVar) param).tsym.name;
        ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
        for (Type type : types.getBounds((TypeVar) param)) {
            bounds.append(JavacResolution.typeToJCTree(type, annotation.getAst(), true));
        }
        typeParams.append(maker.TypeParameter(name, bounds.toList()));
        typeArgs.append(maker.Ident(name));
    }
    for (TypeMirror ex : sig.type.getThrownTypes()) {
        thrown.append(JavacResolution.typeToJCTree((Type) ex, annotation.getAst(), true));
    }
    int idx = 0;
    String[] paramNames = sig.getParameterNames();
    boolean varargs = sig.elem.isVarArgs();
    for (TypeMirror param : sig.type.getParameterTypes()) {
        long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, annotation.getContext());
        JCModifiers paramMods = maker.Modifiers(flags);
        Name name = annotation.toName(paramNames[idx++]);
        if (varargs && idx == paramNames.length) {
            paramMods.flags |= VARARGS;
        }
        params.append(maker.VarDef(paramMods, name, JavacResolution.typeToJCTree((Type) param, annotation.getAst(), true), null));
        args.append(maker.Ident(name));
    }
    JCExpression delegateCall = maker.Apply(toList(typeArgs), maker.Select(delegateReceiver.get(annotation, delegateName), sig.name), toList(args));
    JCStatement body = useReturn ? maker.Return(delegateCall) : maker.Exec(delegateCall);
    JCBlock bodyBlock = maker.Block(0, com.sun.tools.javac.util.List.of(body));
    return recursiveSetGeneratedBy(maker.MethodDef(mods, sig.name, returnType, toList(typeParams), toList(params), toList(thrown), bodyBlock, null), annotation.get(), annotation.getContext());
}
Also used : JavacTypes(com.sun.tools.javac.model.JavacTypes) Types(com.sun.tools.javac.code.Types) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Name(com.sun.tools.javac.util.Name) TypeMirror(javax.lang.model.type.TypeMirror) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) ClassType(com.sun.tools.javac.code.Type.ClassType) Type(com.sun.tools.javac.code.Type) ExecutableType(javax.lang.model.type.ExecutableType) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers)

Example 7 with JCBlock

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

the class HandleEqualsAndHashCode method createHashCode.

public JCMethodDecl createHashCode(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, JCTree source) {
    JavacTreeMaker maker = typeNode.getTreeMaker();
    JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
    JCExpression returnType = maker.TypeIdent(CTC_INT);
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    Name primeName = typeNode.toName(PRIME_NAME);
    Name resultName = typeNode.toName(RESULT_NAME);
    long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
    /* final int PRIME = X; */
    {
        if (!fields.isEmpty() || callSuper) {
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), primeName, maker.TypeIdent(CTC_INT), maker.Literal(HandlerUtil.primeForHashcode())));
        }
    }
    /* int result = 1; */
    {
        statements.append(maker.VarDef(maker.Modifiers(0), resultName, maker.TypeIdent(CTC_INT), maker.Literal(1)));
    }
    if (callSuper) {
        JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("hashCode")), List.<JCExpression>nil());
        statements.append(createResultCalculation(typeNode, callToSuper));
    }
    Name dollar = typeNode.toName("$");
    for (JavacNode fieldNode : fields) {
        JCExpression fType = getFieldType(fieldNode, fieldAccess);
        JCExpression fieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
        if (fType instanceof JCPrimitiveTypeTree) {
            switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
                case BOOLEAN:
                    /* this.fieldName ? X : Y */
                    statements.append(createResultCalculation(typeNode, maker.Parens(maker.Conditional(fieldAccessor, maker.Literal(HandlerUtil.primeForTrue()), maker.Literal(HandlerUtil.primeForFalse())))));
                    break;
                case LONG:
                    {
                        Name dollarFieldName = dollar.append(((JCVariableDecl) fieldNode.get()).name);
                        statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), fieldAccessor));
                        statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName))));
                    }
                    break;
                case FLOAT:
                    /* Float.floatToIntBits(this.fieldName) */
                    statements.append(createResultCalculation(typeNode, maker.Apply(List.<JCExpression>nil(), genJavaLangTypeRef(typeNode, "Float", "floatToIntBits"), List.of(fieldAccessor))));
                    break;
                case DOUBLE:
                    {
                        /* longToIntForHashCode(Double.doubleToLongBits(this.fieldName)) */
                        Name dollarFieldName = dollar.append(((JCVariableDecl) fieldNode.get()).name);
                        JCExpression init = maker.Apply(List.<JCExpression>nil(), genJavaLangTypeRef(typeNode, "Double", "doubleToLongBits"), List.of(fieldAccessor));
                        statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, maker.TypeIdent(CTC_LONG), init));
                        statements.append(createResultCalculation(typeNode, longToIntForHashCode(maker, maker.Ident(dollarFieldName), maker.Ident(dollarFieldName))));
                    }
                    break;
                default:
                case BYTE:
                case SHORT:
                case INT:
                case CHAR:
                    /* just the field */
                    statements.append(createResultCalculation(typeNode, fieldAccessor));
                    break;
            }
        } else if (fType instanceof JCArrayTypeTree) {
            /* java.util.Arrays.deepHashCode(this.fieldName) //use just hashCode() for primitive arrays. */
            boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree;
            boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree;
            boolean useDeepHC = multiDim || !primitiveArray;
            JCExpression hcMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepHC ? "deepHashCode" : "hashCode");
            statements.append(createResultCalculation(typeNode, maker.Apply(List.<JCExpression>nil(), hcMethod, List.of(fieldAccessor))));
        } else /* objects */
        {
            /* final java.lang.Object $fieldName = this.fieldName; */
            /* ($fieldName == null ? NULL_PRIME : $fieldName.hashCode()) */
            Name dollarFieldName = dollar.append(((JCVariableDecl) fieldNode.get()).name);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), dollarFieldName, genJavaLangTypeRef(typeNode, "Object"), fieldAccessor));
            JCExpression hcCall = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(dollarFieldName), typeNode.toName("hashCode")), List.<JCExpression>nil());
            JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(dollarFieldName), maker.Literal(CTC_BOT, null));
            statements.append(createResultCalculation(typeNode, maker.Parens(maker.Conditional(thisEqualsNull, maker.Literal(HandlerUtil.primeForNull()), hcCall))));
        }
    }
    /* return result; */
    {
        statements.append(maker.Return(maker.Ident(resultName)));
    }
    JCBlock body = maker.Block(0, statements.toList());
    return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("hashCode"), returnType, List.<JCTypeParameter>nil(), List.<JCVariableDecl>nil(), List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) ListBuffer(com.sun.tools.javac.util.ListBuffer) 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) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)

Example 8 with JCBlock

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

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

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

the class HandleSetter method createSetter.

public static JCMethodDecl createSetter(long access, JavacNode field, JavacTreeMaker treeMaker, String setterName, boolean shouldReturnThis, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
    if (setterName == null)
        return null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
    JCExpression fieldRef = createFieldAccessor(treeMaker, field, FieldAccess.ALWAYS_FIELD);
    JCAssign assign = treeMaker.Assign(fieldRef, treeMaker.Ident(fieldDecl.name));
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    List<JCAnnotation> nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    List<JCAnnotation> nullables = findAnnotations(field, NULLABLE_PATTERN);
    Name methodName = field.toName(setterName);
    List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables);
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
    JCVariableDecl param = treeMaker.VarDef(treeMaker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
    if (nonNulls.isEmpty()) {
        statements.append(treeMaker.Exec(assign));
    } else {
        JCStatement nullCheck = generateNullCheck(treeMaker, field, source);
        if (nullCheck != null)
            statements.append(nullCheck);
        statements.append(treeMaker.Exec(assign));
    }
    JCExpression methodType = null;
    if (shouldReturnThis) {
        methodType = cloneSelfType(field);
    }
    if (methodType == null) {
        //WARNING: Do not use field.getSymbolTable().voidType - that field has gone through non-backwards compatible API changes within javac1.6.
        methodType = treeMaker.Type(Javac.createVoidType(field.getSymbolTable(), CTC_VOID));
        shouldReturnThis = false;
    }
    if (shouldReturnThis) {
        JCReturn returnStatement = treeMaker.Return(treeMaker.Ident(field.toName("this")));
        statements.append(returnStatement);
    }
    JCBlock methodBody = treeMaker.Block(0, statements.toList());
    List<JCTypeParameter> methodGenericParams = List.nil();
    List<JCVariableDecl> parameters = List.of(param);
    List<JCExpression> throwsClauses = List.nil();
    JCExpression annotationMethodDefaultValue = null;
    List<JCAnnotation> annsOnMethod = copyAnnotations(onMethod);
    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.get(), field.getContext());
    copyJavadoc(field, decl, CopyJavadoc.SETTER);
    return decl;
}
Also used : JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JCAssign(com.sun.tools.javac.tree.JCTree.JCAssign) ListBuffer(com.sun.tools.javac.util.ListBuffer) 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)

Aggregations

JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)44 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)32 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)31 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)28 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)23 Name (com.sun.tools.javac.util.Name)22 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)17 ListBuffer (com.sun.tools.javac.util.ListBuffer)17 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)16 JavacTreeMaker (lombok.javac.JavacTreeMaker)13 JCTree (com.sun.tools.javac.tree.JCTree)11 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)10 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)6 JavacNode (lombok.javac.JavacNode)6 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)5 HasErrorException (com.redhat.ceylon.compiler.java.codegen.recovery.HasErrorException)4 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)4 Type (com.redhat.ceylon.model.typechecker.model.Type)4 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)4 CustomTree (com.redhat.ceylon.compiler.typechecker.tree.CustomTree)3