Search in sources :

Example 1 with Parameter

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

the class ClassOrPackageDoc method getParametersAssertions.

private Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> getParametersAssertions(final Declaration decl) {
    final Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> parametersAssertions = new LinkedHashMap<Parameter, Map<Tree.Assertion, List<Tree.Condition>>>();
    if (((Functional) decl).getParameterLists().isEmpty()) {
        return parametersAssertions;
    }
    Node node = tool.getNode(decl);
    PhasedUnit pu = tool.getUnit(decl);
    if (node == null || pu == null) {
        return parametersAssertions;
    }
    Tree.Body body = null;
    if (node instanceof Tree.MethodDefinition) {
        body = ((Tree.MethodDefinition) node).getBlock();
    } else if (node instanceof Tree.ClassDefinition) {
        body = ((Tree.ClassDefinition) node).getClassBody();
    }
    if (body == null) {
        return parametersAssertions;
    }
    final Map<String, Parameter> parametersNames = new HashMap<String, Parameter>();
    for (ParameterList parameterList : ((Functional) decl).getParameterLists()) {
        for (Parameter parameter : parameterList.getParameters()) {
            parametersNames.put(parameter.getName(), parameter);
        }
    }
    body.visitChildren(new Visitor() {

        private boolean stop = false;

        private Tree.Assertion assertion = null;

        private Set<Parameter> referencedParameters = new HashSet<Parameter>();

        @Override
        public void visit(Tree.Assertion that) {
            assertion = that;
            super.visit(that);
            assertion = null;
        }

        @Override
        public void visit(Tree.Condition that) {
            referencedParameters.clear();
            super.visit(that);
            if (assertion != null && !referencedParameters.isEmpty()) {
                for (Parameter referencedParameter : referencedParameters) {
                    Map<Tree.Assertion, List<Tree.Condition>> parameterAssertions = parametersAssertions.get(referencedParameter);
                    if (parameterAssertions == null) {
                        parameterAssertions = new LinkedHashMap<Tree.Assertion, List<Tree.Condition>>();
                        parametersAssertions.put(referencedParameter, parameterAssertions);
                    }
                    List<Tree.Condition> parameterConditions = parameterAssertions.get(assertion);
                    if (parameterConditions == null) {
                        parameterConditions = new ArrayList<Tree.Condition>();
                        parameterAssertions.put(assertion, parameterConditions);
                    }
                    parameterConditions.add(that);
                }
            }
        }

        @Override
        public void visit(Tree.BaseMemberExpression that) {
            if (assertion != null) {
                Declaration d = that.getDeclaration();
                Scope realScope = com.redhat.ceylon.model.typechecker.model.ModelUtil.getRealScope(d.getScope());
                if (parametersNames.containsKey(d.getName()) && realScope == decl) {
                    referencedParameters.add(parametersNames.get(d.getName()));
                }
            }
            super.visit(that);
        }

        @Override
        public void visit(Tree.Statement that) {
            if (assertion == null) {
                stop = true;
            }
            super.visit(that);
        }

        @Override
        public void visitAny(Node that) {
            if (!stop) {
                super.visitAny(that);
            }
        }
    });
    return parametersAssertions;
}
Also used : Visitor(com.redhat.ceylon.compiler.typechecker.tree.Visitor) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Node(com.redhat.ceylon.compiler.typechecker.tree.Node) ArrayList(java.util.ArrayList) LinkedHashMap(java.util.LinkedHashMap) PhasedUnit(com.redhat.ceylon.compiler.typechecker.context.PhasedUnit) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) List(java.util.List) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) Util.findBottomMostRefinedDeclaration(com.redhat.ceylon.ceylondoc.Util.findBottomMostRefinedDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) HashSet(java.util.HashSet) Functional(com.redhat.ceylon.model.typechecker.model.Functional) Scope(com.redhat.ceylon.model.typechecker.model.Scope) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 2 with Parameter

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

the class ClassOrPackageDoc method writeParameters.

