Search in sources :

Example 1 with Specification

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

the class CodegenUtil method isContainerFunctionalParameter.

public static boolean isContainerFunctionalParameter(Declaration declaration) {
    Scope containerScope = declaration.getContainer();
    Declaration containerDeclaration;
    if (containerScope instanceof Specification) {
        containerDeclaration = ((Specification) containerScope).getDeclaration();
    } else if (containerScope instanceof Declaration) {
        containerDeclaration = (Declaration) containerScope;
    } else {
        // probably invalid user code
        return false;
    }
    return containerDeclaration instanceof Function && ((Function) containerDeclaration).isParameter();
}
Also used : Function(org.eclipse.ceylon.model.typechecker.model.Function) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Specification(org.eclipse.ceylon.model.typechecker.model.Specification) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration)

Example 2 with Specification

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

the class JvmBackendUtil method getTopmostRefinedDeclaration.

public static Declaration getTopmostRefinedDeclaration(Declaration decl, Map<Function, Function> methodOverrides) {
    if (decl instanceof FunctionOrValue && ((FunctionOrValue) decl).isParameter() && decl.getContainer() instanceof Class) {
        // Parameters in a refined class are not considered refinements themselves
        // We have in find the refined attribute
        Class c = (Class) decl.getContainer();
        boolean isAlias = c.isAlias();
        boolean isActual = c.isActual();
        // boxing and stuff
        if (isAlias || isActual) {
            Functional ctor = null;
            int index = c.getParameterList().getParameters().indexOf(findParamForDecl(((TypedDeclaration) decl)));
            // Note(Stef): not entirely sure about that one, what about aliases of actual classes?
            while ((isAlias && c.isAlias()) || (isActual && c.isActual())) {
                ctor = (isAlias && c.isAlias()) ? (Functional) ((ClassAlias) c).getConstructor() : c;
                Type et = c.getExtendedType();
                c = et != null && et.isClass() ? (Class) et.getDeclaration() : null;
                // handle compile errors
                if (c == null)
                    return null;
            }
            if (isActual) {
                ctor = c;
            }
            // be safe
            if (ctor == null || ctor.getParameterLists() == null || ctor.getParameterLists().isEmpty() || ctor.getFirstParameterList() == null || ctor.getFirstParameterList().getParameters() == null || ctor.getFirstParameterList().getParameters().size() <= index)
                return null;
            decl = ctor.getFirstParameterList().getParameters().get(index).getModel();
        }
        if (decl.isShared()) {
            Declaration refinedDecl = c.getRefinedMember(decl.getName(), getSignature(decl), isVariadic(decl));
            if (refinedDecl != null && !ModelUtil.equal(refinedDecl, decl)) {
                return getTopmostRefinedDeclaration(refinedDecl, methodOverrides);
            }
        }
        return decl;
    } else if (decl instanceof FunctionOrValue && // a parameter
    ((FunctionOrValue) decl).isParameter() && (// that's not parameter of a functional parameter
    (decl.getContainer() instanceof Function && !(((Function) decl.getContainer()).isParameter())) || // or is a parameter in a specification
    decl.getContainer() instanceof Specification || (decl.getContainer() instanceof Function && ((Function) decl.getContainer()).isParameter() && createMethod((Function) decl.getContainer())))) {
        // or is a class functional parameter
        // Parameters in a refined method are not considered refinements themselves
        // so we have to look up the corresponding parameter in the container's refined declaration
        Functional func = (Functional) getParameterized((FunctionOrValue) decl);
        if (func == null)
            return decl;
        Declaration kk = getTopmostRefinedDeclaration((Declaration) func, methodOverrides);
        // error recovery
        if (kk instanceof Functional == false)
            return decl;
        Functional refinedFunc = (Functional) kk;
        // shortcut if the functional doesn't override anything
        if (ModelUtil.equal((Declaration) refinedFunc, (Declaration) func)) {
            return decl;
        }
        if (func.getParameterLists().size() != refinedFunc.getParameterLists().size()) {
            // invalid input
            return decl;
        }
        for (int ii = 0; ii < func.getParameterLists().size(); ii++) {
            if (func.getParameterLists().get(ii).getParameters().size() != refinedFunc.getParameterLists().get(ii).getParameters().size()) {
                // invalid input
                return decl;
            }
            // find the index of the parameter in the declaration
            int index = 0;
            for (Parameter px : func.getParameterLists().get(ii).getParameters()) {
                if (px.getModel() == null || px.getModel().equals(decl)) {
                    // And return the corresponding parameter from the refined declaration
                    return refinedFunc.getParameterLists().get(ii).getParameters().get(index).getModel();
                }
                index++;
            }
            continue;
        }
    } else if (methodOverrides != null && decl instanceof Function && ModelUtil.equal(decl.getRefinedDeclaration(), decl) && decl.getContainer() instanceof Specification && ((Specification) decl.getContainer()).getDeclaration() instanceof Function && ((Function) ((Specification) decl.getContainer()).getDeclaration()).isShortcutRefinement() && // hash lookup we do next to make sure it is really one of those cases
    methodOverrides.containsKey(decl)) {
        // special case for class X() extends T(){ m = function() => e; } which we inline
        decl = methodOverrides.get(decl);
    }
    Declaration refinedDecl = decl.getRefinedDeclaration();
    if (refinedDecl != null && !ModelUtil.equal(refinedDecl, decl))
        return getTopmostRefinedDeclaration(refinedDecl);
    return decl;
}
Also used : Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) VisibilityType(org.eclipse.ceylon.model.cmr.VisibilityType) ArtifactResultType(org.eclipse.ceylon.model.cmr.ArtifactResultType) Type(org.eclipse.ceylon.model.typechecker.model.Type) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) Specification(org.eclipse.ceylon.model.typechecker.model.Specification) 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 3 with Specification

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

