Search in sources :

Example 21 with Parameter

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.InitializerParameter that) {
    Parameter p = new Parameter();
    p.setDeclaration(declaration);
    p.setDefaulted(that.getSpecifierExpression() != null);
    p.setHidden(true);
    p.setName(that.getIdentifier().getText());
    that.setParameterModel(p);
    // visitDeclaration(that, p);
    super.visit(that);
    parameterList.getParameters().add(p);
}
Also used : Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter)

Example 22 with Parameter

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

the class DeclarationVisitor method visit.

@Override
public void visit(Tree.AttributeSetterDefinition that) {
    Setter s = new Setter();
    s.setImplemented(that.getBlock() != null);
    that.setDeclarationModel(s);
    visitDeclaration(that, s);
    Scope o = enterScope(s);
    Parameter p = new Parameter();
    p.setHidden(true);
    Value v = new Value();
    v.setInitializerParameter(p);
    p.setModel(v);
    v.setName(s.getName());
    p.setName(s.getName());
    p.setDeclaration(s);
    visitElement(that, v);
    unit.addDeclaration(v);
    Scope sc = getContainer(that);
    sc.addMember(v);
    s.setParameter(p);
    super.visit(that);
    exitScope(o);
    if (that.getSpecifierExpression() == null && that.getBlock() == null && !isNativeHeader(s) && !isNativeHeader(s.getGetter())) {
        that.addError("setter declaration must have a body or => specifier");
    }
}
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) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter)

Example 23 with Parameter

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

the class ClassTransformer method transformSpecifiedMethodBody.

