Search in sources :

Example 1 with List

use of org.eclipse.ceylon.langtools.tools.javac.util.List in project ceylon by eclipse.

the class AbstractTransformer method makeReifiedTypeArgumentResolved.

private JCExpression makeReifiedTypeArgumentResolved(Type pt, boolean qualified, TypeArgumentAccessor typeArgumentAccessor, boolean wantsRaw) {
    if (pt.isUnion()) {
        // FIXME: refactor this shite
        List<JCExpression> typeTestArguments = List.nil();
        java.util.List<Type> typeParameters = pt.getCaseTypes();
        if (typeParameters.size() == 2) {
            Type alternative = null;
            if (typeParameters.get(0).isEmpty())
                alternative = typeParameters.get(1);
            else if (typeParameters.get(1).isEmpty())
                alternative = typeParameters.get(0);
            if (alternative != null && alternative.isTuple()) {
                JCExpression tupleType = makeTupleTypeDescriptor(alternative, true);
                if (tupleType != null)
                    return tupleType;
            }
        }
        for (int i = typeParameters.size() - 1; i >= 0; i--) {
            typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
        }
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "union"), typeTestArguments);
    } else if (pt.isIntersection()) {
        List<JCExpression> typeTestArguments = List.nil();
        java.util.List<Type> typeParameters = pt.getSatisfiedTypes();
        for (int i = typeParameters.size() - 1; i >= 0; i--) {
            typeTestArguments = typeTestArguments.prepend(makeReifiedTypeArgument(typeParameters.get(i)));
        }
        return make().Apply(null, makeSelect(makeTypeDescriptorType(), "intersection"), typeTestArguments);
    } else if (pt.isNothing()) {
        return makeNothingTypeDescriptor();
    }
    TypeDeclaration declaration = pt.getDeclaration();
    if (declaration instanceof Constructor) {
        pt = pt.getExtendedType();
        declaration = pt.getDeclaration();
    }
    if (pt.isClassOrInterface()) {
        // see if we have an alias for it
        if (supportsReifiedAlias((ClassOrInterface) declaration)) {
            JCExpression qualifier = naming.makeDeclarationName(declaration, DeclNameFlag.QUALIFIED);
            return makeSelect(qualifier, naming.getTypeDescriptorAliasName());
        }
        if (pt.isTuple()) {
            JCExpression tupleType = makeTupleTypeDescriptor(pt, false);
            if (tupleType != null)
                return tupleType;
        }
        // no alias, must build it
        List<JCExpression> typeTestArguments;
        JCExpression thisType = makeUnerasedClassLiteral(declaration);
        if (!wantsRaw) {
            typeTestArguments = makeReifiedTypeArgumentsResolved(pt.getTypeArgumentList(), qualified, typeArgumentAccessor);
            // do we have variance overrides?
            Map<TypeParameter, SiteVariance> varianceOverrides = pt.getVarianceOverrides();
            if (!varianceOverrides.isEmpty()) {
                // we need to pass them as second argument then, in an array
                ListBuffer<JCExpression> varianceElements = new ListBuffer<JCExpression>();
                for (TypeParameter typeParameter : declaration.getTypeParameters()) {
                    SiteVariance useSiteVariance = varianceOverrides.get(typeParameter);
                    String selector;
                    if (useSiteVariance != null) {
                        switch(useSiteVariance) {
                            case IN:
                                selector = "IN";
                                break;
                            case OUT:
                                selector = "OUT";
                                break;
                            default:
                                selector = "NONE";
                                break;
                        }
                    } else {
                        selector = "NONE";
                    }
                    JCExpression varianceElement = make().Select(makeIdent(syms().ceylonVarianceType), names().fromString(selector));
                    varianceElements.append(varianceElement);
                }
                JCNewArray varianceArray = make().NewArray(makeIdent(syms().ceylonVarianceType), List.<JCExpression>nil(), varianceElements.toList());
                typeTestArguments = typeTestArguments.prepend(varianceArray);
            }
        } else {
            typeTestArguments = List.nil();
        }
        typeTestArguments = typeTestArguments.prepend(thisType);
        JCExpression classDescriptor = make().Apply(null, makeSelect(makeTypeDescriptorType(), "klass"), typeTestArguments);
        Type qualifyingType = pt.getQualifyingType();
        JCExpression containerType = null;
        if (qualifyingType == null) {
            // it may be contained in a function or value, and we want its type
            // or static class members may have no qualifying type but we want the TDs to treat
            // them as members anyway
            Declaration enclosingDeclaration = getDeclarationContainer(declaration);
            if (enclosingDeclaration instanceof TypedDeclaration)
                containerType = makeTypedDeclarationTypeDescriptorResolved((TypedDeclaration) enclosingDeclaration, typeArgumentAccessor);
            else if (enclosingDeclaration instanceof TypeDeclaration) {
                qualifyingType = ((TypeDeclaration) enclosingDeclaration).getType();
            }
        }
        if (qualifyingType != null && qualifyingType.isConstructor()) {
            qualifyingType = qualifyingType.getQualifyingType();
        }
        if (qualifyingType != null) {
            if (declaration.isStatic() && supportsReified(declaration)) {
                // There is no outer instance with a $reified$T field
                final Type t = pt;
                containerType = makeReifiedTypeArgumentResolved(qualifyingType, true, new TypeArgumentAccessor() {

                    public JCExpression getTypeDescriptor(TypeParameter tp, boolean qualified) {
                        return makeSelect(naming.makeQualifiedThis(makeJavaType(t, JT_RAW)), naming.getTypeArgumentDescriptorName(tp));
                    }
                }, false);
            } else {
                containerType = makeReifiedTypeArgumentResolved(qualifyingType, true, typeArgumentAccessor, // we want raw containers, since we can't capture their TPs
                declaration.isStatic());
            }
        }
        if (containerType == null) {
            return classDescriptor;
        } else {
            return make().Apply(null, makeSelect(makeTypeDescriptorType(), "member"), List.of(containerType, classDescriptor));
        }
    } else if (pt.isTypeParameter()) {
        return typeArgumentAccessor.getTypeDescriptor((TypeParameter) declaration, qualified);
    } else {
        throw BugException.unhandledDeclarationCase(declaration);
    }
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCTypeParameter(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCTypeParameter) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Type(org.eclipse.ceylon.model.typechecker.model.Type) ModelUtil.appliedType(org.eclipse.ceylon.model.typechecker.model.ModelUtil.appliedType) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) SiteVariance(org.eclipse.ceylon.model.typechecker.model.SiteVariance) ArrayList(java.util.ArrayList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) LinkedList(java.util.LinkedList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCNewArray(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewArray)

Example 2 with List

use of org.eclipse.ceylon.langtools.tools.javac.util.List in project ceylon by eclipse.

the class ClassTransformer method transformRefinementSpecifierStatement.

public List<JCStatement> transformRefinementSpecifierStatement(SpecifierStatement op, ClassDefinitionBuilder classBuilder) {
    List<JCStatement> result = List.<JCStatement>nil();
    // Check if this is a shortcut form of formal attribute refinement
    if (op.getRefinement()) {
        Tree.Term baseMemberTerm = op.getBaseMemberExpression();
        if (baseMemberTerm instanceof Tree.ParameterizedExpression)
            baseMemberTerm = ((Tree.ParameterizedExpression) baseMemberTerm).getPrimary();
        Tree.BaseMemberExpression expr = (BaseMemberExpression) baseMemberTerm;
        Declaration decl = expr.getDeclaration();
        if (Decl.isValue(decl) || Decl.isGetter(decl)) {
            // Now build a "fake" declaration for the attribute
            Tree.AttributeDeclaration attrDecl = new Tree.AttributeDeclaration(null);
            attrDecl.setDeclarationModel((Value) decl);
            attrDecl.setIdentifier(expr.getIdentifier());
            attrDecl.setScope(op.getScope());
            attrDecl.setSpecifierOrInitializerExpression(op.getSpecifierExpression());
            attrDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
            // Make sure the boxing information is set correctly
            BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
            v.visit(attrDecl);
            // Generate the attribute
            transform(attrDecl, classBuilder);
        } else if (decl instanceof Function) {
            // Now build a "fake" declaration for the method
            Tree.MethodDeclaration methDecl = new Tree.MethodDeclaration(null);
            Function m = (Function) decl;
            methDecl.setDeclarationModel(m);
            methDecl.setIdentifier(expr.getIdentifier());
            methDecl.setScope(op.getScope());
            methDecl.setAnnotationList(makeShortcutRefinementAnnotationTrees());
            Tree.SpecifierExpression specifierExpression = op.getSpecifierExpression();
            methDecl.setSpecifierExpression(specifierExpression);
            if (specifierExpression instanceof Tree.LazySpecifierExpression == false) {
                Tree.Expression expression = specifierExpression.getExpression();
                Tree.Term expressionTerm = Decl.unwrapExpressionsUntilTerm(expression);
                // we can optimise lambdas and static method calls
                if (!CodegenUtil.canOptimiseMethodSpecifier(expressionTerm, m)) {
                    // we need a field to save the callable value
                    String name = naming.getMethodSpecifierAttributeName(m);
                    JCExpression specifierType = makeJavaType(expression.getTypeModel());
                    JCExpression specifier = expressionGen().transformExpression(expression);
                    classBuilder.field(PRIVATE | FINAL, name, specifierType, specifier, false);
                }
            }
            java.util.List<Tree.ParameterList> parameterListTrees = null;
            if (op.getBaseMemberExpression() instanceof Tree.ParameterizedExpression) {
                parameterListTrees = new ArrayList<>(m.getParameterLists().size());
                parameterListTrees.addAll(((Tree.ParameterizedExpression) op.getBaseMemberExpression()).getParameterLists());
                Tree.Term term = specifierExpression.getExpression().getTerm();
                // and give it the given block of expr as it's specifier
                while (term instanceof Tree.FunctionArgument && m.getParameterLists().size() > 1) {
                    FunctionArgument functionArgument = (Tree.FunctionArgument) term;
                    specifierExpression.setExpression(functionArgument.getExpression());
                    parameterListTrees.addAll(functionArgument.getParameterLists());
                    term = functionArgument.getExpression().getTerm();
                }
            }
            int plIndex = 0;
            // copy from formal declaration
            for (ParameterList pl : m.getParameterLists()) {
                Tree.ParameterList parameterListTree = null;
                if (parameterListTrees != null)
                    parameterListTree = parameterListTrees.get(plIndex++);
                Tree.ParameterList tpl = new Tree.ParameterList(null);
                tpl.setModel(pl);
                int pIndex = 0;
                for (Parameter p : pl.getParameters()) {
                    Tree.Parameter parameterTree = null;
                    if (parameterListTree != null)
                        parameterTree = parameterListTree.getParameters().get(pIndex++);
                    Tree.Parameter tp = null;
                    if (p.getModel() instanceof Value) {
                        Tree.ValueParameterDeclaration tvpd = new Tree.ValueParameterDeclaration(null);
                        if (parameterTree != null)
                            tvpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
                        tvpd.setParameterModel(p);
                        tp = tvpd;
                    } else if (p.getModel() instanceof Function) {
                        Tree.FunctionalParameterDeclaration tfpd = new Tree.FunctionalParameterDeclaration(null);
                        if (parameterTree != null)
                            tfpd.setTypedDeclaration(((Tree.ParameterDeclaration) parameterTree).getTypedDeclaration());
                        tfpd.setParameterModel(p);
                        tp = tfpd;
                    } else {
                        throw BugException.unhandledDeclarationCase(p.getModel());
                    }
                    tp.setScope(p.getDeclaration().getContainer());
                    // tp.setIdentifier(makeIdentifier(p.getName()));
                    tpl.addParameter(tp);
                }
                methDecl.addParameterList(tpl);
            }
            // Make sure the boxing information is set correctly
            BoxingDeclarationVisitor v = new CompilerBoxingDeclarationVisitor(this);
            v.visit(methDecl);
            // Generate the method
            classBuilder.method(methDecl, Errors.GENERATE);
        }
    } else {
        // Normal case, just generate the specifier statement
        result = result.append(expressionGen().transform(op));
    }
    Tree.Term term = op.getBaseMemberExpression();
    if (term instanceof Tree.BaseMemberExpression) {
        Tree.BaseMemberExpression bme = (Tree.BaseMemberExpression) term;
        DeferredSpecification ds = statementGen().getDeferredSpecification(bme.getDeclaration());
        if (ds != null && needsInnerSubstitution(term.getScope(), bme.getDeclaration())) {
            result = result.append(ds.openInnerSubstitution());
        }
    }
    return result;
}
Also used : SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) DeferredSpecification(org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification) ArrayList(java.util.ArrayList) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Function(org.eclipse.ceylon.model.typechecker.model.Function) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) SpecifierExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) BaseMemberExpression(org.eclipse.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)

