Search in sources :

Example 16 with ClassOrInterface

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

the class ExpressionTransformer method transform.

public JCTree transform(Tree.TypeLiteral expr) {
    at(expr);
    if (!expr.getWantsDeclaration()) {
        if (expr.getDeclaration() instanceof Constructor) {
            JCExpression classLiteral = makeTypeLiteralCall(expr.getType().getTypeModel().getQualifyingType(), false, expr.getTypeModel());
            TypeDeclaration classModelDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(expr.getType().getTypeModel().getQualifyingType().getDeclaration().isMember() ? "MemberClass" : "Class");
            JCTypeCast typeCast = make().TypeCast(makeJavaType(classModelDeclaration.appliedType(null, List.of(expr.getType().getTypeModel().getQualifyingType(), typeFact().getNothingType()))), classLiteral);
            Type callableType = expr.getTypeModel().getFullType();
            JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
            return make().Apply(null, naming.makeQualIdent(typeCast, "getConstructor"), List.<JCExpression>of(reifiedArgumentsExpr, make().Literal(expr.getDeclaration().getName())));
        } else {
            return makeTypeLiteralCall(expr.getType().getTypeModel(), true, expr.getTypeModel());
        }
    } else if (expr.getDeclaration() instanceof TypeParameter) {
        // we must get it from its container
        TypeParameter declaration = (TypeParameter) expr.getDeclaration();
        Node node = expr;
        return makeTypeParameterDeclaration(node, declaration);
    } else if (expr.getDeclaration() instanceof Constructor || expr instanceof Tree.NewLiteral) {
        Constructor ctor;
        if (expr.getDeclaration() instanceof Constructor) {
            ctor = (Constructor) expr.getDeclaration();
        } else {
            ctor = Decl.getDefaultConstructor((Class) expr.getDeclaration());
        }
        JCExpression metamodelCall = makeTypeDeclarationLiteral(Decl.getConstructedClass(ctor));
        metamodelCall = make().TypeCast(makeJavaType(typeFact().getClassDeclarationType(), JT_RAW), metamodelCall);
        metamodelCall = make().Apply(null, naming.makeQualIdent(metamodelCall, "getConstructorDeclaration"), List.<JCExpression>of(make().Literal(ctor.getName() == null ? "" : ctor.getName())));
        if (Decl.isEnumeratedConstructor(ctor)) {
            metamodelCall = make().TypeCast(makeJavaType(typeFact().getValueConstructorDeclarationType(), JT_RAW), metamodelCall);
        } else /*else if (Decl.isDefaultConstructor(ctor)){
                metamodelCall = make().TypeCast(
                        makeJavaType(typeFact().getDefaultConstructorDeclarationType(), JT_RAW), metamodelCall);
            } */
        {
            metamodelCall = make().TypeCast(makeJavaType(typeFact().getCallableConstructorDeclarationType(), JT_RAW), metamodelCall);
        }
        return metamodelCall;
    } else if (expr.getDeclaration() instanceof ClassOrInterface || expr.getDeclaration() instanceof TypeAlias) {
        // use the generated class to get to the declaration literal
        JCExpression metamodelCall = makeTypeDeclarationLiteral((TypeDeclaration) expr.getDeclaration());
        Type exprType = expr.getTypeModel().resolveAliases();
        // now cast if required
        if (!exprType.isExactly(((TypeDeclaration) typeFact().getLanguageModuleDeclarationDeclaration("NestableDeclaration")).getType())) {
            JCExpression type = makeJavaType(exprType, JT_NO_PRIMITIVES);
            return make().TypeCast(type, metamodelCall);
        }
        return metamodelCall;
    } else {
        return makeErroneous(expr, "compiler bug: " + expr.getDeclaration() + " is an unsupported declaration type");
    }
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Type(com.redhat.ceylon.model.typechecker.model.Type) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTypeCast(com.sun.tools.javac.tree.JCTree.JCTypeCast) Constructor(com.redhat.ceylon.model.typechecker.model.Constructor) Node(com.redhat.ceylon.compiler.typechecker.tree.Node) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) TypeAlias(com.redhat.ceylon.model.typechecker.model.TypeAlias) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Example 17 with ClassOrInterface

