Search in sources :

Example 56 with JCAnnotation

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

the class AnnotationInvocationVisitor method transformConstructor.

private static JCAnnotation transformConstructor(ExpressionTransformer exprGen, Tree.InvocationExpression invocation, AnnotationInvocation ai, com.sun.tools.javac.util.List<AnnotationFieldName> fieldPath) {
    Map<Parameter, ListBuffer<JCExpression>> args = new LinkedHashMap<Parameter, ListBuffer<JCExpression>>();
    List<Parameter> classParameters = ai.getClassParameters();
    // The class parameter's we've not yet figured out the value for
    ArrayList<Parameter> unbound = new ArrayList<Parameter>(classParameters);
    for (Parameter classParameter : classParameters) {
        for (AnnotationArgument argument : ai.findAnnotationArgumentForClassParameter(classParameter)) {
            JCExpression expr = transformConstructorArgument(exprGen, invocation, classParameter, argument, fieldPath);
            appendArgument(args, classParameter, expr);
            unbound.remove(classParameter);
        }
    }
    outer: for (Parameter classParameter : ((ArrayList<Parameter>) unbound.clone())) {
        // Defaulted argument
        if (ai.isInstantiation()) {
            if (classParameter.isDefaulted()) {
                // That's OK, we'll pick up the default argument from
                // the Java Annotation type
                unbound.remove(classParameter);
                continue outer;
            }
        } else {
            Function ac2 = (Function) ai.getPrimary();
            AnnotationInvocation i = (AnnotationInvocation) ac2.getAnnotationConstructor();
            for (AnnotationArgument aa : i.getAnnotationArguments()) {
                if (aa.getParameter().equals(classParameter)) {
                    appendArgument(args, classParameter, aa.getTerm().makeAnnotationArgumentValue(exprGen, i, com.sun.tools.javac.util.List.<AnnotationFieldName>of(aa)));
                    unbound.remove(classParameter);
                    continue outer;
                }
            }
        }
        if (Strategy.hasEmptyDefaultArgument(classParameter)) {
            appendArgument(args, classParameter, exprGen.make().NewArray(null, null, com.sun.tools.javac.util.List.<JCExpression>nil()));
            unbound.remove(classParameter);
            continue outer;
        }
    }
    for (Parameter classParameter : unbound) {
        appendArgument(args, classParameter, exprGen.makeErroneous(invocation, "compiler bug: unbound annotation class parameter " + classParameter.getName()));
    }
    ListBuffer<JCExpression> assignments = ListBuffer.<JCExpression>lb();
    for (Map.Entry<Parameter, ListBuffer<JCExpression>> entry : args.entrySet()) {
        ListBuffer<JCExpression> exprs = entry.getValue();
        if (exprs.size() == 1) {
            assignments.append(makeArgument(exprGen, invocation, entry.getKey(), exprs.first()));
        } else {
            assignments.append(makeArgument(exprGen, invocation, entry.getKey(), exprGen.make().NewArray(null, null, exprs.toList())));
        }
    }
    JCAnnotation annotation = exprGen.at(invocation).Annotation(ai.makeAnnotationType(exprGen), assignments.toList());
    return annotation;
}
Also used : ListBuffer(com.sun.tools.javac.util.ListBuffer) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 57 with JCAnnotation

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

the class CallableBuilder method buildTypeConstructor.

