Search in sources :

Example 41 with FunctionOrValue

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

the class SpecificationVisitor method visit.

@Override
public void visit(Tree.ClassBody that) {
    if (that.getScope() == declaration.getContainer()) {
        Tree.Statement les = getLastExecutableStatement(that);
        Tree.Declaration lc = getLastConstructor(that);
        declarationSection = les == null;
        lastExecutableStatement = les;
        lastConstructor = lc;
        new Visitor() {

            boolean declarationSection = false;

            @Override
            public void visit(Tree.ExecutableStatement that) {
                super.visit(that);
                if (that == lastExecutableStatement) {
                    declarationSection = true;
                }
            }

            @Override
            public void visit(Tree.Declaration that) {
                super.visit(that);
                if (declarationSection && isSameDeclaration(that)) {
                    definedInDeclarationSection = true;
                }
                if (that == lastExecutableStatement) {
                    declarationSection = true;
                }
            }

            @Override
            public void visit(Tree.StaticMemberOrTypeExpression that) {
                super.visit(that);
                if (declarationSection && declaration instanceof FunctionOrValue && that.getDeclaration() == declaration) {
                    usedInDeclarationSection = true;
                }
            }
        }.visit(that);
        super.visit(that);
        declarationSection = false;
        lastExecutableStatement = null;
        lastConstructor = null;
        if (!declaration.isAnonymous()) {
            if (isSharedDeclarationUninitialized()) {
                Node d = getDeclaration(that);
                if (d == null)
                    d = that;
                d.addError("must be definitely specified by class initializer: " + message(declaration) + explanation(), 1401);
            }
        }
    } else {
        super.visit(that);
    }
}
Also used : Visitor(org.eclipse.ceylon.compiler.typechecker.tree.Visitor) Node(org.eclipse.ceylon.compiler.typechecker.tree.Node) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 42 with FunctionOrValue

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

the class DeclarationVisitor method checkForNativeAnnotation.