use of com.redhat.ceylon.model.typechecker.model.ClassOrInterface 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 18 with ClassOrInterface

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

the class ExpressionTransformer method transform.

public JCExpression transform(Tree.Parameter param) {
    // Transform the expression marking that we're inside a defaulted parameter for $this-handling
    //needDollarThis  = true;
    JCExpression expr;
    at(param);
    if (Strategy.hasDefaultParameterValueMethod(param.getParameterModel())) {
        Tree.SpecifierOrInitializerExpression spec = Decl.getDefaultArgument(param);
        Scope container = param.getParameterModel().getModel().getContainer();
        boolean classParameter = container instanceof ClassOrInterface;
        ClassOrInterface oldWithinDefaultParameterExpression = withinDefaultParameterExpression;
        if (classParameter)
            withinDefaultParameterExpression((ClassOrInterface) container);
        if (param instanceof Tree.FunctionalParameterDeclaration) {
            Tree.FunctionalParameterDeclaration fpTree = (Tree.FunctionalParameterDeclaration) param;
            Tree.SpecifierExpression lazy = (Tree.SpecifierExpression) spec;
            Function fp = (Function) fpTree.getParameterModel().getModel();
            expr = CallableBuilder.anonymous(gen(), param, (Function) fpTree.getTypedDeclaration().getDeclarationModel(), lazy.getExpression(), ((Tree.MethodDeclaration) fpTree.getTypedDeclaration()).getParameterLists(), getTypeForFunctionalParameter(fp), true).build();
        } else {
            expr = transformExpression(spec.getExpression(), CodegenUtil.getBoxingStrategy(param.getParameterModel().getModel()), param.getParameterModel().getType());
        }
        if (classParameter)
            withinDefaultParameterExpression(oldWithinDefaultParameterExpression);
    } else {
        expr = makeErroneous(param, "compiler bug: no default parameter value method");
    }
    //needDollarThis = false;
    return expr;
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) Function(com.redhat.ceylon.model.typechecker.model.Function) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) Scope(com.redhat.ceylon.model.typechecker.model.Scope) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree)

Example 19 with ClassOrInterface

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

the class ExpressionTransformer method lostTypeParameterInInheritance.