protected JCExpression buildTypeConstructor(Type callableType, JCNewClass callableInstance) {
    JCExpression result;
    // Wrap in an anonymous TypeConstructor subcla
    MethodDefinitionBuilder rawApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.apply.toString());
    rawApply.modifiers(Flags.PUBLIC);
    rawApply.isOverride(true);
    // for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
    // apply.typeParameter(tp);
    // }
    rawApply.resultType(null, gen.makeJavaType(callableType, AbstractTransformer.JT_RAW));
    {
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
        pdb.modifiers(Flags.FINAL);
        pdb.type(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType)), null);
        rawApply.parameter(pdb);
    }
    rawApply.body(List.<JCStatement>of(gen.make().Return(gen.make().Apply(null, gen.naming.makeUnquotedIdent(Naming.Unfix.$apply$.toString()), List.<JCExpression>of(gen.naming.makeUnquotedIdent("applied"))))));
    MethodDefinitionBuilder typedApply = MethodDefinitionBuilder.systemMethod(gen, Naming.Unfix.$apply$.toString());
    typedApply.modifiers(Flags.PRIVATE);
    // for (TypeParameter tp : typeModel.getDeclaration().getTypeParameters()) {
    // apply.typeParameter(tp);
    // }
    typedApply.resultType(null, gen.makeJavaType(callableType));
    {
        ParameterDefinitionBuilder pdb = ParameterDefinitionBuilder.systemParameter(gen, "applied");
        pdb.modifiers(Flags.FINAL);
        pdb.type(gen.make().TypeArray(gen.make().Type(gen.syms().ceylonTypeDescriptorType)), null);
        typedApply.parameter(pdb);
    }
    ListBuffer<JCTypeParameter> typeParameters = ListBuffer.<JCTypeParameter>lb();
    for (Map.Entry<TypeParameter, Type> ta : typeModel.getTypeArguments().entrySet()) {
        Type typeArgument = ta.getValue();
        TypeParameter typeParameter = ta.getKey();
        typeParameters.add(gen.makeTypeParameter(typeParameter, null));
        typedApply.body(gen.makeVar(Flags.FINAL, gen.naming.getTypeArgumentDescriptorName(typeParameter), gen.make().Type(gen.syms().ceylonTypeDescriptorType), gen.make().Indexed(gen.makeUnquotedIdent("applied"), gen.make().Literal(typeModel.getTypeArgumentList().indexOf(typeArgument)))));
    }
    typedApply.body(gen.make().Return(callableInstance));
    // typedApply.body(body.toList());
    MethodDefinitionBuilder ctor = MethodDefinitionBuilder.constructor(gen);
    ctor.body(gen.make().Exec(gen.make().Apply(null, gen.naming.makeSuper(), List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))))));
    SyntheticName n = gen.naming.synthetic(typeModel.getDeclaration().getName());
    JCClassDecl classDef = gen.make().ClassDef(gen.make().Modifiers(0, List.<JCAnnotation>nil()), // name,
    n.asName(), typeParameters.toList(), // extending
    gen.make().QualIdent(gen.syms().ceylonAbstractTypeConstructorType.tsym), // implementing,
    List.<JCExpression>nil(), List.<JCTree>of(ctor.build(), rawApply.build(), typedApply.build()));
    result = gen.make().LetExpr(List.<JCStatement>of(classDef), gen.make().NewClass(null, null, n.makeIdent(), List.<JCExpression>nil(), // List.<JCExpression>of(gen.make().Literal(typeModel.asString(true))),
    null));
    return result;
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCClassDecl(com.sun.tools.javac.tree.JCTree.JCClassDecl) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Map(java.util.Map) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 58 with JCAnnotation

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

the class AnnotationInvocation method encode.

/**
 * Encode this invocation into a {@code @AnnotationInstantiation}
 * (if the annotation constructors just calls the annotation class)
 * or {@code @AnnotationInstantiationTree}
 * (if the annotation constructor calls another annotation constructor)
 */