List<JCStatement> transformSpecifiedMethodBody(Tree.MethodDeclaration def, SpecifierExpression specifierExpression) {
    final Function model = def.getDeclarationModel();
    Tree.MethodDeclaration methodDecl = def;
    boolean isLazy = specifierExpression instanceof Tree.LazySpecifierExpression;
    boolean returnNull = false;
    JCExpression bodyExpr;
    Tree.Term term = null;
    if (specifierExpression != null && specifierExpression.getExpression() != null) {
        term = Decl.unwrapExpressionsUntilTerm(specifierExpression.getExpression());
        HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(term);
        if (error != null) {
            return List.<JCStatement>of(this.makeThrowUnresolvedCompilationError(error));
        }
    }
    if (!isLazy && term instanceof Tree.FunctionArgument) {
        // Function specified with lambda: Don't bother generating a
        // Callable, just transform the expr to use as the method body.
        Tree.FunctionArgument fa = (Tree.FunctionArgument) term;
        Type resultType = model.getType();
        returnNull = Decl.isUnboxedVoid(model);
        final java.util.List<Tree.Parameter> lambdaParams = fa.getParameterLists().get(0).getParameters();
        final java.util.List<Tree.Parameter> defParams = def.getParameterLists().get(0).getParameters();
        List<Substitution> substitutions = List.nil();
        for (int ii = 0; ii < lambdaParams.size(); ii++) {
            substitutions = substitutions.append(naming.addVariableSubst((TypedDeclaration) lambdaParams.get(ii).getParameterModel().getModel(), defParams.get(ii).getParameterModel().getName()));
        }
        List<JCStatement> body = null;
        if (fa.getExpression() != null)
            bodyExpr = gen().expressionGen().transformExpression(fa.getExpression(), returnNull ? BoxingStrategy.INDIFFERENT : CodegenUtil.getBoxingStrategy(model), resultType);
        else {
            body = gen().statementGen().transformBlock(fa.getBlock());
            // useless but satisfies branch checking
            bodyExpr = null;
        }
        for (Substitution subs : substitutions) {
            subs.close();
        }
        // if we have a whole body we're done
        if (body != null)
            return body;
    } else if (!isLazy && typeFact().isCallableType(term.getTypeModel())) {
        returnNull = isAnything(term.getTypeModel()) && term.getUnboxed();
        Function method = methodDecl.getDeclarationModel();
        boolean lazy = specifierExpression instanceof Tree.LazySpecifierExpression;
        boolean inlined = CodegenUtil.canOptimiseMethodSpecifier(term, method);
        Invocation invocation;
        if ((lazy || inlined) && term instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) term).getDeclaration() instanceof Functional) {
            Declaration primaryDeclaration = ((Tree.MemberOrTypeExpression) term).getDeclaration();
            Reference producedReference = ((Tree.MemberOrTypeExpression) term).getTarget();
            invocation = new MethodReferenceSpecifierInvocation(this, (Tree.MemberOrTypeExpression) term, primaryDeclaration, producedReference, method, specifierExpression);
        } else if (!lazy && !inlined) {
            // must be a callable we stored
            String name = naming.getMethodSpecifierAttributeName(method);
            invocation = new CallableSpecifierInvocation(this, method, naming.makeUnquotedIdent(name), term, term);
        } else if (isCeylonCallableSubtype(term.getTypeModel())) {
            invocation = new CallableSpecifierInvocation(this, method, expressionGen().transformExpression(term), term, term);
        } else {
            throw new BugException(term, "unhandled primary: " + term == null ? "null" : term.getNodeType());
        }
        invocation.handleBoxing(true);
        invocation.setErased(CodegenUtil.hasTypeErased(term) || getReturnTypeOfCallable(term.getTypeModel()).isNothing());
        bodyExpr = expressionGen().transformInvocation(invocation);
    } else {
        Substitution substitution = null;
        JCStatement varDef = null;
        // Handle implementations of Java variadic methods
        Parameter lastParameter = Decl.getLastParameterFromFirstParameterList(model);
        if (lastParameter != null && Decl.isJavaVariadicIncludingInheritance(lastParameter)) {
            SyntheticName alias = naming.alias(lastParameter.getName());
            substitution = naming.addVariableSubst(lastParameter.getModel(), alias.getName());
            varDef = substituteSequentialForJavaVariadic(alias, lastParameter);
        }
        bodyExpr = expressionGen().transformExpression(model, term);
        if (varDef != null) {
            // Turn into Let for java variadic methods
            bodyExpr = make().LetExpr(List.of(varDef), bodyExpr);
            substitution.close();
        }
        // The innermost of an MPL method declared void needs to return null
        returnNull = Decl.isUnboxedVoid(model) && Decl.isMpl(model);
    }
    if (CodegenUtil.downcastForSmall(term, model)) {
        bodyExpr = expressionGen().applyErasureAndBoxing(bodyExpr, term.getTypeModel(), false, !CodegenUtil.isUnBoxed(term), CodegenUtil.getBoxingStrategy(model), model.getType(), ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK);
    }
    List<JCStatement> body;
    if (!Decl.isUnboxedVoid(model) || Decl.isMpl(model) || Strategy.useBoxedVoid(model)) {
        if (returnNull) {
            body = List.<JCStatement>of(make().Exec(bodyExpr), make().Return(makeNull()));
        } else {
            body = List.<JCStatement>of(make().Return(bodyExpr));
        }
    } else {
        body = List.<JCStatement>of(make().Exec(bodyExpr));
    }
    return body;
}
Also used : JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Function(org.eclipse.ceylon.model.typechecker.model.Function) FunctionArgument(org.eclipse.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) Substitution(org.eclipse.ceylon.compiler.java.codegen.Naming.Substitution) 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) 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) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) SyntheticName(org.eclipse.ceylon.compiler.java.codegen.Naming.SyntheticName) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter)

Example 24 with Parameter

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

the class ClassTransformer method transformClassAliasInstantiator.

/**
 * Builds the instantiator method for a class aliases. In 1.0 you can't
 * actually invoke these, they exist just so there's somewhere to put the
 * class alias annotations. In 1.2 (when we fix #1295) the
 * instantiators will actually do something.
 */
private MethodDefinitionBuilder transformClassAliasInstantiator(final Tree.AnyClass def, Class model, Type aliasedClass) {
    MethodDefinitionBuilder instantiator = MethodDefinitionBuilder.systemMethod(this, NamingBase.getAliasInstantiatorMethodName(model));
    int f = 0;
    if (Strategy.defaultParameterMethodStatic(def.getDeclarationModel())) {
        f = STATIC;
    }
    instantiator.modifiers((modifierTransformation().classFlags(model) & ~FINAL) | f);
    for (TypeParameter tp : typeParametersOfAllContainers(model, false)) {
        instantiator.typeParameter(tp);
    }
    transformTypeParameters(instantiator, model);
    instantiator.resultType(new TransformedType(makeJavaType(aliasedClass), null, makeAtNonNull()));
    instantiator.annotationFlags(Annotations.MODEL_AND_USER | Annotations.IGNORE);
    for (final Tree.Parameter param : def.getParameterList().getParameters()) {
        // Overloaded instantiators
        Parameter paramModel = param.getParameterModel();
        at(param);
        transformParameter(instantiator, param, paramModel, Decl.getMemberDeclaration(def, param));
    }
    instantiator.body(make().Throw(makeNewClass(makeJavaType(typeFact().getExceptionType(), JT_CLASS_NEW))));
    return instantiator;
}
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)