Example 3 with List

use of org.eclipse.ceylon.langtools.tools.javac.util.List in project ceylon by eclipse.

the class ClassTransformer method transformClassOrCtorParameters.

private void transformClassOrCtorParameters(Tree.AnyClass def, Class cls, Constructor constructor, Tree.Declaration node, Tree.ParameterList paramList, boolean delegationConstructor, ClassDefinitionBuilder classBuilder, ParameterizedBuilder<?> constructorBuilder, boolean generateInstantiator, ClassDefinitionBuilder instantiatorDeclCb, ClassDefinitionBuilder instantiatorImplCb) {
    for (final Tree.Parameter param : paramList.getParameters()) {
        // Overloaded instantiators
        Parameter paramModel = param.getParameterModel();
        Parameter refinedParam = CodegenUtil.findParamForDecl((TypedDeclaration) CodegenUtil.getTopmostRefinedDeclaration(param.getParameterModel().getModel()));
        at(param);
        Tree.TypedDeclaration member = def != null ? Decl.getMemberDeclaration(def, param) : null;
        // transform the parameter and its annotations
        transformParameter(constructorBuilder, param, paramModel, member);
        if (Strategy.hasDefaultParameterValueMethod(paramModel) || Strategy.hasDefaultParameterOverload(paramModel) || (generateInstantiator && refinedParam != null && (Strategy.hasDefaultParameterValueMethod(refinedParam) || Strategy.hasDefaultParameterOverload(refinedParam)))) {
            ClassDefinitionBuilder cbForDevaultValues;
            ClassDefinitionBuilder cbForDevaultValuesDecls = null;
            switch(Strategy.defaultParameterMethodOwner(constructor != null ? constructor : cls)) {
                case STATIC:
                    cbForDevaultValues = classBuilder;
                    break;
                case OUTER:
                    cbForDevaultValues = classBuilder.getContainingClassBuilder();
                    break;
                case OUTER_COMPANION:
                    cbForDevaultValues = classBuilder.getContainingClassBuilder().getCompanionBuilder(ModelUtil.getClassOrInterfaceContainer(cls, true));
                    if ((constructor == null || constructor.isShared()) && cls.isShared()) {
                        cbForDevaultValuesDecls = classBuilder.getContainingClassBuilder();
                    }
                    break;
                default:
                    cbForDevaultValues = classBuilder.getCompanionBuilder(cls);
            }
            if (!delegationConstructor) {
                if ((Strategy.hasDefaultParameterValueMethod(paramModel) || (refinedParam != null && Strategy.hasDefaultParameterValueMethod(refinedParam)))) {
                    if (!generateInstantiator || Decl.equal(refinedParam, paramModel)) {
                        // transform the default value into a method
                        cbForDevaultValues.method(makeParamDefaultValueMethod(false, constructor != null ? constructor : cls, paramList, param));
                        if (cbForDevaultValuesDecls != null) {
                            cbForDevaultValuesDecls.method(makeParamDefaultValueMethod(true, constructor != null ? constructor : cls, paramList, param));
                        }
                    } else if (Strategy.hasDelegatedDpm(cls) && cls.getContainer() instanceof Class) {
                        // generate a dpm which delegates to the companion
                        java.util.List<Parameter> parameters = paramList.getModel().getParameters();
                        MethodDefinitionBuilder mdb = makeDelegateToCompanion((Interface) cls.getRefinedDeclaration().getContainer(), constructor != null ? constructor.getReference() : cls.getReference(), ((TypeDeclaration) cls.getContainer()).getType(), FINAL | (modifierTransformation().classFlags(cls) & ~ABSTRACT), List.<TypeParameter>nil(), Collections.<java.util.List<Type>>emptyList(), paramModel.getType().getFullType(), Naming.getDefaultedParamMethodName(cls, paramModel), parameters.subList(0, parameters.indexOf(paramModel)), false, Naming.getDefaultedParamMethodName(cls, paramModel), param.getParameterModel());
                        cbForDevaultValues.method(mdb);
                    }
                }
            }
            boolean addOverloadedConstructor = false;
            if (generateInstantiator) {
                if (cls.isInterfaceMember()) {
                    MethodDefinitionBuilder instBuilder = new DefaultedArgumentInstantiator(daoAbstract, cls, constructor, instantiatorDeclCb.isCompanionBuilder()).makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
                    instantiatorDeclCb.method(instBuilder);
                }
                if (!cls.isInterfaceMember() || !cls.isFormal()) {
                    MethodDefinitionBuilder instBuilder = new DefaultedArgumentInstantiator(new DaoThis(node, paramList), cls, constructor, instantiatorImplCb.isCompanionBuilder()).makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
                    instantiatorImplCb.method(instBuilder);
                } else {
                    addOverloadedConstructor = true;
                }
            } else {
                addOverloadedConstructor = true;
            }
            if (addOverloadedConstructor) {
                // Add overloaded constructors for defaulted parameter
                // MethodDefinitionBuilder overloadBuilder;
                DefaultedArgumentConstructor dac;
                if (constructor != null) {
                    dac = new DefaultedArgumentConstructor(classBuilder.addConstructor(constructor.isDeprecated()), constructor, node, paramList, delegationConstructor);
                } else {
                    dac = new DefaultedArgumentConstructor(classBuilder.addConstructor(cls.isDeprecated()), cls, node, paramList, delegationConstructor);
                }
                // overloadBuilder =
                dac.makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
            }
        }
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 4 with List

use of org.eclipse.ceylon.langtools.tools.javac.util.List in project ceylon by eclipse.

the class ExpressionTransformer method transform.

public JCTree transform(Tree.MemberLiteral expr) {
    at(expr);
    Declaration declaration = expr.getDeclaration();
    if (declaration == null)
        return makeErroneous(expr, "compiler bug: missing declaration");
    if (declaration.isToplevel()) {
        return makeTopLevelValueOrFunctionLiteral(expr);
    } else if (expr.getWantsDeclaration()) {
        return makeMemberValueOrFunctionDeclarationLiteral(expr, declaration);
    } else {
        // get its produced ref
        Reference producedReference = expr.getTarget();
        // it's a member we get from its container type
        Type containerType = producedReference.getQualifyingType();
        // if we have no container type it means we have an object member
        boolean objectMember = containerType.getDeclaration().isAnonymous();
        JCExpression memberCall;
        if (objectMember) {
            // We don't care about the type args for the cast, nor for the reified container expr, because
            // we take the real reified container type from the container instance, and that one has the type
            // arguments
            containerType = ((Class) declaration.getContainer()).getType();
        }
        JCExpression typeCall = makeTypeLiteralCall(containerType, false, expr.getTypeModel());
        // make sure we cast it to ClassOrInterface
        String metatypeName;
        if (Decl.isConstructor(declaration)) {
            Class constructedClass = ModelUtil.getConstructedClass(declaration);
            Declaration container = getDeclarationContainer(constructedClass);
            if (constructedClass.isToplevel() || container instanceof TypeDeclaration == false) {
                metatypeName = "Class";
            } else {
                metatypeName = "MemberClass";
            }
        } else {
            metatypeName = "ClassOrInterface";
        }
        TypeDeclaration classOrInterfaceDeclaration = (TypeDeclaration) typeFact().getLanguageModuleModelDeclaration(metatypeName);
        JCExpression classOrInterfaceTypeExpr = makeJavaType(classOrInterfaceDeclaration.appliedReference(null, Arrays.asList(containerType)).getType());
        typeCall = make().TypeCast(classOrInterfaceTypeExpr, typeCall);
        // we will need a TD for the container
        // Note that we don't use Basic for the container for object members, because that's not how we represent
        // anonymous types.
        JCExpression reifiedContainerExpr = makeReifiedTypeArgument(containerType);
        // make a raw call and cast
        if (Decl.isConstructor(declaration)) {
            Type callableType = producedReference.getFullType();
            /*JCExpression reifiedArgumentsExpr;
                if (Decl.isEnumeratedConstructor(Decl.getConstructor(declaration))) {
                    reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType.getQualifyingType()));
                } else {
                    reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
                }*/
            JCExpression reifiedArguments;
            if (ModelUtil.isEnumeratedConstructor(ModelUtil.getConstructor(declaration))) {
                reifiedArguments = makeReifiedTypeArgument(typeFact().getNothingType());
            } else {
                reifiedArguments = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
            }
            List<JCExpression> arguments = List.of(reifiedArguments, ceylonLiteral(declaration.getName()));
            JCExpression classModel = makeSelect(typeCall, "getDeclaredConstructor");
            memberCall = make().Apply(null, classModel, arguments);
        } else if (declaration instanceof Function) {
            // we need to get types for each type argument
            JCExpression closedTypesExpr = null;
            if (expr.getTypeArgumentList() != null) {
                java.util.List<Type> typeModels = expr.getTypeArgumentList().getTypeModels();
                if (typeModels != null) {
                    closedTypesExpr = getClosedTypesSequential(typeModels);
                }
            }
            // we also need type descriptors for ret and args
            Type callableType = producedReference.getFullType();
            JCExpression reifiedReturnTypeExpr = makeReifiedTypeArgument(typeFact().getCallableReturnType(callableType));
            JCExpression reifiedArgumentsExpr = makeReifiedTypeArgument(typeFact().getCallableTuple(callableType));
            List<JCExpression> arguments;
            if (closedTypesExpr != null)
                arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()), closedTypesExpr);
            else
                arguments = List.of(reifiedContainerExpr, reifiedReturnTypeExpr, reifiedArgumentsExpr, ceylonLiteral(declaration.getName()));
            memberCall = make().Apply(null, makeSelect(typeCall, "getMethod"), arguments);
        } else if (declaration instanceof Value) {
            JCExpression reifiedGetExpr = makeReifiedTypeArgument(producedReference.getType());
            String getterName = "getAttribute";
            Type ptype;
            if (!((Value) declaration).isVariable())
                ptype = typeFact().getNothingType();
            else
                ptype = producedReference.getType();
            JCExpression reifiedSetExpr = makeReifiedTypeArgument(ptype);
            memberCall = make().Apply(null, makeSelect(typeCall, getterName), List.of(reifiedContainerExpr, reifiedGetExpr, reifiedSetExpr, ceylonLiteral(declaration.getName())));
        } else {
            return makeErroneous(expr, "Unsupported member type: " + declaration);
        }
        // if(objectMember){
        // // now get the instance and bind it
        // // I don't think we need any expected type since objects can't be erased
        // JCExpression object = transformExpression(expr.getObjectExpression());
        // // reset the location after we transformed the expression
        // memberCall = at(expr).Apply(null, makeSelect(memberCall, "bind"), List.of(object));
        // }
        // cast the member call because we invoke it with no Java generics
        memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_RAW | JT_NO_PRIMITIVES), memberCall);
        memberCall = make().TypeCast(makeJavaType(expr.getTypeModel(), JT_NO_PRIMITIVES), memberCall);
        return memberCall;
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) Function(org.eclipse.ceylon.model.typechecker.model.Function) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) CondList(org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.CondList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 5 with List

use of org.eclipse.ceylon.langtools.tools.javac.util.List in project ceylon by eclipse.

the class CeylonVisitor method transformSingletonConstructor.

protected void transformSingletonConstructor(HashMap<Constructor, CtorDelegation> delegates, Tree.Enumerated ctor) {
    // generate a constructor
    transformConstructor(ctor, // ctor.getParameterList(),
    null, ctor.getDelegatedConstructor(), ctor.getBlock(), ctor.getEnumerated(), delegates);
    Class clz = ModelUtil.getConstructedClass(ctor.getEnumerated());
    Value singletonModel = ctor.getDeclarationModel();
    // generate a field
    AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.singleton(gen, singletonModel.getName(), singletonModel, false);
    adb.modelAnnotations(gen.makeAtEnumerated());
    adb.modelAnnotations(gen.makeAtIgnore());
    adb.userAnnotations(gen.expressionGen().transformAnnotations(OutputElement.GETTER, ctor));
    adb.fieldAnnotations(gen.expressionGen().transformAnnotations(OutputElement.FIELD, ctor));
    // not setter
    adb.immutable();
    SyntheticName field = gen.naming.getValueConstructorFieldName(singletonModel);
    if (clz.isToplevel()) {
        adb.modifiers((singletonModel.isShared() ? PUBLIC : PRIVATE) | STATIC | FINAL);
        adb.initialValue(gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null), BoxingStrategy.BOXED);
        classBuilder.defs(adb.build());
    } else if (clz.isClassMember()) {
        int mods = 0;
        if (!singletonModel.isShared()) {
            mods |= PRIVATE;
        }
        if (clz.isClassOrInterfaceMember() && clz.isStatic()) {
            mods |= STATIC;
        }
        adb.modifiers(mods);
        // lazy
        adb.initialValue(gen.makeNull(), BoxingStrategy.BOXED);
        List<JCStatement> l = List.<JCStatement>of(gen.make().If(gen.make().Binary(JCTree.Tag.EQ, field.makeIdent(), gen.makeNull()), gen.make().Exec(gen.make().Assign(field.makeIdent(), gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null))), null), gen.make().Return(field.makeIdent()));
        adb.getterBlock(gen.make().Block(0, l));
        long mods2 = PRIVATE | TRANSIENT;
        if (clz.isStatic()) {
            mods2 |= STATIC;
        }
        classBuilder.getContainingClassBuilder().defs(gen.makeVar(mods2, field, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.getConstructedClass(ctor.getEnumerated())), gen.makeNull()));
        classBuilder.getContainingClassBuilder().defs(adb.build());
    } else {
        // LOCAL
        // we have to first make an empty box
        JCNewClass initialValue = gen.make().NewClass(null, null, gen.naming.makeTypeDeclarationExpression(null, ModelUtil.getConstructedClass(ctor.getEnumerated())), List.<JCExpression>of(gen.make().TypeCast(gen.naming.makeNamedConstructorType(ctor.getEnumerated(), false), gen.makeNull())), null);
        JCVariableDecl box = gen.makeVariableBoxDecl(gen.makeNull(), singletonModel);
        classBuilder.before(box);
        // then do the class, and after that, assign our instance to the box
        JCAssign assign = gen.make().Assign(gen.makeSelect(field.getName(), NamingBase.getGetterName(singletonModel)), initialValue);
        classBuilder.after(gen.make().Exec(assign));
    }
}
Also used : JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) JCAssign(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAssign) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) List(org.eclipse.ceylon.langtools.tools.javac.util.List) JCVariableDecl(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCVariableDecl)

Aggregations

List (org.eclipse.ceylon.langtools.tools.javac.util.List)9 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)6 ArrayList (java.util.ArrayList)5 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)5 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)5 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)5 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)4 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)4 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)4 LinkedList (java.util.LinkedList)3 JCNewClass (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass)3 Class (org.eclipse.ceylon.model.typechecker.model.Class)3 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)3 Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)3 Type (org.eclipse.ceylon.model.typechecker.model.Type)3 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)3 Value (org.eclipse.ceylon.model.typechecker.model.Value)3 CondList (org.eclipse.ceylon.compiler.java.codegen.StatementTransformer.CondList)2 AnnotationList (org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList)2 JCPrimitiveTypeTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree)2