the class RefinementVisitor method refineMethod.

private void refineMethod(Function assignedMethod, Tree.BaseMemberExpression bme, Tree.SpecifierStatement that, ClassOrInterface c) {
    if (!assignedMethod.isFormal() && !assignedMethod.isDefault() && !assignedMethod.isShortcutRefinement()) {
        // this condition is here to squash a dupe message
        bme.addError("inherited method may not be refined: " + message(assignedMethod) + " is declared neither 'formal' nor 'default'", 510);
    // return;
    }
    ClassOrInterface ci = (ClassOrInterface) assignedMethod.getContainer();
    String name = assignedMethod.getName();
    List<Type> signature = getSignature(assignedMethod);
    boolean variadic = isVariadic(assignedMethod);
    Declaration refined = ci.getRefinedMember(name, signature, variadic);
    Function root = refined instanceof Function ? (Function) refined : assignedMethod;
    Reference rm = getRefinedMemberReference(assignedMethod, c);
    Function method = new Function();
    method.setName(name);
    List<Tree.ParameterList> paramLists;
    List<TypeParameter> typeParams;
    Tree.Term me = that.getBaseMemberExpression();
    if (me instanceof Tree.ParameterizedExpression) {
        Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) me;
        paramLists = pe.getParameterLists();
        Tree.TypeParameterList typeParameterList = pe.getTypeParameterList();
        if (typeParameterList != null) {
            typeParams = new ArrayList<TypeParameter>();
            for (Tree.TypeParameterDeclaration tpd : typeParameterList.getTypeParameterDeclarations()) {
                typeParams.add(tpd.getDeclarationModel());
            }
        } else {
            typeParams = null;
        }
    } else {
        paramLists = emptyList();
        typeParams = null;
    }
    Unit unit = that.getUnit();
    final Map<TypeParameter, Type> subs;
    if (typeParams != null) {
        // the type parameters are written
        // down in the shortcut refinement
        method.setTypeParameters(typeParams);
        // TODO: check 'em!!
        // no need to check them because
        // this case is actually disallowed
        // elsewhere (specification statements
        // may not have type parameters)
        subs = NO_SUBSTITUTIONS;
    } else if (assignedMethod.isParameterized()) {
        if (me instanceof Tree.ParameterizedExpression) {
            // we have parameters, but no type parameters
            bme.addError("refined method is generic: '" + assignedMethod.getName(unit) + "' declares type parameters");
            subs = NO_SUBSTITUTIONS;
        } else {
            // we're assigning a method reference
            // so we need to magic up some "fake"
            // type parameters
            subs = copyTypeParametersFromRefined(assignedMethod, method, unit);
        }
    } else {
        subs = NO_SUBSTITUTIONS;
    }
    int i = 0;
    for (ParameterList pl : assignedMethod.getParameterLists()) {
        Tree.ParameterList params = paramLists.size() <= i ? null : paramLists.get(i++);
        createRefiningParameterList(rm, method, params, unit, subs, pl);
    }
    method.setShared(true);
    method.setActual(true);
    method.getAnnotations().add(new Annotation("shared"));
    method.getAnnotations().add(new Annotation("actual"));
    method.setRefinedDeclaration(root);
    method.setUnit(unit);
    method.setContainer(c);
    method.setScope(c);
    method.setShortcutRefinement(true);
    method.setDeclaredVoid(assignedMethod.isDeclaredVoid());
    Declaration rmd = rm.getDeclaration();
    if (rmd instanceof TypedDeclaration) {
        TypedDeclaration rmtd = (TypedDeclaration) rmd;
        method.setUncheckedNullType(rmtd.hasUncheckedNullType());
    }
    ModelUtil.setVisibleScope(method);
    c.addMember(method);
    that.setRefinement(true);
    that.setDeclaration(method);
    that.setRefined(root);
    unit.addDeclaration(method);
    Scope scope = that.getScope();
    if (scope instanceof Specification) {
        Specification spec = (Specification) scope;
        spec.setDeclaration(method);
    }
    setRefiningType(c, ci, name, signature, variadic, root, method, unit, subs);
    inheritDefaultedArguments(method);
}
Also used : ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Unit(org.eclipse.ceylon.model.typechecker.model.Unit) Function(org.eclipse.ceylon.model.typechecker.model.Function) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) 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.getTypedDeclaration(org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration) ExpressionVisitor.getRefinedMemberReference(org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor.getRefinedMemberReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Specification(org.eclipse.ceylon.model.typechecker.model.Specification) Annotation(org.eclipse.ceylon.model.typechecker.model.Annotation) IntersectionType(org.eclipse.ceylon.model.typechecker.model.IntersectionType) ModelUtil.intersectionType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.intersectionType) LazyType(org.eclipse.ceylon.model.typechecker.model.LazyType) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.erasedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.erasedType) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList)

