Search in sources :

Example 36 with JCClassDecl

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

the class JavacHandlerUtil method injectType.

/**
 * Adds an inner type (class, interface, enum) to the given type. Cannot inject top-level types.
 *
 * @param typeNode parent type to inject new type into
 * @param type New type (class, interface, etc) to inject.
 * @return
 */
public static JavacNode injectType(JavacNode typeNode, final JCClassDecl type) {
    JCClassDecl typeDecl = (JCClassDecl) typeNode.get();
    addSuppressWarningsAll(type.mods, typeNode, type.pos, getGeneratedBy(type), typeNode.getContext());
    addGenerated(type.mods, typeNode, type.pos, getGeneratedBy(type), typeNode.getContext());
    typeDecl.defs = typeDecl.defs.append(type);
    return typeNode.add(type, Kind.TYPE);
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl)

Example 37 with JCClassDecl

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

the class JavacHandlerUtil method deleteAnnotationIfNeccessary0.

private static void deleteAnnotationIfNeccessary0(JavacNode annotation, String... 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 (String annotationType : annotationTypes) {
        deleteImportFromCompilationUnit(annotation, annotationType);
    }
}
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 38 with JCClassDecl

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

the class HandleDelegate method checkConflictOfTypeVarNames.

/**
 * There's a rare but problematic case if a delegate method has its own type variables, and the delegated type does too, and the method uses both.
 * If for example the delegated type has {@code <E>}, and the method has {@code <T>}, but in our class we have a {@code <T>} at the class level, then we have two different
 * type variables both named {@code T}. We detect this situation and error out asking the programmer to rename their type variable.
 *
 * @throws CantMakeDelegates If there's a conflict. Conflict list is in ex.conflicted.
 */
public void checkConflictOfTypeVarNames(MethodSig sig, JavacNode annotation) throws CantMakeDelegates {
    if (sig.elem.getTypeParameters().isEmpty())
        return;
    Set<String> usedInOurType = new HashSet<String>();
    JavacNode enclosingType = annotation;
    while (enclosingType != null) {
        if (enclosingType.getKind() == Kind.TYPE) {
            List<JCTypeParameter> typarams = ((JCClassDecl) enclosingType.get()).typarams;
            if (typarams != null)
                for (JCTypeParameter param : typarams) {
                    if (param.name != null)
                        usedInOurType.add(param.name.toString());
                }
        }
        enclosingType = enclosingType.up();
    }
    Set<String> usedInMethodSig = new HashSet<String>();
    for (TypeParameterElement param : sig.elem.getTypeParameters()) {
        usedInMethodSig.add(param.getSimpleName().toString());
    }
    usedInMethodSig.retainAll(usedInOurType);
    if (usedInMethodSig.isEmpty())
        return;
    // We might be delegating a List<T>, and we are making method <T> toArray(). A conflict is possible.
    // But only if the toArray method also uses type vars from its class, otherwise we're only shadowing,
    // which is okay as we'll add a @SuppressWarnings.
    FindTypeVarScanner scanner = new FindTypeVarScanner();
    sig.elem.asType().accept(scanner, null);
    Set<String> names = new HashSet<String>(scanner.getTypeVariables());
    names.removeAll(usedInMethodSig);
    if (!names.isEmpty()) {
        // We have a confirmed conflict. We could dig deeper as this may still be a false alarm, but its already an exceedingly rare case.
        CantMakeDelegates cmd = new CantMakeDelegates();
        cmd.conflicted = usedInMethodSig;
        throw cmd;
    }
}
Also used : JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) FindTypeVarScanner(lombok.javac.FindTypeVarScanner) JavacNode(lombok.javac.JavacNode) HashSet(java.util.HashSet) TypeParameterElement(javax.lang.model.element.TypeParameterElement)

Example 39 with JCClassDecl

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

the class HandleEqualsAndHashCode method createTypeReference.