protected final void writeParameters(Declaration decl) throws IOException {
    if (decl instanceof Functional) {
        Map<Parameter, Map<Tree.Assertion, List<Tree.Condition>>> parametersAssertions = getParametersAssertions(decl);
        boolean first = true;
        List<ParameterList> parameterLists = ((Functional) decl).getParameterLists();
        for (ParameterList parameterList : parameterLists) {
            for (Parameter parameter : parameterList.getParameters()) {
                ParameterDocData parameterDocData = getParameterDocData(parameter, parametersAssertions);
                if (!parameterDocData.isEmpty()) {
                    if (first) {
                        first = false;
                        open("div class='parameters section'");
                        around("span class='title'", "Parameters: ");
                        open("ul");
                    }
                    open("li");
                    open("code");
                    around("span class='parameter' id='" + decl.getName() + "-" + parameter.getName() + "'", parameter.getName());
                    // if parameter is function, we need to produce links to its parameters
                    if (parameter.getModel() instanceof Function) {
                        writeParameterLinksIfRequired((Function) parameter.getModel(), false, decl.getName() + "-");
                    }
                    if (!isEmpty(parameterDocData.defaultValue)) {
                        around("span class='parameter-default-value' title='Parameter default value'", " = " + parameterDocData.defaultValue);
                    }
                    close("code");
                    if (!isEmpty(parameterDocData.doc)) {
                        around("div class='doc section'", parameterDocData.doc);
                    }
                    writeParameterAssertions(decl, parameterDocData.parameterAssertions);
                    close("li");
                }
            }
        }
        if (!first) {
            close("ul");
            close("div");
        }
    }
}
Also used : Functional(com.redhat.ceylon.model.typechecker.model.Functional) Function(com.redhat.ceylon.model.typechecker.model.Function) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map)

Example 3 with Parameter

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

the class CallableBuilder method methodReference.

/**
     * Constructs an {@code AbstractCallable} suitable for wrapping a 
     * method reference. For example:
     * <pre>
     *   void someMethod() { ... }
     *   Anything() ref = someMethod;
     * </pre>
     */