Example 4 with Specification

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.SpecifierStatement that) {
    Tree.Term lhs = that.getBaseMemberExpression();
    if (lhs instanceof Tree.ParameterizedExpression) {
        Tree.ParameterizedExpression pe = (Tree.ParameterizedExpression) lhs;
        pe.setLeftTerm(true);
    }
    Specification s = new Specification();
    s.setId(id++);
    visitElement(that, s);
    Scope o = enterScope(s);
    super.visit(that);
    exitScope(o);
}
Also used : Scope(org.eclipse.ceylon.model.typechecker.model.Scope) ConditionScope(org.eclipse.ceylon.model.typechecker.model.ConditionScope) ModelUtil.getRealScope(org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope) CustomTree(org.eclipse.ceylon.compiler.typechecker.tree.CustomTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Specification(org.eclipse.ceylon.model.typechecker.model.Specification)

Aggregations

Specification (org.eclipse.ceylon.model.typechecker.model.Specification)4 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)3 Function (org.eclipse.ceylon.model.typechecker.model.Function)3 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)3 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)3 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)3 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)2 ModelUtil.getRealScope (org.eclipse.ceylon.model.typechecker.model.ModelUtil.getRealScope)2 Type (org.eclipse.ceylon.model.typechecker.model.Type)2 AnalyzerUtil.getTypedDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypedDeclaration)1 ExpressionVisitor.getRefinedMemberReference (org.eclipse.ceylon.compiler.typechecker.analyzer.ExpressionVisitor.getRefinedMemberReference)1 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)1 ArtifactResultType (org.eclipse.ceylon.model.cmr.ArtifactResultType)1 VisibilityType (org.eclipse.ceylon.model.cmr.VisibilityType)1 Annotation (org.eclipse.ceylon.model.typechecker.model.Annotation)1 Class (org.eclipse.ceylon.model.typechecker.model.Class)1 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)1 ConditionScope (org.eclipse.ceylon.model.typechecker.model.ConditionScope)1 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)1 Functional (org.eclipse.ceylon.model.typechecker.model.Functional)1