Search in sources :

Example 41 with ListBuffer

use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.

the class AbstractTransformer method makeAtLocalDeclarations.

private List<JCAnnotation> makeAtLocalDeclarations(Set<String> localDeclarations, Set<Interface> localInterfaces) {
    if (localDeclarations.isEmpty() && localInterfaces.isEmpty())
        return List.nil();
    ListBuffer<JCExpression> array = new ListBuffer<JCTree.JCExpression>();
    // sort them to get the same behaviour on every JDK
    SortedSet<String> sortedNames = new TreeSet<String>();
    sortedNames.addAll(localDeclarations);
    for (Interface iface : localInterfaces) {
        sortedNames.add("::" + naming.makeTypeDeclarationName(iface));
    }
    for (String val : sortedNames) array.add(make().Literal(val));
    JCExpression attr = make().Assign(naming.makeUnquotedIdent("value"), make().NewArray(null, null, array.toList()));
    return makeModelAnnotation(syms().ceylonAtLocalDeclarationsType, List.of(attr));
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TreeSet(java.util.TreeSet) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Example 42 with ListBuffer

use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.

the class AbstractTransformer method getLicenseAuthorsDocAnnotationArguments.

/** Returns a ListBuffer with assignment expressions for the doc, license and by arguments, as well as name,
     * to be used in an annotation which requires them (such as Module and Package) */
ListBuffer<JCExpression> getLicenseAuthorsDocAnnotationArguments(String name, java.util.List<Annotation> anns) {
    ListBuffer<JCExpression> authors = new ListBuffer<JCTree.JCExpression>();
    ListBuffer<JCExpression> res = new ListBuffer<JCExpression>();
    res.add(make().Assign(naming.makeUnquotedIdent("name"), make().Literal(name)));
    for (Annotation a : anns) {
        if (a.getPositionalArguments() != null && !a.getPositionalArguments().isEmpty()) {
            if (a.getName().equals("doc")) {
                res.add(make().Assign(naming.makeUnquotedIdent("doc"), make().Literal(a.getPositionalArguments().get(0))));
            } else if (a.getName().equals("license")) {
                res.add(make().Assign(naming.makeUnquotedIdent("license"), make().Literal(a.getPositionalArguments().get(0))));
            } else if (a.getName().equals("by")) {
                for (String author : a.getPositionalArguments()) {
                    authors.add(make().Literal(author));
                }
            }
        }
    }
    if (!authors.isEmpty()) {
        res.add(make().Assign(naming.makeUnquotedIdent("by"), make().NewArray(null, null, authors.toList())));
    }
    return res;
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) LanguageAnnotation(com.redhat.ceylon.model.loader.LanguageAnnotation) Annotation(com.redhat.ceylon.model.typechecker.model.Annotation) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation)

Example 43 with ListBuffer

use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.

the class AbstractTransformer method makeAtLocalContainer.

protected List<JCAnnotation> makeAtLocalContainer(List<String> path, String companionClassName) {
    if (path.isEmpty())
        return List.nil();
    ListBuffer<JCExpression> array = new ListBuffer<JCTree.JCExpression>();
    for (String val : path) array.add(make().Literal(val));
    JCExpression pathAttr = make().Assign(naming.makeUnquotedIdent("path"), make().NewArray(null, null, array.toList()));
    JCExpression companionAttr = make().Assign(naming.makeUnquotedIdent("companionClassName"), make().Literal(companionClassName == null ? "" : companionClassName));
    return makeModelAnnotation(syms().ceylonAtLocalContainerType, List.of(pathAttr, companionAttr));
}
Also used : JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree)

Example 44 with ListBuffer

use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.

the class AbstractTransformer method makeTupleTypeDescriptor.

