Search in sources :

Example 1 with Functional

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

the class AbstractTransformer method makeJavaTypeAnnotations.

JCTree.JCAnnotation makeJavaTypeAnnotations(TypedDeclaration decl, boolean handleFunctionalParameter) {
    if (decl == null || decl.getType() == null)
        return null;
    Type type;
    if (decl instanceof Function && ((Function) decl).isParameter() && handleFunctionalParameter) {
        type = getTypeForFunctionalParameter((Function) decl);
    } else if (decl instanceof Functional && Decl.isMpl((Functional) decl)) {
        type = getReturnTypeOfCallable(decl.appliedTypedReference(null, Collections.<Type>emptyList()).getFullType());
    } else {
        type = decl.getType();
    }
    boolean declaredVoid = decl instanceof Function && Strategy.useBoxedVoid((Function) decl) && Decl.isUnboxedVoid(decl);
    return makeJavaTypeAnnotations(type, declaredVoid, CodegenUtil.hasTypeErased(decl), CodegenUtil.hasUntrustedType(decl), needsJavaTypeAnnotations(decl, type), decl.hasUncheckedNullType());
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)

Example 2 with Functional

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

the class AbstractTransformer method nonWideningType.

Type nonWideningType(TypedReference declaration, TypedReference refinedDeclaration) {
    final Reference pr;
    if (declaration.equals(refinedDeclaration)) {
        pr = declaration;
    } else {
        Type refinedType = refinedDeclaration.getType();
        // since it may have changed name
        if (refinedType.getDeclaration() instanceof TypeParameter && refinedType.getDeclaration().getContainer() instanceof Function) {
            // find its index in the refined declaration
            TypeParameter refinedTypeParameter = (TypeParameter) refinedType.getDeclaration();
            Function refinedMethod = (Function) refinedTypeParameter.getContainer();
            int i = 0;
            for (TypeParameter tp : refinedMethod.getTypeParameters()) {
                if (tp.getName().equals(refinedTypeParameter.getName()))
                    break;
                i++;
            }
            if (i >= refinedMethod.getTypeParameters().size()) {
                throw new BugException("can't find type parameter " + refinedTypeParameter.getName() + " in its container " + refinedMethod.getName());
            }
            // the refining method type parameter should be at the same index
            if (declaration.getDeclaration() instanceof Function == false)
                throw new BugException("refining declaration is not a method: " + declaration);
            Function refiningMethod = (Function) declaration.getDeclaration();
            if (i >= refiningMethod.getTypeParameters().size()) {
                throw new BugException("refining method does not have enough type parameters to refine " + refinedMethod.getName());
            }
            pr = refiningMethod.getTypeParameters().get(i).getType();
        } else {
            pr = refinedType;
        }
    }
    if (pr.getDeclaration() instanceof Functional && Decl.isMpl((Functional) pr.getDeclaration())) {
        // the innermost Callable.
        return getReturnTypeOfCallable(pr.getFullType());
    }
    return getPinnedType(declaration, pr.getType());
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference)

Example 3 with Functional

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

the class BoxingDeclarationVisitor method setBoxingState.