private boolean lostTypeParameterInInheritance(ClassOrInterface exprDecl, ClassOrInterface commonDecl, boolean searchInterfaces, boolean lostTypeParameter) {
    // stop if we found the common decl
    if (Decl.equal(exprDecl, commonDecl))
        return lostTypeParameter;
    if (searchInterfaces) {
        // find a match in interfaces
        for (Type pt : exprDecl.getSatisfiedTypes()) {
            // FIXME: this is very heavy-handed because we consider that once we've lost a type parameter we've lost them all
            // but we could optimise this by checking:
            // 1/ which type parameter we've really lost
            // 2/ if the type parameters we're passing to our super type actually depend in any way from type parameters we've lost
            boolean lostTypeParameter2 = lostTypeParameter || isTurnedToRaw(pt);
            pt = simplifyType(pt);
            // it has to be an interface
            Interface interf = (Interface) pt.getDeclaration();
            if (lostTypeParameterInInheritance(interf, commonDecl, searchInterfaces, lostTypeParameter2))
                return true;
        }
    }
    // search for super classes
    Type extendedType = exprDecl.getExtendedType();
    if (extendedType != null) {
        // FIXME: see above
        boolean lostTypeParameter2 = lostTypeParameter || isTurnedToRaw(extendedType);
        extendedType = simplifyType(extendedType);
        // it has to be a Class
        Class extendedTypeDeclaration = (Class) extendedType.getDeclaration();
        // looks like Object's superclass is Object, so stop right there
        if (extendedTypeDeclaration != typeFact().getObjectDeclaration())
            return lostTypeParameterInInheritance(extendedTypeDeclaration, commonDecl, searchInterfaces, lostTypeParameter2);
    }
    // didn't find it
    return false;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 20 with ClassOrInterface

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

the class Naming method addNamesForWrapperClass.

private <R> void addNamesForWrapperClass(TypeDeclarationBuilder<R> builder, TypedDeclaration decl, int namingOptions) {
    if ((namingOptions & NA_FQ) != 0) {
        if ((namingOptions & NA_WRAPPER) == 0 && (namingOptions & NA_WRAPPER_UNQUOTED) == 0) {
            throw new BugException("If you pass FQ you must pass WRAPPER or WRAPPER_UNQUOTED too, or there's no class name to qualify!");
        }
        List<String> outerNames = null;
        Scope s = decl.getContainer();
        while (s != null) {
            if (s instanceof Package) {
                final List<String> packageName = ((Package) s).getName();
                for (int ii = 0; ii < packageName.size(); ii++) {
                    if (ii == 0 && packageName.get(ii).isEmpty()) {
                        continue;
                    }
                    builder.select(quoteIfJavaKeyword(packageName.get(ii)));
                }
                break;
            } else if (s instanceof ClassOrInterface) {
                if (outerNames == null) {
                    outerNames = new ArrayList<String>(2);
                }
                outerNames.add(getQuotedClassName((ClassOrInterface) s, 0));
            } else if (s instanceof TypedDeclaration) {
                if (outerNames == null) {
                    outerNames = new ArrayList<String>(2);
                }
                outerNames.add(quoteIfJavaKeyword(((TypedDeclaration) s).getName()));
            }
            s = s.getContainer();
        }
        if (outerNames != null) {
            for (int ii = outerNames.size() - 1; ii >= 0; ii--) {
                String outerName = outerNames.get(ii);
                builder.select(outerName);
            }
        }
    }
    if ((namingOptions & NA_WRAPPER) != 0) {
        builder.select(getQuotedClassName(decl, namingOptions & (NA_GETTER | NA_SETTER)));
    } else if ((namingOptions & NA_WRAPPER_UNQUOTED) != 0) {
        builder.select(getRealName(decl, namingOptions & (NA_GETTER | NA_SETTER | NA_WRAPPER_UNQUOTED)));
    } else if ((namingOptions & NA_Q_LOCAL_INSTANCE) != 0) {
        if (Decl.isBoxedVariable(decl)) {
            builder.select(getVariableBoxName(decl));
        } else {
            builder.select(getAttrClassName(decl, namingOptions & (NA_GETTER | NA_SETTER)));
        }
    }
    if ((namingOptions & NA_WRAPPER_WITH_THIS) != 0) {
        builder.select("this");
    }
}
Also used : ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Scope(com.redhat.ceylon.model.typechecker.model.Scope) ArrayList(java.util.ArrayList) Package(com.redhat.ceylon.model.typechecker.model.Package)

Aggregations

ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)37 Type (com.redhat.ceylon.model.typechecker.model.Type)21 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)20 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)16 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)15 Interface (com.redhat.ceylon.model.typechecker.model.Interface)13 ModelUtil.appliedType (com.redhat.ceylon.model.typechecker.model.ModelUtil.appliedType)11 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)11 Class (com.redhat.ceylon.model.typechecker.model.Class)9 Package (com.redhat.ceylon.model.typechecker.model.Package)7 Scope (com.redhat.ceylon.model.typechecker.model.Scope)7 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)7 Function (com.redhat.ceylon.model.typechecker.model.Function)6 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)6 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)5 Constructor (com.redhat.ceylon.model.typechecker.model.Constructor)5 TypeAlias (com.redhat.ceylon.model.typechecker.model.TypeAlias)5 JCTree (com.sun.tools.javac.tree.JCTree)5 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)5 ArrayList (java.util.ArrayList)5