Search in sources :

Example 1 with Scope

use of com.redhat.ceylon.model.typechecker.model.Scope in project ceylon-compiler by ceylon.

the class ExpressionTransformer method appendDeclarationLiteralForAnnotation.

/**
 * Appends into the given builder a String representation of the given
 * declaration, suitable for parsing my the DeclarationParser.
 */
private static void appendDeclarationLiteralForAnnotation(Declaration decl, StringBuilder sb) {
    Scope container = decl.getContainer();
    while (true) {
        if (container instanceof Declaration) {
            appendDeclarationLiteralForAnnotation((Declaration) container, sb);
            sb.append(".");
            break;
        } else if (container instanceof Package) {
            appendDeclarationLiteralForAnnotation((Package) container, sb);
            sb.append(":");
            break;
        }
        container = container.getContainer();
    }
    if (decl instanceof Class) {
        sb.append("C").append(decl.getName());
    } else if (decl instanceof Interface) {
        sb.append("I").append(decl.getName());
    } else if (decl instanceof TypeAlias) {
        sb.append("A").append(decl.getName());
    } else if (decl instanceof Value) {
        sb.append("V").append(decl.getName());
    } else if (decl instanceof Function) {
        sb.append("F").append(decl.getName());
    } else if (decl instanceof TypeParameter) {
        sb.append("P").append(decl.getName());
    } else if (decl instanceof Constructor) {
        sb.append("c").append(decl.getName());
    } else {
        throw BugException.unhandledDeclarationCase(decl);
    }
}
Also used : Function(com.redhat.ceylon.model.typechecker.model.Function) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) Value(com.redhat.ceylon.model.typechecker.model.Value) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Package(com.redhat.ceylon.model.typechecker.model.Package) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 2 with Scope

use of com.redhat.ceylon.model.typechecker.model.Scope in project ceylon-compiler by ceylon.

the class ExpressionTransformer method needDollarThis.

private boolean needDollarThis(Tree.StaticMemberOrTypeExpression expr) {
    if (expr instanceof Tree.BaseMemberExpression) {
        // We need to add a `$this` prefix to the member expression if:
        // * The member was declared on an interface I and
        // * The member is being used in the companion class of I or
        // // REMOVED: some subinterface of I, and
        // some member type of I, and
        // * The member is shared (non-shared means its only on the companion class)
        // FIXME: https://github.com/ceylon/ceylon-compiler/issues/1019
        final Declaration decl = expr.getDeclaration();
        if (!Decl.withinInterface(decl))
            return false;
        // Find the method/getter/setter where the expr is being used
        Scope scope = expr.getScope();
        while (scope != null) {
            // Is it being used in an interface (=> impl)
            if (scope instanceof Interface && ((Interface) scope).getType().isSubtypeOf(scope.getDeclaringType(decl))) {
                return decl.isShared();
            }
            scope = scope.getContainer();
        }
    }
    return false;
}
Also used : Scope(com.redhat.ceylon.model.typechecker.model.Scope) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 3 with Scope

use of com.redhat.ceylon.model.typechecker.model.Scope in project ceylon-compiler by ceylon.

the class ExpressionTransformer method makeTypeParameterDeclaration.

/**
 * Makes an expression equivalent to the result of {@code `given T`}
 * @param node
 * @param declaration
 * @return
 */
JCExpression makeTypeParameterDeclaration(Node node, TypeParameter declaration) {
    Scope container = declaration.getContainer();
    if (container instanceof Declaration) {
        JCExpression containerExpr;
        Declaration containerDeclaration = (Declaration) container;
        if (containerDeclaration instanceof ClassOrInterface || containerDeclaration instanceof TypeAlias) {
            JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) containerDeclaration);
            JCExpression metamodelCast = makeJavaType(typeFact().getLanguageModuleDeclarationTypeDeclaration("GenericDeclaration").getType(), JT_NO_PRIMITIVES);
            containerExpr = make().TypeCast(metamodelCast, metamodelCall);
        } else if (containerDeclaration.isToplevel()) {
            containerExpr = makeTopLevelValueOrFunctionDeclarationLiteral(containerDeclaration);
        } else {
            containerExpr = makeMemberValueOrFunctionDeclarationLiteral(node, containerDeclaration);
        }
        // now it must be a ClassOrInterfaceDeclaration or a FunctionDeclaration, both of which have the method we need
        return at(node).Apply(null, makeSelect(containerExpr, "getTypeParameterDeclaration"), List.of(ceylonLiteral(declaration.getName())));
    } else {
        return makeErroneous(node, "compiler bug: " + container + " is not a supported type parameter container");
    }
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Scope(com.redhat.ceylon.model.typechecker.model.Scope) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 4 with Scope

use of com.redhat.ceylon.model.typechecker.model.Scope in project ceylon-compiler by ceylon.

the class ExpressionTransformer method addInterfaceImplAccessorIfRequired.

// 
// Array access
private JCExpression addInterfaceImplAccessorIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
    // For interfaces we sometimes need to access either the interface instance or its $impl class
    if (decl instanceof Constructor) {
        decl = (Class) Decl.container(decl);
    }
    Scope declContainer = Decl.container(decl);
    if (qualExpr != null && // this is only for interface containers
    declContainer instanceof Interface && // we only ever need the $impl if the declaration is not shared
    !decl.isShared() && (!(expr instanceof Tree.QualifiedMemberExpression) || !isSuperOrSuperOf(((Tree.QualifiedMemberExpression) expr).getPrimary()))) {
        Interface declaration = (Interface) declContainer;
        // access the interface $impl instance
        qualExpr = naming.makeCompanionAccessorCall(qualExpr, declaration);
        // so we need to cast it to the type of the companion
        if (Decl.isAncestorLocal(declaration)) {
            Type type;
            // try to find the best type
            if (expr instanceof Tree.QualifiedMemberOrTypeExpression)
                type = ((Tree.QualifiedMemberOrTypeExpression) expr).getPrimary().getTypeModel();
            else
                type = declaration.getType();
            qualExpr = make().TypeCast(makeJavaType(type, JT_COMPANION), qualExpr);
        }
    }
    return qualExpr;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 5 with Scope