private JCExpression makeTupleTypeDescriptor(Type pt, boolean firstElementOptional) {
    java.util.List<Type> tupleElementTypes = typeFact().getTupleElementTypes(pt);
    boolean isVariadic = typeFact().isTupleLengthUnbounded(pt);
    boolean atLeastOne = false;
    boolean needsRestSplit = false;
    Type restType = null;
    if (isVariadic) {
        // unwrap the last element
        restType = tupleElementTypes.get(tupleElementTypes.size() - 1);
        // to optimise
        if (restType.isUnknown())
            return null;
        tupleElementTypes.set(tupleElementTypes.size() - 1, typeFact.getSequentialElementType(restType));
        atLeastOne = restType.getDeclaration().inherits(typeFact().getSequenceDeclaration());
        // the last rest element may be a type param, in which case we resolve it at runtime
        needsRestSplit = !restType.getDeclaration().equals(typeFact.getSequenceDeclaration()) && !restType.getDeclaration().equals(typeFact.getSequentialDeclaration());
    }
    int firstDefaulted;
    if (!firstElementOptional) {
        // only do this crazy computation if the first element is not optional (case of []|[A] which is a union type really)
        int minimumLength = typeFact().getTupleMinimumLength(pt);
        // [B+] -> 1
        if (atLeastOne)
            minimumLength--;
        // [A,B=] -> 1
        // [A=,B*] -> 0
        // [A,B+] -> 1
        // [B*] -> 0
        // [B+] -> 0
        // [A,B=] -> 2
        // [A=,B*] -> 1
        // [A,B+] -> 1
        // [B*] -> 0
        // [B+] -> 0
        int nonVariadicParams = tupleElementTypes.size();
        if (isVariadic)
            nonVariadicParams--;
        // [A,B=] -> 2!=1 -> 1
        // [A=,B*] -> 1!=0 -> 0
        // [A,B+] -> 1==1 -> -1
        // [B*] -> 0==0 -> -1
        // [B+] -> 0==0 -> -1
        firstDefaulted = nonVariadicParams != minimumLength ? minimumLength : -1;
    } else {
        firstDefaulted = 0;
    }
    JCExpression restTypeDescriptor = null;
    JCExpression restElementTypeDescriptor = null;
    if (needsRestSplit) {
        Type restElementType = tupleElementTypes.get(tupleElementTypes.size() - 1);
        tupleElementTypes.remove(tupleElementTypes.size() - 1);
        restTypeDescriptor = makeReifiedTypeArgumentResolved(restType, false);
        restElementTypeDescriptor = makeReifiedTypeArgumentResolved(restElementType, false);
    }
    ListBuffer<JCExpression> args = new ListBuffer<JCExpression>();
    if (needsRestSplit) {
        args.append(restTypeDescriptor);
        args.append(restElementTypeDescriptor);
    } else {
        args.append(makeBoolean(isVariadic));
        args.append(makeBoolean(atLeastOne));
    }
    args.append(makeInteger(firstDefaulted));
    for (Type element : tupleElementTypes) {
        args.append(makeReifiedTypeArgumentResolved(element, false));
    }
    JCExpression tupleDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), needsRestSplit ? "tupleWithRest" : "tuple"), args.toList());
    return tupleDescriptor;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) ListBuffer(com.sun.tools.javac.util.ListBuffer)

Example 45 with ListBuffer

use of com.sun.tools.javac.util.ListBuffer in project ceylon-compiler by ceylon.

the class ClassTransformer method transformObject.