public static JCExpression methodReference(CeylonTransformer gen, final Tree.StaticMemberOrTypeExpression forwardCallTo, ParameterList parameterList) {
    ListBuffer<JCStatement> letStmts = ListBuffer.<JCTree.JCStatement>lb();
    CallableBuilder cb = new CallableBuilder(gen, forwardCallTo, forwardCallTo.getTypeModel(), parameterList);
    cb.parameterTypes = cb.getParameterTypesFromCallableModel();
    Naming.SyntheticName instanceFieldName;
    boolean instanceFieldIsBoxed = false;
    if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression && !ExpressionTransformer.isSuperOrSuperOf(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary()) && !ExpressionTransformer.isPackageQualified((Tree.QualifiedMemberOrTypeExpression) forwardCallTo)) {
        if ((((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SpreadOp)) {
            instanceFieldIsBoxed = true;
            instanceFieldName = null;
        } else {
            Tree.QualifiedMemberOrTypeExpression qmte = (Tree.QualifiedMemberOrTypeExpression) forwardCallTo;
            boolean prevCallableInv = gen.expressionGen().withinSyntheticClassBody(true);
            try {
                instanceFieldName = gen.naming.synthetic(Unfix.$instance$);
                int varTypeFlags = Decl.isPrivateAccessRequiringCompanion(qmte) ? JT_COMPANION : 0;
                Type primaryType;
                if (Decl.isValueTypeDecl(qmte.getPrimary().getTypeModel())) {
                    primaryType = qmte.getPrimary().getTypeModel();
                } else {
                    primaryType = qmte.getTarget().getQualifyingType();
                }
                if (((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getMemberOperator() instanceof Tree.SafeMemberOp) {
                    primaryType = gen.typeFact().getOptionalType(primaryType);
                }
                JCExpression primaryExpr = gen.expressionGen().transformQualifiedMemberPrimary(qmte);
                if (Decl.isPrivateAccessRequiringCompanion(qmte)) {
                    primaryExpr = gen.naming.makeCompanionAccessorCall(primaryExpr, (Interface) qmte.getDeclaration().getContainer());
                }
                Type varType = qmte.getDeclaration().isShared() ? primaryType : Decl.getPrivateAccessType(qmte);
                if (qmte.getPrimary().getUnboxed() == false) {
                    varTypeFlags |= JT_NO_PRIMITIVES;
                    instanceFieldIsBoxed = true;
                }
                letStmts.add(gen.makeVar(Flags.FINAL, instanceFieldName, gen.makeJavaType(varType, varTypeFlags), primaryExpr));
                if (qmte.getPrimary() instanceof Tree.MemberOrTypeExpression && ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration() instanceof TypedDeclaration) {
                    cb.instanceSubstitution = gen.naming.addVariableSubst((TypedDeclaration) ((Tree.MemberOrTypeExpression) qmte.getPrimary()).getDeclaration(), instanceFieldName.getName());
                }
            } finally {
                gen.expressionGen().withinSyntheticClassBody(prevCallableInv);
            }
        }
    } else {
        instanceFieldName = null;
    }
    CallableTransformation tx;
    cb.defaultValueCall = new DefaultValueMethodTransformation() {

        @Override
        public JCExpression makeDefaultValueMethod(AbstractTransformer gen, Parameter defaultedParam, List<JCExpression> defaultMethodArgs) {
            JCExpression fn = null;
            if (forwardCallTo instanceof Tree.BaseMemberOrTypeExpression) {
                fn = gen.naming.makeDefaultedParamMethod(null, defaultedParam);
            } else if (forwardCallTo instanceof Tree.QualifiedMemberOrTypeExpression) {
                JCExpression qualifier = gen.expressionGen().transformTermForInvocation(((Tree.QualifiedMemberOrTypeExpression) forwardCallTo).getPrimary(), null);
                fn = gen.naming.makeDefaultedParamMethod(qualifier, defaultedParam);
            }
            return gen.make().Apply(null, fn, defaultMethodArgs);
        }
    };
    if (cb.isVariadic) {
        tx = cb.new VariadicCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, false));
    } else {
        tx = cb.new FixedArityCallableTransformation(cb.new CallMethodWithForwardedBody(instanceFieldName, instanceFieldIsBoxed, forwardCallTo, true), null);
    }
    cb.useTransformation(tx);
    return letStmts.isEmpty() ? cb.build() : gen.make().LetExpr(letStmts.toList(), cb.build());
}
Also used : JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) SyntheticName(com.redhat.ceylon.compiler.java.codegen.Naming.SyntheticName) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Example 4 with Parameter

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

the class CallableBuilder method unboundValueMemberReference.

/**
     * Used for "static" value references. For example:
     * <pre>
     *     value x = Integer.plus;
     *     value y = Foo.method;
     *     value z = Outer.Inner;
     * </pre>
     */
