Search in sources :

Example 6 with JCAnnotation

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.

the class ClassTransformer method transform.

public void transform(Tree.AttributeDeclaration decl, ClassDefinitionBuilder classBuilder) {
    final Value model = decl.getDeclarationModel();
    boolean withinInterface = model.isInterfaceMember();
    Tree.SpecifierOrInitializerExpression initializer = decl.getSpecifierOrInitializerExpression();
    final boolean lazy = initializer instanceof Tree.LazySpecifierExpression;
    String attrName = decl.getIdentifier().getText();
    boolean memoized = Decl.isMemoized(decl);
    boolean isStatic = model.isStatic();
    // Only a non-formal or a concrete-non-lazy attribute has a corresponding field
    // and if a captured class parameter exists with the same name we skip this part as well
    Parameter parameter = CodegenUtil.findParamForDecl(decl);
    boolean useField = !lazy && Strategy.useField(model);
    boolean createField = !lazy && !model.isFormal() && Strategy.createField(parameter, model) && !model.isJavaNative();
    boolean createCompanionField = !lazy && withinInterface && initializer != null;
    JCThrow err = null;
    JCExpression memoizedInitialValue = null;
    if (createCompanionField || createField) {
        TypedReference typedRef = getTypedReference(model);
        TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
        Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
        if (Decl.isIndirect(decl)) {
            attrName = Naming.getAttrClassName(model, 0);
            nonWideningType = getGetterInterfaceType(model);
        }
        JCExpression initialValue = null;
        BoxingStrategy boxingStrategy = null;
        if (initializer != null) {
            Tree.Expression expression = initializer.getExpression();
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getTerm());
            int flags = CodegenUtil.downcastForSmall(expression, model) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
            flags |= model.hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
            if (error != null) {
                initialValue = null;
                err = makeThrowUnresolvedCompilationError(error.getErrorMessage().getMessage());
            } else {
                boxingStrategy = useJavaBox(model, nonWideningType) && javaBoxExpression(expression.getTypeModel(), nonWideningType) ? BoxingStrategy.JAVA : CodegenUtil.getBoxingStrategy(model);
                initialValue = expressionGen().transformExpression(expression, boxingStrategy, isStatic && nonWideningType.isTypeParameter() ? typeFact().getAnythingType() : nonWideningType, flags);
            }
        }
        if (memoized) {
            memoizedInitialValue = initialValue;
            initialValue = makeDefaultExprForType(nonWideningType);
        }
        int flags = 0;
        if (!CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration())) {
            flags |= JT_NO_PRIMITIVES;
        }
        long modifiers = useField ? modifierTransformation().field(decl) : modifierTransformation().localVar(decl);
        // does it in those cases)
        if (parameter == null || parameter.isHidden()) {
            JCExpression type;
            if (isStatic && nonWideningType.isTypeParameter()) {
                type = make().Type(syms().objectType);
            } else {
                type = makeJavaType(nonWideningType, flags);
            }
            if (createCompanionField) {
                classBuilder.getCompanionBuilder((TypeDeclaration) model.getContainer()).field(modifiers, attrName, type, initialValue, !useField);
            } else {
                List<JCAnnotation> annos = makeAtIgnore().prependList(expressionGen().transformAnnotations(OutputElement.FIELD, decl));
                if (classBuilder.hasDelegatingConstructors()) {
                    annos = annos.prependList(makeAtNoInitCheck());
                }
                // fields should be ignored, they are accessed by the getters
                if (err == null) {
                    // TODO This should really be using AttributeDefinitionBuilder somehow
                    if (useField) {
                        AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.field(this, null, attrName, model, Decl.isIndirect(decl)).fieldAnnotations(annos).fieldNullability(makeNullabilityAnnotations(model)).initialValue(initialValue, boxingStrategy).fieldVisibilityModifiers(modifiers).modifiers(modifiers);
                        classBuilder.defs(adb.buildFields());
                        List<JCStatement> buildInit = adb.buildInit(false);
                        if (!buildInit.isEmpty()) {
                            if (isStatic) {
                                classBuilder.defs(make().Block(STATIC, buildInit));
                            } else {
                                classBuilder.getInitBuilder().init(buildInit);
                            }
                        }
                    } else if (!memoized) {
                        classBuilder.field(modifiers, attrName, type, initialValue, !useField, annos);
                        if (!isEe(model) && model.isLate() && CodegenUtil.needsLateInitField(model, typeFact())) {
                            classBuilder.field(PRIVATE | Flags.VOLATILE | Flags.TRANSIENT, Naming.getInitializationFieldName(attrName), make().Type(syms().booleanType), make().Literal(false), false, makeAtIgnore());
                        }
                    }
                }
            }
        }
        // A shared attribute might be initialized in a for statement, so
        // we might need a def-assignment subst for it
        JCStatement outerSubs = statementGen().openOuterSubstitutionIfNeeded(model, model.getType(), 0);
        if (outerSubs != null) {
            classBuilder.getInitBuilder().init(outerSubs);
        }
    }
    if (useField || withinInterface || lazy) {
        boolean generateInClassOrInterface = !withinInterface || model.isShared() || isStatic;
        boolean generateInCompanionClass = withinInterface && lazy && !isStatic;
        if (generateInClassOrInterface) {
            // Generate getter in main class or interface (when shared)
            at(decl.getType());
            AttributeDefinitionBuilder getter = makeGetter(decl, false, memoizedInitialValue);
            if (err != null) {
                getter.getterBlock(make().Block(0, List.<JCStatement>of(err)));
            }
            classBuilder.attribute(getter);
        }
        if (generateInCompanionClass) {
            Interface container = (Interface) model.getContainer();
            // Generate getter in companion class
            classBuilder.getCompanionBuilder(container).attribute(makeGetter(decl, true, null));
        }
        if (Decl.isVariable(model) || model.isLate()) {
            if (generateInClassOrInterface) {
                // Generate setter in main class or interface (when shared)
                classBuilder.attribute(makeSetter(decl, false, memoizedInitialValue));
            }
            if (generateInCompanionClass) {
                Interface container = (Interface) model.getContainer();
                // Generate setter in companion class
                classBuilder.getCompanionBuilder(container).attribute(makeSetter(decl, true, null));
            }
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) JCThrow(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCThrow)

Example 7 with JCAnnotation

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.

the class ClassTransformer method addAtContainer.

private void addAtContainer(ClassDefinitionBuilder classBuilder, TypeDeclaration model) {
    Scope scope = Decl.getNonSkippedContainer((Scope) model);
    Scope declarationScope = Decl.getFirstDeclarationContainer((Scope) model);
    boolean inlineObjectInToplevelAttr = Decl.isTopLevelObjectExpressionType(model);
    if (scope == null || (scope instanceof Package && !inlineObjectInToplevelAttr) && scope == declarationScope)
        return;
    if (scope instanceof ClassOrInterface && scope == declarationScope && !inlineObjectInToplevelAttr && // we do not check for types inside initialiser section which are private and not captured because we treat them as members
    !(model instanceof Interface && Decl.hasLocalNotInitializerAncestor(model))) {
        ClassOrInterface container = (ClassOrInterface) scope;
        List<JCAnnotation> atContainer = makeAtContainer(container.getType(), model.isStatic());
        classBuilder.annotations(atContainer);
    } else {
        if (model instanceof Interface)
            classBuilder.annotations(makeLocalContainerPath((Interface) model));
        Declaration declarationContainer = getDeclarationContainer(model);
        classBuilder.annotations(makeAtLocalDeclaration(model.getQualifier(), declarationContainer == null));
    }
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Package(org.eclipse.ceylon.model.typechecker.model.Package) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)

Example 8 with JCAnnotation

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.

the class ExpressionTransformer method transformAnonymousAnnotation.

public void transformAnonymousAnnotation(Tree.AnonymousAnnotation annotation, Map<Class, ListBuffer<JCAnnotation>> annos) {
    Type docType = ((TypeDeclaration) typeFact().getLanguageModuleDeclaration("DocAnnotation")).getType();
    JCAnnotation docAnnotation = at(annotation).Annotation(makeJavaType(docType, JT_ANNOTATION), List.<JCExpression>of(make().Assign(naming.makeUnquotedIdent("description"), transform(annotation.getStringLiteral()))));
    putAnnotation(annos, docAnnotation, (Class) docType.getDeclaration());
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)

Example 9 with JCAnnotation

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.

the class ExpressionTransformer method transform.

private List<JCAnnotation> transform(Object useSite, OutputElement target, Tree.AnnotationList annotationList, EnumSet<OutputElement> outputs) {
    if (annotationList == null) {
        return List.nil();
    }
    if ((gen().disableAnnotations & CeylonTransformer.DISABLE_USER_ANNOS) != 0) {
        return List.nil();
    }
    LinkedHashMap<Class, ListBuffer<JCAnnotation>> annotationSet = new LinkedHashMap<>();
    if (annotationList != null) {
        if (annotationList.getAnonymousAnnotation() != null && AnnotationUtil.isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("doc"), useSite, target)) {
            transformAnonymousAnnotation(annotationList.getAnonymousAnnotation(), annotationSet);
        }
        if (annotationList.getAnnotations() != null) {
            for (Tree.Annotation annotation : annotationList.getAnnotations()) {
                Function annoCtorDecl = ((Function) ((Tree.BaseMemberExpression) annotation.getPrimary()).getDeclaration());
                if (annoCtorDecl != null) {
                    String aname = annoCtorDecl.getQualifiedNameString();
                    if ("java.lang::transient".equals(aname) || "java.lang::volatile".equals(aname) || "java.lang::synchronized".equals(aname) || "java.lang::native".equals(aname) || "java.lang::strictfp".equals(aname) || "java.lang::overloaded".equals(aname) || "java.lang::nonbean".equals(aname)) {
                        continue;
                    }
                }
                boolean isNaturalTarget = AnnotationUtil.isNaturalTarget(annoCtorDecl, useSite, target);
                EnumSet<OutputElement> possibleTargets = AnnotationUtil.interopAnnotationTargeting(useSite instanceof Declaration ? isEe((Declaration) useSite) : false, outputs, annotation, false, false, useSite instanceof Declaration ? (Declaration) useSite : null);
                if ((isNaturalTarget && possibleTargets == null) || (possibleTargets != null && possibleTargets.equals(EnumSet.of(target)))) {
                    transformAnnotation(annotation, annotationSet);
                }
            }
        }
    }
    ListBuffer<JCAnnotation> result = new ListBuffer<JCAnnotation>();
    for (Class annotationClass : annotationSet.keySet()) {
        ListBuffer<JCAnnotation> annotations = annotationSet.get(annotationClass);
        if (isSequencedAnnotation(annotationClass)) {
            JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(annotationClass.getType(), JT_ANNOTATIONS), List.<JCExpression>of(make().NewArray(null, null, upcastExprList(annotations.toList()))));
            result.append(wrapperAnnotation);
        } else if (isRepeatableAnnotation(annotationClass)) {
            Interface containerAnnotation = getRepeatableContainer(annotationClass);
            JCAnnotation wrapperAnnotation = make().Annotation(makeJavaType(containerAnnotation.appliedType(null, Collections.<Type>emptyList())), List.<JCExpression>of(make().NewArray(null, null, upcastExprList(annotations.toList()))));
            result.append(wrapperAnnotation);
        } else {
            if (annotations.size() > 1) {
                makeErroneous(annotationList, "compiler bug: multiple occurances of non-sequenced annotation class " + annotationClass.getQualifiedNameString());
            }
            result.appendList(annotations);
        }
    }
    // Special case: Generate a @java.lang.Deprecated() if Ceylon deprecated
    if (annotationList != null) {
        for (Tree.Annotation annotation : annotationList.getAnnotations()) {
            if (AnnotationUtil.isNaturalTarget((Function) typeFact().getLanguageModuleDeclaration("deprecated"), useSite, target) && isDeprecatedAnnotation(annotation.getPrimary()) && !(useSite instanceof Function) && !(useSite instanceof Constructor)) {
                result.appendList(makeAtDeprecated());
            }
        }
    }
    return result.toList();
}
Also used : Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) LinkedHashMap(java.util.LinkedHashMap) Function(org.eclipse.ceylon.model.typechecker.model.Function) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) OutputElement(org.eclipse.ceylon.model.loader.model.OutputElement) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 10 with JCAnnotation