private List<JCTree> transformObject(Node def, Tree.Declaration annotated, Tree.SatisfiedTypes satisfiesTypes, Value model, Class klass, ClassDefinitionBuilder containingClassBuilder, boolean makeLocalInstance) {
    naming.clearSubstitutions(klass);
    String name = klass.getName();
    String javaClassName = Naming.quoteClassName(name);
    ClassDefinitionBuilder objectClassBuilder = ClassDefinitionBuilder.object(this, javaClassName, name, Decl.isLocal(klass)).forDefinition(klass);
    if (Strategy.introduceJavaIoSerializable(klass, typeFact().getJavaIoSerializable())) {
        objectClassBuilder.introduce(make().QualIdent(syms().serializableType.tsym));
        if (def instanceof Tree.ObjectDefinition && klass.isMember() && (klass.isShared() || klass.isCaptured() || model.isCaptured())) {
            addWriteReplace(klass, objectClassBuilder);
        }
    }
    makeReadResolve(objectClassBuilder, klass, model);
    // Make sure top types satisfy reified type
    addReifiedTypeInterface(objectClassBuilder, klass);
    if (supportsReifiedAlias(klass))
        objectClassBuilder.reifiedAlias(klass.getType());
    CeylonVisitor visitor = gen().visitor;
    final ListBuffer<JCTree> prevDefs = visitor.defs;
    final boolean prevInInitializer = visitor.inInitializer;
    final ClassDefinitionBuilder prevClassBuilder = visitor.classBuilder;
    List<JCStatement> childDefs;
    try {
        visitor.defs = new ListBuffer<JCTree>();
        visitor.inInitializer = true;
        visitor.classBuilder = objectClassBuilder;
        def.visitChildren(visitor);
        childDefs = (List<JCStatement>) visitor.getResult().toList();
    } finally {
        visitor.classBuilder = prevClassBuilder;
        visitor.inInitializer = prevInInitializer;
        visitor.defs = prevDefs;
    }
    addMissingUnrefinedMembers(def, klass, objectClassBuilder);
    satisfaction(satisfiesTypes, klass, objectClassBuilder);
    serialization(klass, objectClassBuilder);
    if (model != null && Decl.isToplevel(model) && def instanceof Tree.ObjectDefinition) {
        // generate a field and getter
        AttributeDefinitionBuilder builder = AttributeDefinitionBuilder.wrapped(this, null, objectClassBuilder, model.getName(), model, true).userAnnotations(makeAtIgnore()).userAnnotationsSetter(makeAtIgnore()).immutable().initialValue(makeNewClass(naming.makeName(model, Naming.NA_FQ | Naming.NA_WRAPPER))).is(PUBLIC, Decl.isShared(klass)).is(STATIC, true);
        if (annotated != null) {
            builder.fieldAnnotations(expressionGen().transformAnnotations(OutputElement.FIELD, annotated));
            builder.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, annotated));
        }
        objectClassBuilder.defs(builder.build());
    }
    if (annotated != null) {
        objectClassBuilder.annotations(expressionGen().transformAnnotations(OutputElement.TYPE, annotated));
        objectClassBuilder.getInitBuilder().userAnnotations(expressionGen().transformAnnotations(OutputElement.CONSTRUCTOR, annotated));
    }
    // make sure we set the container in case we move it out
    addAtContainer(objectClassBuilder, klass);
    objectClassBuilder.annotations(makeAtObject()).satisfies(klass.getSatisfiedTypes()).defs((List) childDefs);
    objectClassBuilder.getInitBuilder().modifiers(PRIVATE);
    objectClassBuilder.addGetTypeMethod(klass.getType());
    if (model != null)
        objectClassBuilder.modelAnnotations(model.getAnnotations()).modifiers(transformObjectDeclFlags(model));
    List<JCTree> result = objectClassBuilder.build();
    if (makeLocalInstance) {
        if (model.isSelfCaptured()) {
            // if it's captured we need to box it and define the var before the class, so it can access it
            JCNewClass newInstance = makeNewClass(objectClassBuilder.getClassName(), false, null);
            JCFieldAccess setter = naming.makeSelect(Naming.getLocalValueName(model), Naming.getSetterName(model));
            JCStatement assign = make().Exec(make().Assign(setter, newInstance));
            result = result.prepend(assign);
            JCVariableDecl localDecl = makeVariableBoxDecl(null, model);
            result = result.prepend(localDecl);
        } else {
            // not captured, we can define the var after the class
            JCVariableDecl localDecl = makeLocalIdentityInstance(name, objectClassBuilder.getClassName(), false);
            result = result.append(localDecl);
        }
    } else if (model != null && Decl.withinClassOrInterface(model)) {
        boolean generateGetter = Decl.isCaptured(model);
        JCExpression type = makeJavaType(klass.getType());
        if (generateGetter) {
            int modifiers = TRANSIENT | PRIVATE;
            JCExpression initialValue = makeNull();
            containingClassBuilder.field(modifiers, name, type, initialValue, false);
            AttributeDefinitionBuilder getter = AttributeDefinitionBuilder.getter(this, name, model).modifiers(transformAttributeGetSetDeclFlags(model, false));
            if (def instanceof Tree.ObjectDefinition) {
                getter.userAnnotations(expressionGen().transformAnnotations(OutputElement.GETTER, ((Tree.ObjectDefinition) def)));
            }
            ListBuffer<JCStatement> stmts = ListBuffer.<JCStatement>lb();
            stmts.add(make().If(make().Binary(JCTree.EQ, naming.makeUnquotedIdent(Naming.quoteFieldName(name)), makeNull()), make().Exec(make().Assign(naming.makeUnquotedIdent(Naming.quoteFieldName(name)), makeNewClass(makeJavaType(klass.getType()), null))), null));
            stmts.add(make().Return(naming.makeUnquotedIdent(Naming.quoteFieldName(name))));
            getter.getterBlock(make().Block(0, stmts.toList()));
            result = result.appendList(getter.build());
        } else {
            int modifiers = FINAL;
            JCExpression initialValue = makeNewClass(makeJavaType(klass.getType()), null);
            containingClassBuilder.field(modifiers, name, type, initialValue, true);
        }
    }
    return result;
}
Also used : JCFieldAccess(com.sun.tools.javac.tree.JCTree.JCFieldAccess) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCTree(com.sun.tools.javac.tree.JCTree) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass)

Aggregations

ListBuffer (com.sun.tools.javac.util.ListBuffer)88 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)54 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)25 JCVariableDecl (com.sun.tools.javac.tree.JCTree.JCVariableDecl)25 JCTree (com.sun.tools.javac.tree.JCTree)22 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)22 Name (com.sun.tools.javac.util.Name)19 JavacNode (lombok.javac.JavacNode)18 JCAnnotation (com.sun.tools.javac.tree.JCTree.JCAnnotation)17 JCBlock (com.sun.tools.javac.tree.JCTree.JCBlock)17 JavacTreeMaker (lombok.javac.JavacTreeMaker)17 JCMethodDecl (com.sun.tools.javac.tree.JCTree.JCMethodDecl)14 Type (com.redhat.ceylon.model.typechecker.model.Type)12 JCClassDecl (com.sun.tools.javac.tree.JCTree.JCClassDecl)12 JCModifiers (com.sun.tools.javac.tree.JCTree.JCModifiers)11 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)8 List (com.sun.tools.javac.util.List)7 ArrayList (java.util.ArrayList)7 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)6 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)6