public JCAnnotation encode(AbstractTransformer gen, ListBuffer<JCExpression> instantiations) {
    ListBuffer<JCExpression> arguments = ListBuffer.lb();
    for (AnnotationArgument argument : getAnnotationArguments()) {
        arguments.append(gen.make().Literal(argument.getTerm().encode(gen, instantiations)));
    }
    JCExpression primary;
    if (isInstantiation()) {
        primary = gen.makeJavaType(getAnnotationClassType());
    } else {
        primary = gen.naming.makeName((Function) getPrimary(), Naming.NA_FQ | Naming.NA_WRAPPER);
    }
    JCAnnotation atInstantiation = gen.make().Annotation(gen.make().Type(gen.syms().ceylonAtAnnotationInstantiationType), com.sun.tools.javac.util.List.<JCExpression>of(gen.make().Assign(gen.naming.makeUnquotedIdent("arguments"), gen.make().NewArray(null, null, arguments.toList())), gen.make().Assign(gen.naming.makeUnquotedIdent("primary"), gen.naming.makeQualIdent(primary, "class"))));
    if (instantiations.isEmpty()) {
        return atInstantiation;
    } else {
        return gen.make().Annotation(gen.make().Type(gen.syms().ceylonAtAnnotationInstantiationTreeType), com.sun.tools.javac.util.List.<JCExpression>of(gen.make().NewArray(null, null, instantiations.prepend(atInstantiation).toList())));
    }
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 59 with JCAnnotation

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

the class AbstractTransformer method makeAtAnnotation.

private JCExpression makeAtAnnotation(Annotation annotation) {
    JCExpression valueAttribute = make().Assign(naming.makeUnquotedIdent("value"), make().Literal(annotation.getName()));
    List<JCExpression> attributes;
    if (!annotation.getPositionalArguments().isEmpty()) {
        java.util.List<String> positionalArguments = annotation.getPositionalArguments();
        ListBuffer<JCExpression> array = new ListBuffer<JCTree.JCExpression>();
        for (String val : positionalArguments) array.add(make().Literal(val));
        JCExpression argumentsAttribute = make().Assign(naming.makeUnquotedIdent("arguments"), make().NewArray(null, null, array.toList()));
        attributes = List.of(valueAttribute, argumentsAttribute);
    } else if (!annotation.getNamedArguments().isEmpty()) {
        Map<String, String> namedArguments = annotation.getNamedArguments();
        ListBuffer<JCExpression> array = new ListBuffer<JCTree.JCExpression>();
        for (Entry<String, String> entry : namedArguments.entrySet()) {
            JCExpression argNameAttribute = make().Assign(naming.makeUnquotedIdent("name"), make().Literal(entry.getKey()));
            JCExpression argValueAttribute = make().Assign(naming.makeUnquotedIdent("value"), make().Literal(entry.getValue()));
            JCAnnotation namedArg = make().Annotation(makeIdent(syms().ceylonAtNamedArgumentType), List.of(argNameAttribute, argValueAttribute));
            array.add(namedArg);
        }
        JCExpression argumentsAttribute = make().Assign(naming.makeUnquotedIdent("namedArguments"), make().NewArray(null, null, array.toList()));
        attributes = List.of(valueAttribute, argumentsAttribute);
    } else
        attributes = List.of(valueAttribute);
    return make().Annotation(makeIdent(syms().ceylonAtAnnotationType), attributes);
}
Also used : Entry(java.util.Map.Entry) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) Map(java.util.Map) LineMap(com.sun.tools.javac.util.Position.LineMap) HashMap(java.util.HashMap) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 60 with JCAnnotation

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

the class CollectionLiteralAnnotationTerm method makeDpmAnnotations.

@Override
public com.sun.tools.javac.util.List<JCAnnotation> makeDpmAnnotations(ExpressionTransformer exprGen) {
    if (factory == null) {
    // A tuple
    // TODO @TupleValue({elements...})
    } else {
        // A sequence
        ListBuffer<JCExpression> lb = ListBuffer.lb();
        for (LiteralAnnotationTerm term : (List<LiteralAnnotationTerm>) (List) elements) {
            lb.add(term.makeLiteral(exprGen));
        }
        JCNewArray array = exprGen.make().NewArray(null, null, lb.toList());
        return factory.makeAtValue(exprGen, null, array);
    }
    return com.sun.tools.javac.util.List.<JCAnnotation>nil();
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) List(java.util.List) ArrayList(java.util.ArrayList) JCNewArray(com.sun.tools.javac.tree.JCTree.JCNewArray) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Aggregations

JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)93 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)64 Name (com.sun.tools.javac.util.Name)35 ListBuffer (com.sun.tools.javac.util.ListBuffer)34 JavacTreeMaker (lombok.javac.JavacTreeMaker)33 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)29 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)29 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)28 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)27 JavacNode (lombok.javac.JavacNode)27 JCTree (com.sun.tools.javac.tree.JCTree)22 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)22 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)21 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)14 JCFieldAccess (com.sun.tools.javac.tree.JCTree.JCFieldAccess)13 JCArrayTypeTree (com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)11 JCIdent (com.sun.tools.javac.tree.JCTree.JCIdent)11 JCMethodInvocation (com.sun.tools.javac.tree.JCTree.JCMethodInvocation)11 JCAssign (com.sun.tools.javac.tree.JCTree.JCAssign)10 ArrayList (java.util.ArrayList)10