private void checkForNativeAnnotation(Tree.Declaration that, Declaration model, Scope scope) {
    Unit unit = model.getUnit();
    if (model.isNative()) {
        Backends mbackends = model.getNativeBackends();
        boolean isHeader = model.isNativeHeader();
        String name = model.getName();
        boolean canBeNative = canBeNative(that);
        if (canBeNative) {
            Backends moduleBackends = unit.getPackage().getModule().getNativeBackends();
            Backends backends = model.getScope().getScopedBackends();
            if (!isHeader && !moduleBackends.none() && !mbackends.supports(moduleBackends)) {
                that.addError("native backend name on declaration conflicts with module descriptor: '\"" + mbackends.names() + "\"' is not '\"" + moduleBackends.names() + "\"' for '" + name + "'");
            } else if (!isHeader && !backends.none() && !backends.supports(mbackends)) {
                that.addError("native backend for declaration conflicts with its scope: native implementation '" + name + "' for '\"" + mbackends.names() + "\"' occurs in a scope which only supports '\"" + backends.names() + "\"'");
            }
            if (isHeader && existImplementations(model)) {
                that.addError("native header must be declared before its implementations: the native header '" + name + "' is declared after an implementation");
            }
            if (model instanceof Interface && ((Interface) model).isAlias()) {
                that.addError("interface alias may not be marked native: '" + name + "' (add a body if a native interface was intended)");
            }
            model.setNativeBackends(mbackends);
            Declaration member = getNativeHeader(model);
            if (member == null || member.isNativeImplementation()) {
                // it's not shared
                if (!isHeader && mustHaveHeader(model) && !moduleBackends.equals(mbackends)) {
                    that.addError("shared native implementation must have a header: '" + model.getName() + "' has no native header");
                }
            }
            if (member == null) {
                if (model.isNativeHeader()) {
                    handleNativeHeader(model, name);
                    if (that instanceof Tree.ObjectDefinition) {
                        Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
                        handleNativeHeader(od.getAnonymousClass(), name);
                    } else if (that instanceof Tree.Constructor) {
                        Tree.Constructor c = (Tree.Constructor) that;
                        handleNativeHeader(c.getConstructor(), name);
                    }
                } else {
                    member = model.getContainer().getDirectMemberForBackend(model.getName(), mbackends);
                    if (member != null && member != model) {
                        that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
                        unit.getDuplicateDeclarations().add(member);
                    }
                }
            } else {
                if (member.isNative()) {
                    List<Declaration> overloads = member.getOverloads();
                    if (isHeader && member.isNativeHeader()) {
                        that.addError("duplicate native header: the header for '" + name + "' is not unique");
                        unit.getDuplicateDeclarations().add(member);
                    } else {
                        Declaration overload = findOverloadForBackend(mbackends, model, overloads);
                        if (overload != null) {
                            that.addError("duplicate native implementation: the implementation '" + name + "' for '\"" + mbackends.names() + "\"' is not unique");
                            unit.getDuplicateDeclarations().add(overload);
                        }
                    }
                    if (isAllowedToChangeModel(member) && !hasModelInOverloads(model, overloads)) {
                        overloads.add(model);
                        if (that instanceof Tree.ObjectDefinition) {
                            Tree.ObjectDefinition od = (Tree.ObjectDefinition) that;
                            Declaration objImplCls = od.getAnonymousClass();
                            Value value = (Value) member;
                            Class objHdrCls = (Class) value.getType().getDeclaration();
                            objHdrCls.getOverloads().add(objImplCls);
                        } else if (that instanceof Tree.Constructor) {
                            Tree.Constructor c = (Tree.Constructor) that;
                            Declaration cd = c.getConstructor();
                            FunctionOrValue fov = (FunctionOrValue) member;
                            Constructor hdr = (Constructor) fov.getType().getDeclaration();
                            hdr.getOverloads().add(cd);
                        }
                    }
                } else {
                    if (isHeader) {
                        that.addError("native header for non-native declaration: '" + name + "' is not declared native");
                    } else {
                        that.addError("native implementation for non-native header: '" + name + "' is not declared native");
                    }
                }
            }
        } else if (!(model instanceof Setter) && !isHeader) {
            if (!canBeNative) {
                that.addError("native declaration is not a class, constructor, method, attribute or object: '" + name + "' may not be annotated 'native'");
            }
        }
    }
}
Also used : ModelUtil.isDefaultConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isDefaultConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Backends(org.eclipse.ceylon.common.Backends) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Class(org.eclipse.ceylon.model.typechecker.model.Class) AnalyzerUtil.isVeryAbstractClass(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.isVeryAbstractClass) ModelUtil.isAnonymousClass(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isAnonymousClass) 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) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 43 with FunctionOrValue

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

the class DeclarationVisitor method handleNativeHeader.