private void setBoxingState(TypedDeclaration declaration, TypedDeclaration refinedDeclaration, Node that) {
    Type type = declaration.getType();
    if (type == null) {
        // an error must have already been reported
        return;
    }
    // fetch the real refined declaration if required
    if (Decl.equal(declaration, refinedDeclaration) && declaration instanceof FunctionOrValue && ((FunctionOrValue) declaration).isParameter() && declaration.getContainer() instanceof Class) {
        // maybe it is really inherited from a field?
        FunctionOrValue methodOrValueForParam = (FunctionOrValue) declaration;
        if (methodOrValueForParam != null) {
            // make sure we get the refined version of that member
            refinedDeclaration = (TypedDeclaration) methodOrValueForParam.getRefinedDeclaration();
        }
    }
    // inherit underlying type constraints
    if (!Decl.equal(refinedDeclaration, declaration)) {
        // simple case
        if (type.getUnderlyingType() == null && refinedDeclaration.getType() != null) {
            if (type.isCached()) {
                type = type.clone();
            }
            type.setUnderlyingType(refinedDeclaration.getType().getUnderlyingType());
            declaration.setType(type);
        }
        // special case for variadics
        if (Decl.isValueParameter(refinedDeclaration)) {
            Parameter parameter = ((FunctionOrValue) refinedDeclaration).getInitializerParameter();
            if (parameter.isSequenced()) {
                // inherit the underlying type of the iterated type
                Type refinedIteratedType = refinedDeclaration.getType().getTypeArgumentList().get(0);
                if (refinedIteratedType.getUnderlyingType() != null) {
                    Type ourIteratedType = type.getTypeArgumentList().get(0);
                    if (ourIteratedType.getUnderlyingType() == null) {
                        if (ourIteratedType.isCached()) {
                            ourIteratedType = ourIteratedType.clone();
                        }
                        ourIteratedType.setUnderlyingType(refinedIteratedType.getUnderlyingType());
                        type.getTypeArgumentList().set(0, ourIteratedType);
                        // make sure we remove those types from the cache otherwise UGLY things happen
                        TypeCache cache = type.getDeclaration().getUnit().getCache();
                        if (cache != null) {
                            cache.remove(ourIteratedType);
                            cache.remove(type);
                        }
                    }
                }
            }
        }
    }
    // abort if our boxing state has already been set
    if (declaration.getUnboxed() != null)
        return;
    // functional parameter return values are always boxed if we're not creating a method for them
    if (declaration instanceof Function && ((Function) declaration).isParameter() && !JvmBackendUtil.createMethod((Function) declaration)) {
        declaration.setUnboxed(false);
        return;
    }
    if (!Decl.equal(refinedDeclaration, declaration)) {
        // make sure refined declarations have already been set
        if (refinedDeclaration.getUnboxed() == null)
            setBoxingState(refinedDeclaration, refinedDeclaration, that);
        // inherit
        declaration.setUnboxed(refinedDeclaration.getUnboxed());
    } else if (declaration instanceof Function && Strategy.useBoxedVoid((Function) declaration) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
        declaration.setUnboxed(false);
    } else if ((isCeylonBasicType(type) || Decl.isUnboxedVoid(declaration)) && !(refinedDeclaration.getTypeDeclaration() instanceof TypeParameter) && (refinedDeclaration.getContainer() instanceof Declaration == false || !CodegenUtil.isContainerFunctionalParameter(refinedDeclaration)) && !(refinedDeclaration instanceof Functional && Decl.isMpl((Functional) refinedDeclaration))) {
        boolean unbox = !forceBoxedLocals || !(declaration instanceof Value) || !Decl.isLocal(declaration) || Decl.isParameter(declaration) || Decl.isTransient(declaration);
        // until it's used later by user code
        if (declaration.getOriginalDeclaration() != null && declaration.hasUncheckedNullType())
            unbox = false;
        declaration.setUnboxed(unbox);
    } else if (Decl.isValueParameter(declaration) && CodegenUtil.isContainerFunctionalParameter(declaration) && JvmBackendUtil.createMethod((FunctionOrValue) declaration.getContainer())) {
        Function functionalParameter = (Function) declaration.getContainer();
        TypedDeclaration refinedFrom = (TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(functionalParameter, optimisedMethodSpecifiersToMethods);
        if (Decl.equal(refinedFrom, functionalParameter)) {
            // not a method return type (where void would be considered unboxed).
            if (declaration.getUnit().getAnythingType().isExactly(declaration.getType()) || declaration.getUnit().isOptionalType(declaration.getType())) {
                declaration.setUnboxed(false);
            } else {
                declaration.setUnboxed(true);
            }
        } else {
            // make sure refined declarations have already been set
            if (refinedFrom.getUnboxed() == null)
                setBoxingState(refinedFrom, refinedFrom, that);
            // inherit
            declaration.setUnboxed(refinedFrom.getUnboxed());
        }
    } else {
        declaration.setUnboxed(false);
    }
    // Any "@boxed" or "@unboxed" compiler annotation overrides
    boxFromAnnotation(declaration, that);
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AbstractTransformer.isPinnedType(org.eclipse.ceylon.compiler.java.codegen.AbstractTransformer.isPinnedType) Type(org.eclipse.ceylon.model.typechecker.model.Type) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypeCache(org.eclipse.ceylon.model.typechecker.context.TypeCache) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) FunctionalParameterDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionalParameterDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) AttributeDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 4 with Functional

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

the class ClassOrPackageDoc method doc.

protected final void doc(String id, String name, Declaration d) throws IOException {
    String declarationName = Util.getDeclarationName(d);
    id = (id != null ? id : name);
    boolean alias = Util.nullSafeCompare(name, declarationName) != 0;
    // put the id on the td because IE8 doesn't support id attributes on tr (yeah right)
    open("tr");
    open("td id='" + id + "' nowrap");
    writeIcon(d);
    if (!(d instanceof Constructor)) {
        around("code class='decl-label'", name);
        close("td");
        open("td");
    }
    writeLinkOneSelf(id);
    if (alias) {
        writeTagged(d);
        writeAlias(d);
    } else {
        writeLinkSource(d);
        writeTagged(d);
        if (d instanceof Functional) {
            writeParameterLinksIfRequired((Functional) d);
        }
        open("code class='signature'");
        around("span class='modifiers'", getModifiers(d));
        write(" ");
        if (!ModelUtil.isConstructor(d)) {
            if (!Decl.isDynamic(d)) {
                if (d instanceof Functional && ((Functional) d).isDeclaredVoid()) {
                    around("span class='void'", "void");
                } else if (d instanceof TypedDeclaration) {
                    linkRenderer().to(((TypedDeclaration) d).getType()).useScope(d).write();
                } else {
                    linkRenderer().to(d).useScope(d).write();
                }
            } else {
                around("span class='dynamic'", "dynamic");
            }
        }
        write(" ");
        open("span class='identifier'");
        write(name);
        close("span");
        if (isConstantValue(d)) {
            writeConstantValue((Value) d);
        }
        if (d instanceof Generic) {
            writeTypeParameters(d.getTypeParameters(), d);
        }
        if (d instanceof Functional) {
            writeParameterList((Functional) d, d);
        }
        if (d instanceof Generic) {
            writeTypeParametersConstraints(d.getTypeParameters(), d);
        }
        if (d instanceof Value) {
            Setter setter = ((Value) d).getSetter();
            if (setter != null && Util.getAnnotation(setter.getUnit(), setter.getAnnotations(), "doc") != null) {
                tool.warningSetterDoc(d.getQualifiedNameString(), d);
            }
        }
        close("code");
        writeDescription(d);
    }
    close("td");
    close("tr");
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Generic(org.eclipse.ceylon.model.typechecker.model.Generic) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) Setter(org.eclipse.ceylon.model.typechecker.model.Setter)