use of com.redhat.ceylon.model.typechecker.model.Scope in project ceylon-compiler by ceylon.

the class Naming method appendTypeDeclaration.

private void appendTypeDeclaration(final TypeDeclaration decl, EnumSet<DeclNameFlag> flags, TypeDeclarationBuilder<?> typeDeclarationBuilder, Scope scope, final boolean last) {
    if (scope instanceof Class || scope instanceof TypeAlias || (scope instanceof Constructor && (scope.equals(decl) || !Decl.isLocalNotInitializerScope(scope)))) {
        TypeDeclaration klass = (TypeDeclaration) scope;
        if (klass.isAnonymous() && !klass.isNamed())
            typeDeclarationBuilder.clear();
        typeDeclarationBuilder.append(escapeClassName(klass.getName() != null ? klass.getName() : ""));
        if (Decl.isCeylon(klass)) {
            if (flags.contains(DeclNameFlag.COMPANION) && Decl.isLocalNotInitializer(klass) && last) {
                typeDeclarationBuilder.append(IMPL_POSTFIX);
            } else if (flags.contains(DeclNameFlag.ANNOTATION) && last) {
                typeDeclarationBuilder.append(ANNO_POSTFIX);
            } else if (flags.contains(DeclNameFlag.ANNOTATIONS) && last) {
                typeDeclarationBuilder.append(ANNOS_POSTFIX);
            } else if (flags.contains(DeclNameFlag.DELEGATION) && last) {
                typeDeclarationBuilder.append(DELEGATION_POSTFIX);
            }
        }
    } else if (scope instanceof Interface) {
        Interface iface = (Interface) scope;
        typeDeclarationBuilder.append(iface.getName());
        if (Decl.isCeylon(iface) && ((decl instanceof Class || decl instanceof Constructor || decl instanceof TypeAlias || scope instanceof Constructor) || flags.contains(DeclNameFlag.COMPANION))) {
            typeDeclarationBuilder.append(IMPL_POSTFIX);
        }
    } else if (Decl.isLocalNotInitializerScope(scope)) {
        if (flags.contains(DeclNameFlag.COMPANION) || !(decl instanceof Interface)) {
            typeDeclarationBuilder.clear();
        } else if (flags.contains(DeclNameFlag.QUALIFIED) || (decl instanceof Interface)) {
            Scope nonLocal = scope;
            while (!(nonLocal instanceof Declaration)) {
                nonLocal = nonLocal.getContainer();
            }
            typeDeclarationBuilder.append(((Declaration) nonLocal).getPrefixedName());
            if (!Decl.equalScopes(scope, nonLocal)) {
                typeDeclarationBuilder.append('$');
                typeDeclarationBuilder.append(getLocalId(scope));
            }
            if (decl instanceof Interface) {
                typeDeclarationBuilder.append('$');
            } else {
                if (flags.contains(DeclNameFlag.QUALIFIED)) {
                    typeDeclarationBuilder.selectAppended();
                } else {
                    typeDeclarationBuilder.clear();
                }
            }
        }
        return;
    } else if (scope instanceof TypedDeclaration && ((Declaration) scope).isToplevel()) {
    // nothing? that's just weird
    }
    if (!last) {
        if (decl instanceof Interface && Decl.isCeylon((TypeDeclaration) decl) && !flags.contains(DeclNameFlag.COMPANION)) {
            typeDeclarationBuilder.append('$');
        } else if (decl instanceof Constructor && ((Class) decl.getContainer()).isMember() && decl.getContainer().equals(scope)) {
            typeDeclarationBuilder.append('$');
        } else {
            if (flags.contains(DeclNameFlag.QUALIFIED)) {
                typeDeclarationBuilder.selectAppended();
            } else {
                typeDeclarationBuilder.clear();
            }
        }
    } else {
        typeDeclarationBuilder.selectAppended();
    }
    return;
}
Also used : TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Scope(com.redhat.ceylon.model.typechecker.model.Scope) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) Class(com.redhat.ceylon.model.typechecker.model.Class) LazyClass(com.redhat.ceylon.model.loader.model.LazyClass) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Aggregations

Scope (com.redhat.ceylon.model.typechecker.model.Scope)38 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)26 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)22 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)20 Package (com.redhat.ceylon.model.typechecker.model.Package)16 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)14 Interface (com.redhat.ceylon.model.typechecker.model.Interface)10 Class (com.redhat.ceylon.model.typechecker.model.Class)8 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)8 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)7 Type (com.redhat.ceylon.model.typechecker.model.Type)7 ArrayList (java.util.ArrayList)7 Function (com.redhat.ceylon.model.typechecker.model.Function)6 Constructor (com.redhat.ceylon.model.typechecker.model.Constructor)5 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)5 Value (com.redhat.ceylon.model.typechecker.model.Value)5 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)5 JCTree (com.sun.tools.javac.tree.JCTree)4 Generic (com.redhat.ceylon.model.typechecker.model.Generic)3 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)3