private void handleNativeHeader(Declaration model, String name) {
    // Deal with implementations from the ModelLoader
    ArrayList<FunctionOrValue> loadedFunctionsOrValues = null;
    ArrayList<ClassOrInterface> loadedClasses = null;
    ArrayList<Constructor> loadedConstructors = null;
    for (Backend backendToSearch : Backend.getRegisteredBackends()) {
        Declaration overloadFromModelLoader = model.getContainer().getDirectMemberForBackend(name, backendToSearch.asSet());
        if (overloadFromModelLoader instanceof FunctionOrValue) {
            if (loadedFunctionsOrValues == null) {
                loadedFunctionsOrValues = new ArrayList<FunctionOrValue>();
            }
            FunctionOrValue fov = (FunctionOrValue) overloadFromModelLoader;
            loadedFunctionsOrValues.add(fov);
        } else if (overloadFromModelLoader instanceof ClassOrInterface) {
            if (loadedClasses == null) {
                loadedClasses = new ArrayList<ClassOrInterface>();
            }
            ClassOrInterface c = (ClassOrInterface) overloadFromModelLoader;
            loadedClasses.add(c);
        } else if (overloadFromModelLoader instanceof Constructor) {
            if (loadedConstructors == null) {
                loadedConstructors = new ArrayList<Constructor>();
            }
            Constructor c = (Constructor) overloadFromModelLoader;
            loadedConstructors.add(c);
        }
    }
    // Initialize the header's overloads
    if (model instanceof FunctionOrValue) {
        FunctionOrValue m = (FunctionOrValue) model;
        if (loadedFunctionsOrValues != null) {
            m.initOverloads(loadedFunctionsOrValues.toArray(NO_FUNCTIONS_OR_VALUES));
        } else {
            m.initOverloads();
        }
    } else if (model instanceof ClassOrInterface) {
        ClassOrInterface c = (ClassOrInterface) model;
        if (loadedClasses != null) {
            c.initOverloads(loadedClasses.toArray(NO_CLASSES));
        } else {
            c.initOverloads();
        }
    } else if (model instanceof Constructor) {
        Constructor c = (Constructor) model;
        if (loadedConstructors != null) {
            c.initOverloads(loadedConstructors.toArray(NO_CONSTRUCTORS));
        } else {
            c.initOverloads();
        }
    }
}
Also used : ModelUtil.getContainingClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getContainingClassOrInterface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) Backend(org.eclipse.ceylon.common.Backend) TreeUtil.getNativeBackend(org.eclipse.ceylon.compiler.typechecker.tree.TreeUtil.getNativeBackend) ModelUtil.isDefaultConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isDefaultConstructor) ModelUtil.isConstructor(org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ArrayList(java.util.ArrayList) 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) AnalyzerUtil.getTypeDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)

Example 44 with FunctionOrValue

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

the class ExpressionVisitor method createInferredParameter.

/**
 * Create a model for an inferred parameter of an
 * anonymous function.
 */
private boolean createInferredParameter(Tree.FunctionArgument anon, Declaration declaration, Tree.Parameter ap, Parameter parameter, Type type, FunctionOrValue original, boolean error) {
    if (isTypeUnknown(type)) {
        type = unit.getUnknownType();
        if (!dynamic) {
            if (error) {
                ap.addError("could not infer parameter type: '" + parameter.getName() + "' would have unknown type");
            } else {
                return false;
            }
        }
    } else if (involvesTypeParams(declaration, type)) {
        if (error) {
            type = unit.getUnknownType();
            ap.addError("could not infer parameter type: '" + parameter.getName() + "' would have type '" + type.asString(unit) + "' involving type parameters");
        } else {
            return false;
        }
    }
    Value model = (Value) parameter.getModel();
    if (model == null) {
        model = new Value();
        model.setUnit(unit);
        model.setName(parameter.getName());
        model.setOriginalParameterDeclaration(original);
        parameter.setModel(model);
        Function m = anon.getDeclarationModel();
        model.setContainer(m);
        model.setScope(m);
        m.addMember(model);
    }
    model.setType(type);
    model.setInferred(true);
    if (declaration != null && type != null && declaration.isJava() && !type.isUnknown() && type.isSubtypeOf(unit.getObjectType()) && canHaveUncheckedNulls(type)) {
        model.setUncheckedNullType(true);
    }
    model.setInitializerParameter(parameter);
    if (ap instanceof Tree.ValueParameterDeclaration) {
        Tree.ValueParameterDeclaration vpd = (Tree.ValueParameterDeclaration) ap;
        vpd.getTypedDeclaration().getType().setTypeModel(type);
    }
    return true;
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree)

Example 45 with FunctionOrValue

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

the class ExpressionVisitor method checkPositionalArgument.

private void checkPositionalArgument(Parameter p, Reference pr, Tree.ListedArgument a) {
    FunctionOrValue paramModel = p.getModel();
    if (paramModel != null) {
        a.setParameter(p);
        TypedReference paramRef = pr.getTypedParameterWithWildcardCaputure(p);
        Type paramType = paramType(a.getScope(), paramRef, paramModel);
        Type at = a.getTypeModel();
        if (!isTypeUnknown(at) && !isTypeUnknown(paramType)) {
            checkAssignable(at, paramType, a, "argument must be assignable to parameter " + argdesc(p, pr), 2100);
        }
    }
}
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) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) 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