public JCExpression createTypeReference(JavacNode type, boolean addWildcards) {
    java.util.List<String> list = new ArrayList<String>();
    java.util.List<Integer> genericsCount = addWildcards ? new ArrayList<Integer>() : null;
    list.add(type.getName());
    if (addWildcards)
        genericsCount.add(((JCClassDecl) type.get()).typarams.size());
    boolean staticContext = (((JCClassDecl) type.get()).getModifiers().flags & Flags.STATIC) != 0;
    JavacNode tNode = type.up();
    while (tNode != null && tNode.getKind() == Kind.TYPE) {
        list.add(tNode.getName());
        if (addWildcards)
            genericsCount.add(staticContext ? 0 : ((JCClassDecl) tNode.get()).typarams.size());
        if (!staticContext)
            staticContext = (((JCClassDecl) tNode.get()).getModifiers().flags & Flags.STATIC) != 0;
        tNode = tNode.up();
    }
    Collections.reverse(list);
    if (addWildcards)
        Collections.reverse(genericsCount);
    JavacTreeMaker maker = type.getTreeMaker();
    JCExpression chain = maker.Ident(type.toName(list.get(0)));
    if (addWildcards)
        chain = wildcardify(maker, chain, genericsCount.get(0));
    for (int i = 1; i < list.size(); i++) {
        chain = maker.Select(chain, type.toName(list.get(i)));
        if (addWildcards)
            chain = wildcardify(maker, chain, genericsCount.get(i));
    }
    return chain;
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JavacTreeMaker(lombok.javac.JavacTreeMaker) ArrayList(java.util.ArrayList) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode)

Example 40 with JCClassDecl

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

the class HandleFieldDefaults method generateFieldDefaultsForType.

public boolean generateFieldDefaultsForType(JavacNode typeNode, JavacNode errorNode, AccessLevel level, boolean makeFinal, boolean checkForTypeLevelFieldDefaults) {
    if (checkForTypeLevelFieldDefaults) {
        if (hasAnnotation(FieldDefaults.class, typeNode)) {
            // The annotation will make it happen, so we can skip it.
            return true;
        }
    }
    JCClassDecl typeDecl = null;
    if (typeNode.get() instanceof JCClassDecl)
        typeDecl = (JCClassDecl) typeNode.get();
    long modifiers = typeDecl == null ? 0 : typeDecl.mods.flags;
    boolean notAClass = (modifiers & (Flags.INTERFACE | Flags.ANNOTATION)) != 0;
    if (typeDecl == null || notAClass) {
        errorNode.addError("@FieldDefaults is only supported on a class or an enum.");
        return false;
    }
    for (JavacNode field : typeNode.down()) {
        if (field.getKind() != Kind.FIELD)
            continue;
        JCVariableDecl fieldDecl = (JCVariableDecl) field.get();
        // Skip fields that start with $
        if (fieldDecl.name.toString().startsWith("$"))
            continue;
        setFieldDefaultsForField(field, level, makeFinal);
    }
    return true;
}
Also used : JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) JavacNode(lombok.javac.JavacNode) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl)

Aggregations

JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)46 JavacNode (lombok.javac.JavacNode)24 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)23 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)14 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)11 ListBuffer (com.sun.tools.javac.util.ListBuffer)11 JCTree (com.sun.tools.javac.tree.JCTree)10 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)9 JavacTreeMaker (lombok.javac.JavacTreeMaker)9 ClassSymbol (com.sun.tools.javac.code.Symbol.ClassSymbol)6 Name (com.sun.tools.javac.util.Name)6 Type (com.sun.tools.javac.code.Type)5 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)5 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)4 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)4 JCIdent (com.sun.tools.javac.tree.JCTree.JCIdent)4 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)4 JCCompilationUnit (com.sun.tools.javac.tree.JCTree.JCCompilationUnit)3 Type (com.redhat.ceylon.model.typechecker.model.Type)2 Tree (com.sun.source.tree.Tree)2