public static CallableBuilder unboundValueMemberReference(CeylonTransformer gen, Tree.QualifiedMemberOrTypeExpression qmte, Type typeModel, final TypedDeclaration value) {
    CallBuilder callBuilder = CallBuilder.instance(gen);
    Type qualifyingType = qmte.getTarget().getQualifyingType();
    JCExpression target = gen.naming.makeUnquotedIdent(Unfix.$instance$);
    target = gen.expressionGen().applyErasureAndBoxing(target, qmte.getPrimary().getTypeModel(), true, BoxingStrategy.BOXED, qualifyingType);
    if (gen.expressionGen().isThrowableMessage(qmte)) {
        callBuilder.invoke(gen.utilInvocation().throwableMessage());
        callBuilder.argument(target);
    } else if (gen.expressionGen().isThrowableSuppressed(qmte)) {
        callBuilder.invoke(gen.utilInvocation().suppressedExceptions());
        callBuilder.argument(target);
    } else {
        JCExpression memberName = gen.naming.makeQualifiedName(target, value, Naming.NA_GETTER | Naming.NA_MEMBER);
        if (value instanceof FieldValue) {
            callBuilder.fieldRead(memberName);
        } else {
            callBuilder.invoke(memberName);
        }
    }
    JCExpression innerInvocation = callBuilder.build();
    // use the return type since the value is actually applied
    Type returnType = gen.getReturnTypeOfCallable(typeModel);
    innerInvocation = gen.expressionGen().applyErasureAndBoxing(innerInvocation, returnType, // expression is a Callable
    qmte.getTypeErased(), !CodegenUtil.isUnBoxed(value), BoxingStrategy.BOXED, returnType, 0);
    ParameterList outerPl = new ParameterList();
    Parameter instanceParameter = new Parameter();
    instanceParameter.setName(Naming.name(Unfix.$instance$));
    Value valueModel = new Value();
    instanceParameter.setModel(valueModel);
    Type accessType = gen.getParameterTypeOfCallable(typeModel, 0);
    ;
    if (!value.isShared()) {
        accessType = Decl.getPrivateAccessType(qmte);
    }
    valueModel.setName(instanceParameter.getName());
    valueModel.setInitializerParameter(instanceParameter);
    valueModel.setType(accessType);
    valueModel.setUnboxed(false);
    outerPl.getParameters().add(instanceParameter);
    CallableBuilder outer = new CallableBuilder(gen, null, typeModel, outerPl);
    outer.parameterTypes = outer.getParameterTypesFromParameterModels();
    List<JCStatement> innerBody = List.<JCStatement>of(gen.make().Return(innerInvocation));
    outer.useDefaultTransformation(innerBody);
    outer.companionAccess = Decl.isPrivateAccessRequiringCompanion(qmte);
    return outer;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) Value(com.redhat.ceylon.model.typechecker.model.Value) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) FieldValue(com.redhat.ceylon.model.loader.model.FieldValue) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement)

Example 5 with Parameter

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

the class ExpressionTransformer method transformArgumentsForCallableSpecifier.

private List<ExpressionAndType> transformArgumentsForCallableSpecifier(CallableSpecifierInvocation invocation) {
    List<ExpressionAndType> result = List.<ExpressionAndType>nil();
    int argIndex = 0;
    for (Parameter parameter : invocation.getMethod().getFirstParameterList().getParameters()) {
        Type exprType = expressionGen().getTypeForParameter(parameter, null, this.TP_TO_BOUND);
        Parameter declaredParameter = invocation.getMethod().getFirstParameterList().getParameters().get(argIndex);
        JCExpression arg = naming.makeName(parameter.getModel(), Naming.NA_IDENT);
        arg = expressionGen().applyErasureAndBoxing(arg, exprType, !parameter.getModel().getUnboxed(), // Callables always have boxed params 
        BoxingStrategy.BOXED, declaredParameter.getType());
        result = result.append(new ExpressionAndType(arg, makeJavaType(declaredParameter.getType())));
        argIndex++;
    }
    return result;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter)

Aggregations

Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)56 TypeParameter (com.redhat.ceylon.model.typechecker.model.TypeParameter)40 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)25 Type (com.redhat.ceylon.model.typechecker.model.Type)24 Function (com.redhat.ceylon.model.typechecker.model.Function)19 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)18 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)17 JCTree (com.sun.tools.javac.tree.JCTree)15 Class (com.redhat.ceylon.model.typechecker.model.Class)14 ArrayList (java.util.ArrayList)14 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)13 JCNewClass (com.sun.tools.javac.tree.JCTree.JCNewClass)13 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)12 Value (com.redhat.ceylon.model.typechecker.model.Value)12 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)11 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)11 TypedReference (com.redhat.ceylon.model.typechecker.model.TypedReference)11 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)10 JCPrimitiveTypeTree (com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree)9 JCTypeParameter (com.sun.tools.javac.tree.JCTree.JCTypeParameter)9