Example 25 with Parameter

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

the class ClassTransformer method transform.

public void transform(Tree.AttributeDeclaration decl, ClassDefinitionBuilder classBuilder) {
    final Value model = decl.getDeclarationModel();
    boolean withinInterface = model.isInterfaceMember();
    Tree.SpecifierOrInitializerExpression initializer = decl.getSpecifierOrInitializerExpression();
    final boolean lazy = initializer instanceof Tree.LazySpecifierExpression;
    String attrName = decl.getIdentifier().getText();
    boolean memoized = Decl.isMemoized(decl);
    boolean isStatic = model.isStatic();
    // Only a non-formal or a concrete-non-lazy attribute has a corresponding field
    // and if a captured class parameter exists with the same name we skip this part as well
    Parameter parameter = CodegenUtil.findParamForDecl(decl);
    boolean useField = !lazy && Strategy.useField(model);
    boolean createField = !lazy && !model.isFormal() && Strategy.createField(parameter, model) && !model.isJavaNative();
    boolean createCompanionField = !lazy && withinInterface && initializer != null;
    JCThrow err = null;
    JCExpression memoizedInitialValue = null;
    if (createCompanionField || createField) {
        TypedReference typedRef = getTypedReference(model);
        TypedReference nonWideningTypedRef = nonWideningTypeDecl(typedRef);
        Type nonWideningType = nonWideningType(typedRef, nonWideningTypedRef);
        if (Decl.isIndirect(decl)) {
            attrName = Naming.getAttrClassName(model, 0);
            nonWideningType = getGetterInterfaceType(model);
        }
        JCExpression initialValue = null;
        BoxingStrategy boxingStrategy = null;
        if (initializer != null) {
            Tree.Expression expression = initializer.getExpression();
            HasErrorException error = errors().getFirstExpressionErrorAndMarkBrokenness(expression.getTerm());
            int flags = CodegenUtil.downcastForSmall(expression, model) ? ExpressionTransformer.EXPR_UNSAFE_PRIMITIVE_TYPECAST_OK : 0;
            flags |= model.hasUncheckedNullType() ? ExpressionTransformer.EXPR_TARGET_ACCEPTS_NULL : 0;
            if (error != null) {
                initialValue = null;
                err = makeThrowUnresolvedCompilationError(error.getErrorMessage().getMessage());
            } else {
                boxingStrategy = useJavaBox(model, nonWideningType) && javaBoxExpression(expression.getTypeModel(), nonWideningType) ? BoxingStrategy.JAVA : CodegenUtil.getBoxingStrategy(model);
                initialValue = expressionGen().transformExpression(expression, boxingStrategy, isStatic && nonWideningType.isTypeParameter() ? typeFact().getAnythingType() : nonWideningType, flags);
            }
        }
        if (memoized) {
            memoizedInitialValue = initialValue;
            initialValue = makeDefaultExprForType(nonWideningType);
        }
        int flags = 0;
        if (!CodegenUtil.isUnBoxed(nonWideningTypedRef.getDeclaration())) {
            flags |= JT_NO_PRIMITIVES;
        }
        long modifiers = useField ? modifierTransformation().field(decl) : modifierTransformation().localVar(decl);
        // does it in those cases)
        if (parameter == null || parameter.isHidden()) {
            JCExpression type;
            if (isStatic && nonWideningType.isTypeParameter()) {
                type = make().Type(syms().objectType);
            } else {
                type = makeJavaType(nonWideningType, flags);
            }
            if (createCompanionField) {
                classBuilder.getCompanionBuilder((TypeDeclaration) model.getContainer()).field(modifiers, attrName, type, initialValue, !useField);
            } else {
                List<JCAnnotation> annos = makeAtIgnore().prependList(expressionGen().transformAnnotations(OutputElement.FIELD, decl));
                if (classBuilder.hasDelegatingConstructors()) {
                    annos = annos.prependList(makeAtNoInitCheck());
                }
                // fields should be ignored, they are accessed by the getters
                if (err == null) {
                    // TODO This should really be using AttributeDefinitionBuilder somehow
                    if (useField) {
                        AttributeDefinitionBuilder adb = AttributeDefinitionBuilder.field(this, null, attrName, model, Decl.isIndirect(decl)).fieldAnnotations(annos).fieldNullability(makeNullabilityAnnotations(model)).initialValue(initialValue, boxingStrategy).fieldVisibilityModifiers(modifiers).modifiers(modifiers);
                        classBuilder.defs(adb.buildFields());
                        List<JCStatement> buildInit = adb.buildInit(false);
                        if (!buildInit.isEmpty()) {
                            if (isStatic) {
                                classBuilder.defs(make().Block(STATIC, buildInit));
                            } else {
                                classBuilder.getInitBuilder().init(buildInit);
                            }
                        }
                    } else if (!memoized) {
                        classBuilder.field(modifiers, attrName, type, initialValue, !useField, annos);
                        if (!isEe(model) && model.isLate() && CodegenUtil.needsLateInitField(model, typeFact())) {
                            classBuilder.field(PRIVATE | Flags.VOLATILE | Flags.TRANSIENT, Naming.getInitializationFieldName(attrName), make().Type(syms().booleanType), make().Literal(false), false, makeAtIgnore());
                        }
                    }
                }
            }
        }
        // A shared attribute might be initialized in a for statement, so
        // we might need a def-assignment subst for it
        JCStatement outerSubs = statementGen().openOuterSubstitutionIfNeeded(model, model.getType(), 0);
        if (outerSubs != null) {
            classBuilder.getInitBuilder().init(outerSubs);
        }
    }
    if (useField || withinInterface || lazy) {
        boolean generateInClassOrInterface = !withinInterface || model.isShared() || isStatic;
        boolean generateInCompanionClass = withinInterface && lazy && !isStatic;
        if (generateInClassOrInterface) {
            // Generate getter in main class or interface (when shared)
            at(decl.getType());
            AttributeDefinitionBuilder getter = makeGetter(decl, false, memoizedInitialValue);
            if (err != null) {
                getter.getterBlock(make().Block(0, List.<JCStatement>of(err)));
            }
            classBuilder.attribute(getter);
        }
        if (generateInCompanionClass) {
            Interface container = (Interface) model.getContainer();
            // Generate getter in companion class
            classBuilder.getCompanionBuilder(container).attribute(makeGetter(decl, true, null));
        }
        if (Decl.isVariable(model) || model.isLate()) {
            if (generateInClassOrInterface) {
                // Generate setter in main class or interface (when shared)
                classBuilder.attribute(makeSetter(decl, false, memoizedInitialValue));
            }
            if (generateInCompanionClass) {
                Interface container = (Interface) model.getContainer();
                // Generate setter in companion class
                classBuilder.getCompanionBuilder(container).attribute(makeSetter(decl, true, null));
            }
        }
    }
}
Also used : TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) JCStatement(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCStatement) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) HasErrorException(org.eclipse.ceylon.compiler.java.codegen.recovery.HasErrorException) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) 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) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) JCAnnotation(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCAnnotation) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) JCThrow(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCThrow)

Aggregations

Parameter (org.eclipse.ceylon.model.typechecker.model.Parameter)160 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)123 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)71 Type (org.eclipse.ceylon.model.typechecker.model.Type)71 ParameterList (org.eclipse.ceylon.model.typechecker.model.ParameterList)57 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)48 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)45 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)45 Function (org.eclipse.ceylon.model.typechecker.model.Function)43 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)42 Value (org.eclipse.ceylon.model.typechecker.model.Value)42 ArrayList (java.util.ArrayList)38 JCExpression (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression)30 AnalyzerUtil.getMatchingParameter (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getMatchingParameter)27 AnalyzerUtil.getUnspecifiedParameter (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getUnspecifiedParameter)27 Functional (org.eclipse.ceylon.model.typechecker.model.Functional)27 Class (org.eclipse.ceylon.model.typechecker.model.Class)23 JCTree (org.eclipse.ceylon.langtools.tools.javac.tree.JCTree)21 CustomTree (org.eclipse.ceylon.compiler.typechecker.tree.CustomTree)19 TypedReference (org.eclipse.ceylon.model.typechecker.model.TypedReference)19