Search in sources :

Example 11 with JCMethodDecl

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

the class HandleWither method createWitherForField.

public void createWitherForField(AccessLevel level, JavacNode fieldNode, JavacNode source, boolean strictMode, List<JCAnnotation> onMethod, List<JCAnnotation> onParam) {
    JavacNode typeNode = fieldNode.up();
    boolean makeAbstract = typeNode != null && typeNode.getKind() == Kind.TYPE && (((JCClassDecl) typeNode.get()).mods.flags & Flags.ABSTRACT) != 0;
    if (fieldNode.getKind() != Kind.FIELD) {
        fieldNode.addError("@Wither is only supported on a class or a field.");
        return;
    }
    JCVariableDecl fieldDecl = (JCVariableDecl) fieldNode.get();
    String methodName = toWitherName(fieldNode);
    if (methodName == null) {
        fieldNode.addWarning("Not generating wither for this field: It does not fit your @Accessors prefix list.");
        return;
    }
    if ((fieldDecl.mods.flags & Flags.STATIC) != 0) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for static fields.");
        }
        return;
    }
    if ((fieldDecl.mods.flags & Flags.FINAL) != 0 && fieldDecl.init != null) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for final, initialized fields.");
        }
        return;
    }
    if (fieldDecl.name.toString().startsWith("$")) {
        if (strictMode) {
            fieldNode.addWarning("Not generating wither for this field: Withers cannot be generated for fields starting with $.");
        }
        return;
    }
    for (String altName : toAllWitherNames(fieldNode)) {
        switch(methodExists(altName, fieldNode, false, 1)) {
            case EXISTS_BY_LOMBOK:
                return;
            case EXISTS_BY_USER:
                if (strictMode) {
                    String altNameExpl = "";
                    if (!altName.equals(methodName))
                        altNameExpl = String.format(" (%s)", altName);
                    fieldNode.addWarning(String.format("Not generating %s(): A method with that name already exists%s", methodName, altNameExpl));
                }
                return;
            default:
            case NOT_EXISTS:
        }
    }
    long access = toJavacModifier(level);
    JCMethodDecl createdWither = createWither(access, fieldNode, fieldNode.getTreeMaker(), source, onMethod, onParam, makeAbstract);
    ClassSymbol sym = ((JCClassDecl) fieldNode.up().get()).sym;
    Type returnType = sym == null ? null : sym.type;
    injectMethod(typeNode, createdWither, List.<Type>of(getMirrorForFieldType(fieldNode)), returnType);
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) Type(com.sun.tools.javac.code.Type) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacNode(lombok.javac.JavacNode) ClassSymbol(com.sun.tools.javac.code.Symbol.ClassSymbol) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 12 with JCMethodDecl

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

the class HandleWither method createWither.

