Search in sources :

Example 1 with FunctionOrValue

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

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

the class CallableBuilder method getParameterTypesFromParameterModels.

private java.util.List<Type> getParameterTypesFromParameterModels() {
    java.util.List<Type> parameterTypes = new ArrayList<Type>(numParams);
    // get them from our declaration
    for (Parameter p : paramLists.getParameters()) {
        Type pt;
        FunctionOrValue pm = p.getModel();
        if (pm instanceof Function && ((Function) pm).isParameter())
            pt = gen.getTypeForFunctionalParameter((Function) pm);
        else
            pt = p.getType();
        parameterTypes.add(pt);
    }
    return parameterTypes;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Type(org.eclipse.ceylon.model.typechecker.model.Type) ArrayList(java.util.ArrayList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 3 with FunctionOrValue

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

the class ExpressionVisitor method accountForIntermediateRefinements.

private Reference accountForIntermediateRefinements(Tree.SpecifierStatement that, FunctionOrValue refinedMethodOrValue, FunctionOrValue methodOrValue, ClassOrInterface refiningType, List<Declaration> interveningRefinements) {
    // accumulate an intersection of the types of
    // everything it refines
    List<Type> refinedTypes = new ArrayList<Type>();
    // don't check this one here because it is
    // separately checked in visit(SpecifierStatement)
    Reference refinedProducedReference = getRefinedMemberReference(refinedMethodOrValue, refiningType);
    Map<TypeParameter, Type> substs = substitutions(refinedMethodOrValue, methodOrValue);
    Type refinedType = refinedProducedReference.getType().substitute(substs, null);
    boolean allHaveNulls = hasNullReturnValues(refinedType, refinedMethodOrValue);
    intersectReturnType(refinedTypes, refinedType);
    for (Declaration intervening : interveningRefinements) {
        if (intervening instanceof FunctionOrValue && // factors here as well?
        !refinedMethodOrValue.equals(intervening)) {
            FunctionOrValue refinement = (FunctionOrValue) intervening;
            Reference refinedMember = getRefinedMemberReference(refinement, refiningType);
            Map<TypeParameter, Type> subs = substitutions(refinement, methodOrValue);
            Type type = refinedMember.getType().substitute(subs, null);
            allHaveNulls = allHaveNulls && hasNullReturnValues(type, refinement);
            intersectReturnType(refinedTypes, type);
            checkIntermediateRefinement(that, refinement, refinedMember);
        }
    }
    Type it = canonicalIntersection(refinedTypes, unit);
    if (allHaveNulls && !unit.isOptionalType(it)) {
        methodOrValue.setUncheckedNullType(true);
        Tree.Term lhs = that.getBaseMemberExpression();
        // TODO: this is pretty ugly, think of something better!
        lhs.setTypeModel(unit.getOptionalType(lhs.getTypeModel()));
    }
    methodOrValue.setType(it);
    return refinedProducedReference;
}
Also used : ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) ArrayList(java.util.ArrayList) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) AnalyzerUtil.getPackageTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) ModelUtil.getNativeDeclaration(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getNativeDeclaration) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 4 with FunctionOrValue

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

the class ExpressionVisitor method checkNamedArgument.

private void checkNamedArgument(Tree.NamedArgument arg, Reference reference, Parameter param) {
    arg.setParameter(param);
    Type argType = null;
    if (arg instanceof Tree.SpecifiedArgument) {
        Tree.SpecifiedArgument sa = (Tree.SpecifiedArgument) arg;
        Tree.Expression e = sa.getSpecifierExpression().getExpression();
        if (e != null) {
            argType = e.getTypeModel();
        }
    } else if (arg instanceof Tree.TypedArgument) {
        Tree.TypedArgument typedArg = (Tree.TypedArgument) arg;
        TypedDeclaration argDec = typedArg.getDeclarationModel();
        argType = argumentType(arg.getScope(), argDec);
        checkArgumentToVoidParameter(param, typedArg);
        if (!dynamic && isTypeUnknown(argType) && !hasError(arg)) {
            arg.addError("could not determine type of named argument: the type of '" + param.getName() + "' is not known");
        }
    }
    FunctionOrValue paramModel = param.getModel();
    if (paramModel != null) {
        TypedReference paramRef = reference.getTypedParameter(param);
        Type paramType = paramType(arg.getScope(), paramRef, paramModel);
        if (!isTypeUnknown(argType) && !isTypeUnknown(paramType)) {
            Node node;
            if (arg instanceof Tree.SpecifiedArgument) {
                Tree.SpecifiedArgument specifiedArg = (Tree.SpecifiedArgument) arg;
                node = specifiedArg.getSpecifierExpression();
            } else {
                node = arg;
            }
            checkAssignable(argType, paramType, node, "named argument must be assignable to parameter " + argdesc(param, reference), 2100);
        }
    }
}
Also used : AnalyzerUtil.getPackageTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypedDeclaration) AnalyzerUtil.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) ModelUtil.unionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType) AnalyzerUtil.spreadType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType) AnalyzerUtil.getTupleType(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) ModelUtil.genericFunctionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 5 with FunctionOrValue

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

the class ExpressionVisitor method createInferredDynamicParameter.

private void createInferredDynamicParameter(Function m, Parameter pm) {
    FunctionOrValue model = pm.getModel();
    if (model == null) {
        Value value = (Value) model;
        value = new Value();
        value.setUnit(unit);
        value.setName(pm.getName());
        pm.setModel(value);
        value.setContainer(m);
        value.setScope(m);
        m.addMember(value);
        value.setType(unit.getUnknownType());
        // value.setDynamic(true);
        value.setDynamicallyTyped(true);
        value.setInferred(true);
        value.setInitializerParameter(pm);
    }
}
Also used : Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Aggregations

FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)28 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)27 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)26 Type (org.eclipse.ceylon.model.typechecker.model.Type)25 Value (org.eclipse.ceylon.model.typechecker.model.Value)24 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)22 Function (org.eclipse.ceylon.model.typechecker.model.Function)22 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)21 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)19 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)13 ArrayList (java.util.ArrayList)12 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)11 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)10 AnalyzerUtil.getTupleType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTupleType)9 AnalyzerUtil.spreadType (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.spreadType)9 ModelUtil.appliedType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType)9 ModelUtil.genericFunctionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.genericFunctionType)9 ModelUtil.intersectionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType)9 ModelUtil.unionType (org.eclipse.ceylon.model.typechecker.model.ModelUtil.unionType)9