use of org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation in project ceylon by eclipse.

the class StatementTransformer method transform.

// FIXME There is a similar implementation in ClassGen!
public List<JCStatement> transform(Tree.AttributeDeclaration decl) {
    ListBuffer<JCStatement> result = new ListBuffer<JCStatement>();
    // If the attribute is really from a parameter then don't generate a local variable
    Parameter parameter = CodegenUtil.findParamForDecl(decl);
    if (parameter == null) {
        final Name attrName = names().fromString(naming.substitute(decl.getDeclarationModel()));
        Type t = decl.getDeclarationModel().getType();
        JCExpression initialValue = null;
        SpecifierOrInitializerExpression initOrSpec = decl.getSpecifierOrInitializerExpression();
        if (initOrSpec != null) {
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(initOrSpec.getExpression().getTerm());
            if (error != null) {
                return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
            }
            int flags = CodegenUtil.downcastForSmall(initOrSpec.getExpression(), decl.getDeclarationModel()) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
            flags |= decl.getDeclarationModel().hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
            initialValue = expressionGen().transformExpression(initOrSpec.getExpression(), CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()), decl.getDeclarationModel().getType(), flags);
        } else if (decl.getDeclarationModel().isVariable()) {
            // Java's definite initialization doesn't always work
            // so give variable attribute declarations without
            // initializers a default value. See #1153.
            initialValue = makeDefaultExprForType(t);
            if (CodegenUtil.getBoxingStrategy(decl.getDeclarationModel()) == BoxingStrategy.BOXED && canUnbox(t)) {
                initialValue = boxType(initialValue, t);
            }
        }
        List<JCAnnotation> annots = List.<JCAnnotation>nil();
        int modifiers = transformLocalFieldDeclFlags(decl);
        JCExpression typeExpr = makeJavaType(decl.getDeclarationModel(), t, modifiers);
        result.append(at(decl.getIdentifier()).VarDef(at(decl.getIdentifier()).Modifiers(modifiers, annots), attrName, typeExpr, initialValue));
        JCStatement outerSubs = openOuterSubstitutionIfNeeded(decl.getDeclarationModel(), t, modifiers);
        if (outerSubs != null) {
            result.append(outerSubs);
        }
    }
    return result.toList();
}
Also used : Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) SpecifierOrInitializerExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Name(org.eclipse.ceylon.langtools.tools.javac.util.Name) CName(org.eclipse.ceylon.compiler.java.codegen.Naming.CName) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName)

Aggregations

JCAnnotation (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation)23 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)14 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)12 ListBuffer (org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer)12 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)7 Type (org.eclipse.ceylon.model.typechecker.model.Type)6 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)6 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)5 HasErrorException (org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException)4 JCStatement (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement)4 JCVariableDecl (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)4 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)4 MethodDeclaration (org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration)3 JCPrimitiveTypeTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree)3 LazyInterface (org.eclipse.ceylon.model.loader.model.LazyInterface)3 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)3 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)3 IOException (java.io.IOException)2 LinkedHashMap (java.util.LinkedHashMap)2