Search in sources :

Example 41 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function 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 42 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class LocalTypeVisitor method visit.

@Override
public void visit(Tree.BaseMemberOrTypeExpression that) {
    Declaration model = that.getDeclaration();
    if (model != null && (model instanceof Function || model instanceof Class) && !that.getAssigned() && // if it's a parameter we don't need to wrap it in a class
    !model.isParameter() && (model instanceof Class == false || !that.getStaticMethodReferencePrimary()) && !that.getDirectlyInvoked()) {
        String prefix = this.prefix;
        enterAnonymousClass();
        super.visit(that);
        exitAnonymousClass();
        this.prefix = prefix;
    } else {
        super.visit(that);
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 43 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class LocalTypeVisitor method visit.

@Override
public void visit(Tree.QualifiedMemberOrTypeExpression that) {
    Declaration model = that.getDeclaration();
    if (model != null && (model instanceof Function || model instanceof Class) && !that.getAssigned() && // if it's a parameter we don't need to wrap it in a class
    !model.isParameter() && (model instanceof Class == false || !that.getStaticMethodReferencePrimary()) && !that.getDirectlyInvoked()) {
        String prefix = this.prefix;
        enterAnonymousClass();
        super.visit(that);
        exitAnonymousClass();
        this.prefix = prefix;
    } else {
        super.visit(that);
    }
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 44 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class MethodDefinitionBuilder method getNonWideningParam.

public NonWideningParam getNonWideningParam(TypedReference typedRef, WideningRules wideningRules) {
    TypedDeclaration nonWideningDecl = null;
    int flags = 0;
    long modifiers = 0;
    Type nonWideningType;
    FunctionOrValue mov = (FunctionOrValue) typedRef.getDeclaration();
    if (Decl.isValue(mov)) {
        TypedReference nonWideningTypedRef = gen.nonWideningTypeDecl(typedRef);
        nonWideningType = gen.nonWideningType(typedRef, nonWideningTypedRef).resolveAliases();
        nonWideningDecl = nonWideningTypedRef.getDeclaration();
    } else {
        // Stef: So here's the thing. I know this is wrong for Function where we should do getFullType(), BUT
        // lots of methods call this and then feed the output into AT.makeJavaType(TypedDeclaration typeDecl, Type type, int flags)
        // which adds the Callable type, so if we fix it here we have to remove it from there and there's lots of callers of that
        // function which rely on its behaviour and frankly I've had enough of this refactoring, so a few callers of this function
        // have to add the Callable back. It sucks, yeah, but so far it works, which is amazing enough that I don't want to touch it
        // any more. More ambitious/courageous people are welcome to fix this properly.
        nonWideningType = typedRef.getType().resolveAliases();
        nonWideningDecl = mov;
    }
    if (!CodegenUtil.isUnBoxed(nonWideningDecl))
        flags |= AbstractTransformer.JT_NO_PRIMITIVES;
    // make sure we don't accidentally narrow value parameters that would be erased in the topmost declaration
    if (wideningRules != WideningRules.NONE && mov instanceof Value) {
        TypedDeclaration refinedParameter = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(mov);
        if (refinedParameter != null && refinedParameter instanceof Value && ((Value) refinedParameter).getInitializerParameter() != null && gen.isJavaVariadic(((Value) refinedParameter).getInitializerParameter())) {
            modifiers |= Flags.VARARGS;
        }
        // mixin bridge methods have the same rules as when refining stuff except they are their own refined decl
        if (wideningRules == WideningRules.FOR_MIXIN || !Decl.equal(refinedParameter, mov)) {
            Type refinedParameterType;
            // in the refined parameter type
            if (refinedParameter instanceof Function)
                refinedParameterType = refinedParameter.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType();
            else
                refinedParameterType = refinedParameter.getType();
            // if the supertype method itself got erased to Object, we can't do better than this
            if (gen.willEraseToObject(refinedParameterType) && !gen.willEraseToBestBounds(mov))
                nonWideningType = gen.typeFact().getObjectType();
            else if (CodegenUtil.isRaw(refinedParameter)) {
                flags |= AbstractTransformer.JT_RAW;
            } else {
                flags |= AbstractTransformer.JT_NARROWED;
            }
            if ((flags & AbstractTransformer.JT_RAW) == 0 && !Decl.equal(refinedParameter, mov) && implementsRawParameter(mov)) {
                flags |= AbstractTransformer.JT_RAW;
            }
        }
    }
    // keep in sync with gen.willEraseToBestBounds()
    if (wideningRules != WideningRules.NONE && (gen.typeFact().isUnion(nonWideningType) || gen.typeFact().isIntersection(nonWideningType))) {
        final Type refinedType = ((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(nonWideningDecl)).getType();
        if (refinedType.isTypeParameter() && !refinedType.getSatisfiedTypes().isEmpty()) {
            nonWideningType = refinedType.getSatisfiedTypes().get(0);
            // Could be parameterized, and type param won't be in scope, so have to go raw
            flags |= AbstractTransformer.JT_RAW;
        }
    }
    // this is to be done on the parameter's containing method, to see if that method must have raw parameters
    if (mov.isParameter() && mov.getContainer() instanceof Declaration && gen.rawParameters((Declaration) mov.getContainer())) {
        flags |= AbstractTransformer.JT_RAW;
    }
    return new NonWideningParam(flags, modifiers, nonWideningType, nonWideningDecl);
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 45 with Function

use of org.eclipse.ceylon.model.typechecker.model.Function in project ceylon by eclipse.

the class Naming method quoteMethodNameIfProperty.

private static String quoteMethodNameIfProperty(Function method) {
    String name = method.getName();
    if (!method.isShared()) {
        name = suffixName(Suffix.$priv$, name);
    }
    // Toplevel methods keep their original name because their names might be mangled
    if (method instanceof LazyFunction) {
        return ((LazyFunction) method).getRealName();
    }
    // since local methods have a $getter suffix
    if (!method.isClassOrInterfaceMember())
        return name;
    // do not quote method names if we have a refined constraint
    Function refinedMethod = (Function) method.getRefinedDeclaration();
    if (refinedMethod instanceof JavaMethod) {
        return ((JavaMethod) refinedMethod).getRealName();
    }
    // get/is with at least one more letter, no parameter and non-void type
    if (((name.length() >= 4 && name.startsWith("get")) || name.length() >= 3 && name.startsWith("is")) && // not the total number of parameters
    method.getFirstParameterList().getParameters().isEmpty() && !AbstractTransformer.isAnything(method.getType()))
        return quote(name);
    // set with one parameter and void type
    if ((name.length() >= 4 && name.startsWith("set")) && // not the total number of parameters
    method.getFirstParameterList().getParameters().size() == 1 && AbstractTransformer.isAnything(method.getType()))
        return quote(name);
    return name;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) JavaMethod(org.eclipse.ceylon.model.loader.model.JavaMethod) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction)

Aggregations

Function (org.eclipse.ceylon.model.typechecker.model.Function)167 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)71 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)70 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)69 Type (org.eclipse.ceylon.model.typechecker.model.Type)68 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)62 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)57 Value (org.eclipse.ceylon.model.typechecker.model.Value)50 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)46 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)43 Class (org.eclipse.ceylon.model.typechecker.model.Class)39 ArrayList (java.util.ArrayList)32 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)29 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)26 Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)23 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)23 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)23 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)23 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)22 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)21