public JCMethodDecl createWither(long access, JavacNode field, JavacTreeMaker maker, JavacNode source, List<JCAnnotation> onMethod, List<JCAnnotation> onParam, boolean makeAbstract) {
    String witherName = toWitherName(field);
    if (witherName == null)
        return null;
    JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
    List<JCAnnotation> nonNulls = findAnnotations(field, NON_NULL_PATTERN);
    List<JCAnnotation> nullables = findAnnotations(field, NULLABLE_PATTERN);
    Name methodName = field.toName(witherName);
    JCExpression returnType = cloneSelfType(field);
    JCBlock methodBody = null;
    long flags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, field.getContext());
    List<JCAnnotation> annsOnParam = copyAnnotations(onParam).appendList(nonNulls).appendList(nullables);
    JCVariableDecl param = maker.VarDef(maker.Modifiers(flags, annsOnParam), fieldDecl.name, fieldDecl.vartype, null);
    if (!makeAbstract) {
        ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
        JCExpression selfType = cloneSelfType(field);
        if (selfType == null)
            return null;
        ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
        for (JavacNode child : field.up().down()) {
            if (child.getKind() != Kind.FIELD)
                continue;
            JCVariableDecl childDecl = (JCVariableDecl) child.get();
            // Skip fields that start with $
            if (childDecl.name.toString().startsWith("$"))
                continue;
            long fieldFlags = childDecl.mods.flags;
            // Skip static fields.
            if ((fieldFlags & Flags.STATIC) != 0)
                continue;
            // Skip initialized final fields.
            if (((fieldFlags & Flags.FINAL) != 0) && childDecl.init != null)
                continue;
            if (child.get() == field.get()) {
                args.append(maker.Ident(fieldDecl.name));
            } else {
                args.append(createFieldAccessor(maker, child, FieldAccess.ALWAYS_FIELD));
            }
        }
        JCNewClass newClass = maker.NewClass(null, List.<JCExpression>nil(), selfType, args.toList(), null);
        JCExpression identityCheck = maker.Binary(CTC_EQUAL, createFieldAccessor(maker, field, FieldAccess.ALWAYS_FIELD), maker.Ident(fieldDecl.name));
        JCConditional conditional = maker.Conditional(identityCheck, maker.Ident(field.toName("this")), newClass);
        JCReturn returnStatement = maker.Return(conditional);
        if (nonNulls.isEmpty()) {
            statements.append(returnStatement);
        } else {
            JCStatement nullCheck = generateNullCheck(maker, field, source);
            if (nullCheck != null)
                statements.append(nullCheck);
            statements.append(returnStatement);
        }
        methodBody = maker.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(maker.Annotation(genJavaLangTypeRef(field, "Deprecated"), List.<JCExpression>nil()));
    }
    if (makeAbstract)
        access = access | Flags.ABSTRACT;
    JCMethodDecl decl = recursiveSetGeneratedBy(maker.MethodDef(maker.Modifiers(access, annsOnMethod), methodName, returnType, methodGenericParams, parameters, throwsClauses, methodBody, annotationMethodDefaultValue), source.get(), field.getContext());
    copyJavadoc(field, decl, CopyJavadoc.WITHER);
    return decl;
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCReturn(com.sun.tools.javac.tree.JCTree.JCReturn) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCConditional(com.sun.tools.javac.tree.JCTree.JCConditional) 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) JavacNode(lombok.javac.JavacNode) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 13 with JCMethodDecl

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

the class JavacHandlerUtil method deleteAnnotationIfNeccessary0.

private static void deleteAnnotationIfNeccessary0(JavacNode annotation, Class<? extends Annotation>... annotationTypes) {
    if (inNetbeansEditor(annotation))
        return;
    if (!annotation.shouldDeleteLombokAnnotations())
        return;
    JavacNode parentNode = annotation.directUp();
    switch(parentNode.getKind()) {
        case FIELD:
        case ARGUMENT:
        case LOCAL:
            JCVariableDecl variable = (JCVariableDecl) parentNode.get();
            variable.mods.annotations = filterList(variable.mods.annotations, annotation.get());
            break;
        case METHOD:
            JCMethodDecl method = (JCMethodDecl) parentNode.get();
            method.mods.annotations = filterList(method.mods.annotations, annotation.get());
            break;
        case TYPE:
            try {
                JCClassDecl type = (JCClassDecl) parentNode.get();
                type.mods.annotations = filterList(type.mods.annotations, annotation.get());
            } catch (ClassCastException e) {
            //something rather odd has been annotated. Better to just break only delombok instead of everything.
            }
            break;
        default:
            //This really shouldn't happen, but if it does, better just break delombok instead of breaking everything.
            return;
    }
    parentNode.getAst().setChanged();
    for (Class<?> annotationType : annotationTypes) {
        deleteImportFromCompilationUnit(annotation, annotationType.getName());
    }
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) JavacNode(lombok.javac.JavacNode) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Example 14 with JCMethodDecl

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

the class JavacGuavaSingularizer method generatePluralMethod.