Example 5 with Functional

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

the class ClassOrPackageDoc method getParametersAssertions.

private Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> getParametersAssertions(final Declaration decl) {
    final Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> parametersAssertions = new LinkedHashMap<Parameter, Map<Tree.Assertion, List<Tree.Condition>>>();
    if (((Functional) decl).getParameterLists().isEmpty()) {
        return parametersAssertions;
    }
    Node node = tool.getNode(decl);
    PhasedUnit pu = tool.getUnit(decl);
    if (node == null || pu == null) {
        return parametersAssertions;
    }
    Tree.Body body = null;
    if (node instanceof Tree.MethodDefinition) {
        body = ((Tree.MethodDefinition) node).getBlock();
    } else if (node instanceof Tree.ClassDefinition) {
        body = ((Tree.ClassDefinition) node).getClassBody();
    }
    if (body == null) {
        return parametersAssertions;
    }
    final Map<String, Parameter> parametersNames = new HashMap<String, Parameter>();
    for (ParameterList parameterList : ((Functional) decl).getParameterLists()) {
        for (Parameter parameter : parameterList.getParameters()) {
            parametersNames.put(parameter.getName(), parameter);
        }
    }
    body.visitChildren(new Visitor() {

        private boolean stop = false;

        private Tree.Assertion assertion = null;

        private Set<Parameter> referencedParameters = new HashSet<Parameter>();

        @Override
        public void visit(Tree.Assertion that) {
            assertion = that;
            super.visit(that);
            assertion = null;
        }

        @Override
        public void visit(Tree.Condition that) {
            referencedParameters.clear();
            super.visit(that);
            if (assertion != null && !referencedParameters.isEmpty()) {
                for (Parameter referencedParameter : referencedParameters) {
                    Map<Tree.Assertion, List<Tree.Condition>> parameterAssertions = parametersAssertions.get(referencedParameter);
                    if (parameterAssertions == null) {
                        parameterAssertions = new LinkedHashMap<Tree.Assertion, List<Tree.Condition>>();
                        parametersAssertions.put(referencedParameter, parameterAssertions);
                    }
                    List<Tree.Condition> parameterConditions = parameterAssertions.get(assertion);
                    if (parameterConditions == null) {
                        parameterConditions = new ArrayList<Tree.Condition>();
                        parameterAssertions.put(assertion, parameterConditions);
                    }
                    parameterConditions.add(that);
                }
            }
        }

        @Override
        public void visit(Tree.BaseMemberExpression that) {
            if (assertion != null) {
                Declaration d = that.getDeclaration();
                Scope realScope = org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope(d.getScope());
                if (parametersNames.containsKey(d.getName()) && realScope == decl) {
                    referencedParameters.add(parametersNames.get(d.getName()));
                }
            }
            super.visit(that);
        }

        @Override
        public void visit(Tree.Statement that) {
            if (assertion == null) {
                stop = true;
            }
            super.visit(that);
        }

        @Override
        public void visitAny(Node that) {
            if (!stop) {
                super.visitAny(that);
            }
        }
    });
    return parametersAssertions;
}
Also used : Visitor(org.eclipse.ceylon.compiler.typechecker.tree.Visitor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) PhasedUnit(org.eclipse.ceylon.compiler.typechecker.context.PhasedUnit) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) List(java.util.List) Util.findBottomMostRefinedDeclaration(org.eclipse.ceylon.ceylondoc.Util.findBottomMostRefinedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) HashSet(java.util.HashSet) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Aggregations

Functional (org.eclipse.ceylon.model.typechecker.model.Functional)58 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)30 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)28 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)28 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)25 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)24 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)24 Type (org.eclipse.ceylon.model.typechecker.model.Type)22 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)13 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)13 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)12 Value (org.eclipse.ceylon.model.typechecker.model.Value)12 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)11 Class (org.eclipse.ceylon.model.typechecker.model.Class)11 Function (org.eclipse.ceylon.model.typechecker.model.Function)11 Reference (org.eclipse.ceylon.model.typechecker.model.Reference)11 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)10 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)9 AnalyzerUtil.checkCasesDisjoint (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.checkCasesDisjoint)8