protected void generatePluralMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
    List<JCTypeParameter> typeParams = List.nil();
    List<JCExpression> thrown = List.nil();
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
    JCExpression thisDotFieldDotAddAll = chainDots(builderType, "this", data.getPluralName().toString(), getAddMethodName() + "All");
    JCExpression invokeAddAll = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAddAll, List.<JCExpression>of(maker.Ident(data.getPluralName())));
    statements.append(maker.Exec(invokeAddAll));
    if (returnStatement != null)
        statements.append(returnStatement);
    JCBlock body = maker.Block(0, statements.toList());
    Name methodName = data.getPluralName();
    long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
    if (!fluent)
        methodName = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName() + "All", methodName.toString()));
    JCExpression paramType;
    String aaTypeName = getAddAllTypeName();
    if (aaTypeName.startsWith("java.lang.") && aaTypeName.indexOf('.', 11) == -1) {
        paramType = genJavaLangTypeRef(builderType, aaTypeName.substring(10));
    } else {
        paramType = chainDotsString(builderType, aaTypeName);
    }
    paramType = addTypeArgs(getTypeArgumentsCount(), true, builderType, paramType, data.getTypeArgs(), source);
    JCVariableDecl param = maker.VarDef(maker.Modifiers(paramFlags), data.getPluralName(), paramType, null);
    JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, List.of(param), thrown, body, null);
    injectMethod(builderType, method);
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) 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) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers)

Example 15 with JCMethodDecl

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

the class JavacGuavaSingularizer method generateSingularMethod.

void generateSingularMethod(JavacTreeMaker maker, JCExpression returnType, JCStatement returnStatement, SingularData data, JavacNode builderType, JCTree source, boolean fluent) {
    List<JCTypeParameter> typeParams = List.nil();
    List<JCExpression> thrown = List.nil();
    LombokImmutableList<String> suffixes = getArgumentSuffixes();
    Name[] names = new Name[suffixes.size()];
    for (int i = 0; i < suffixes.size(); i++) {
        String s = suffixes.get(i);
        Name n = data.getSingularName();
        names[i] = s.isEmpty() ? n : builderType.toName(s);
    }
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC);
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    statements.append(createConstructBuilderVarIfNeeded(maker, data, builderType, source));
    JCExpression thisDotFieldDotAdd = chainDots(builderType, "this", data.getPluralName().toString(), getAddMethodName());
    ListBuffer<JCExpression> invokeAddExprBuilder = new ListBuffer<JCExpression>();
    for (int i = 0; i < suffixes.size(); i++) {
        invokeAddExprBuilder.append(maker.Ident(names[i]));
    }
    List<JCExpression> invokeAddExpr = invokeAddExprBuilder.toList();
    JCExpression invokeAdd = maker.Apply(List.<JCExpression>nil(), thisDotFieldDotAdd, invokeAddExpr);
    statements.append(maker.Exec(invokeAdd));
    if (returnStatement != null)
        statements.append(returnStatement);
    JCBlock body = maker.Block(0, statements.toList());
    Name methodName = data.getSingularName();
    long paramFlags = JavacHandlerUtil.addFinalIfNeeded(Flags.PARAMETER, builderType.getContext());
    if (!fluent)
        methodName = builderType.toName(HandlerUtil.buildAccessorName(getAddMethodName(), methodName.toString()));
    ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>();
    for (int i = 0; i < suffixes.size(); i++) {
        JCExpression pt = cloneParamType(i, maker, data.getTypeArgs(), builderType, source);
        JCVariableDecl p = maker.VarDef(maker.Modifiers(paramFlags), names[i], pt, null);
        params.append(p);
    }
    JCMethodDecl method = maker.MethodDef(mods, methodName, returnType, typeParams, params.toList(), thrown, body, null);
    injectMethod(builderType, method);
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JCMethodDecl(com.sun.tools.javac.tree.JCTree.JCMethodDecl) 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) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers)

Aggregations

JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)45 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)31 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)20 Name (com.sun.tools.javac.util.Name)17 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)16 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)16 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)15 ListBuffer (com.sun.tools.javac.util.ListBuffer)14 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)13 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)13 JavacNode (lombok.javac.JavacNode)13 JCTree (com.sun.tools.javac.tree.JCTree)12 SuggestedFix (com.google.errorprone.fixes.SuggestedFix)5 Type (com.sun.tools.javac.code.Type)5 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)5 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)5 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)5 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)4 JavacTreeMaker (lombok.javac.JavacTreeMaker)4 JCExpressionStatement (com.sun.tools.javac.tree.JCTree.JCExpressionStatement)3