Search in sources :

Example 21 with List

use of com.sun.tools.javac.util.List in project lombok by rzwitserloot.

the class HandleEqualsAndHashCode method createEquals.

public JCMethodDecl createEquals(JavacNode typeNode, List<JavacNode> fields, boolean callSuper, FieldAccess fieldAccess, boolean needsCanEqual, JCTree source, List<JCAnnotation> onParam) {
    JavacTreeMaker maker = typeNode.getTreeMaker();
    Name oName = typeNode.toName("o");
    Name otherName = typeNode.toName("other");
    Name thisName = typeNode.toName("this");
    JCAnnotation overrideAnnotation = maker.Annotation(genJavaLangTypeRef(typeNode, "Override"), List.<JCExpression>nil());
    JCModifiers mods = maker.Modifiers(Flags.PUBLIC, List.of(overrideAnnotation));
    JCExpression objectType = genJavaLangTypeRef(typeNode, "Object");
    JCExpression returnType = maker.TypeIdent(CTC_BOOLEAN);
    long finalFlag = JavacHandlerUtil.addFinalIfNeeded(0L, typeNode.getContext());
    ListBuffer<JCStatement> statements = new ListBuffer<JCStatement>();
    final List<JCVariableDecl> params = List.of(maker.VarDef(maker.Modifiers(finalFlag | Flags.PARAMETER, onParam), oName, objectType, null));
    /* if (o == this) return true; */
    {
        statements.append(maker.If(maker.Binary(CTC_EQUAL, maker.Ident(oName), maker.Ident(thisName)), returnBool(maker, true), null));
    }
    /* if (!(o instanceof Outer.Inner.MyType)) return false; */
    {
        JCUnary notInstanceOf = maker.Unary(CTC_NOT, maker.Parens(maker.TypeTest(maker.Ident(oName), createTypeReference(typeNode, false))));
        statements.append(maker.If(notInstanceOf, returnBool(maker, false), null));
    }
    /* Outer.Inner.MyType<?> other = (Outer.Inner.MyType<?>) o; */
    {
        if (!fields.isEmpty() || needsCanEqual) {
            final JCExpression selfType1 = createTypeReference(typeNode, true), selfType2 = createTypeReference(typeNode, true);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherName, selfType1, maker.TypeCast(selfType2, maker.Ident(oName))));
        }
    }
    /* if (!other.canEqual((java.lang.Object) this)) return false; */
    {
        if (needsCanEqual) {
            List<JCExpression> exprNil = List.nil();
            JCExpression thisRef = maker.Ident(thisName);
            JCExpression castThisRef = maker.TypeCast(genJavaLangTypeRef(typeNode, "Object"), thisRef);
            JCExpression equalityCheck = maker.Apply(exprNil, maker.Select(maker.Ident(otherName), typeNode.toName("canEqual")), List.of(castThisRef));
            statements.append(maker.If(maker.Unary(CTC_NOT, equalityCheck), returnBool(maker, false), null));
        }
    }
    /* if (!super.equals(o)) return false; */
    if (callSuper) {
        JCMethodInvocation callToSuper = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(typeNode.toName("super")), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(oName)));
        JCUnary superNotEqual = maker.Unary(CTC_NOT, callToSuper);
        statements.append(maker.If(superNotEqual, returnBool(maker, false), null));
    }
    Name thisDollar = typeNode.toName("this$");
    Name otherDollar = typeNode.toName("other$");
    for (JavacNode fieldNode : fields) {
        JCExpression fType = getFieldType(fieldNode, fieldAccess);
        JCExpression thisFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess);
        JCExpression otherFieldAccessor = createFieldAccessor(maker, fieldNode, fieldAccess, maker.Ident(otherName));
        if (fType instanceof JCPrimitiveTypeTree) {
            switch(((JCPrimitiveTypeTree) fType).getPrimitiveTypeKind()) {
                case FLOAT:
                    /* if (Float.compare(this.fieldName, other.fieldName) != 0) return false; */
                    statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, false));
                    break;
                case DOUBLE:
                    /* if (Double.compare(this.fieldName, other.fieldName) != 0) return false; */
                    statements.append(generateCompareFloatOrDouble(thisFieldAccessor, otherFieldAccessor, maker, typeNode, true));
                    break;
                default:
                    /* if (this.fieldName != other.fieldName) return false; */
                    statements.append(maker.If(maker.Binary(CTC_NOT_EQUAL, thisFieldAccessor, otherFieldAccessor), returnBool(maker, false), null));
                    break;
            }
        } else if (fType instanceof JCArrayTypeTree) {
            /* if (!java.util.Arrays.deepEquals(this.fieldName, other.fieldName)) return false; //use equals for primitive arrays. */
            boolean multiDim = ((JCArrayTypeTree) fType).elemtype instanceof JCArrayTypeTree;
            boolean primitiveArray = ((JCArrayTypeTree) fType).elemtype instanceof JCPrimitiveTypeTree;
            boolean useDeepEquals = multiDim || !primitiveArray;
            JCExpression eqMethod = chainDots(typeNode, "java", "util", "Arrays", useDeepEquals ? "deepEquals" : "equals");
            List<JCExpression> args = List.of(thisFieldAccessor, otherFieldAccessor);
            statements.append(maker.If(maker.Unary(CTC_NOT, maker.Apply(List.<JCExpression>nil(), eqMethod, args)), returnBool(maker, false), null));
        } else /* objects */
        {
            /* final java.lang.Object this$fieldName = this.fieldName; */
            /* final java.lang.Object other$fieldName = other.fieldName; */
            /* if (this$fieldName == null ? other$fieldName != null : !this$fieldName.equals(other$fieldName)) return false; */
            Name fieldName = ((JCVariableDecl) fieldNode.get()).name;
            Name thisDollarFieldName = thisDollar.append(fieldName);
            Name otherDollarFieldName = otherDollar.append(fieldName);
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), thisDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), thisFieldAccessor));
            statements.append(maker.VarDef(maker.Modifiers(finalFlag), otherDollarFieldName, genJavaLangTypeRef(typeNode, "Object"), otherFieldAccessor));
            JCExpression thisEqualsNull = maker.Binary(CTC_EQUAL, maker.Ident(thisDollarFieldName), maker.Literal(CTC_BOT, null));
            JCExpression otherNotEqualsNull = maker.Binary(CTC_NOT_EQUAL, maker.Ident(otherDollarFieldName), maker.Literal(CTC_BOT, null));
            JCExpression thisEqualsThat = maker.Apply(List.<JCExpression>nil(), maker.Select(maker.Ident(thisDollarFieldName), typeNode.toName("equals")), List.<JCExpression>of(maker.Ident(otherDollarFieldName)));
            JCExpression fieldsAreNotEqual = maker.Conditional(thisEqualsNull, otherNotEqualsNull, maker.Unary(CTC_NOT, thisEqualsThat));
            statements.append(maker.If(fieldsAreNotEqual, returnBool(maker, false), null));
        }
    }
    /* return true; */
    {
        statements.append(returnBool(maker, true));
    }
    JCBlock body = maker.Block(0, statements.toList());
    return recursiveSetGeneratedBy(maker.MethodDef(mods, typeNode.toName("equals"), returnType, List.<JCTypeParameter>nil(), params, List.<JCExpression>nil(), body, null), source, typeNode.getContext());
}
Also used : JCBlock(com.sun.tools.javac.tree.JCTree.JCBlock) JavacTreeMaker(lombok.javac.JavacTreeMaker) ListBuffer(com.sun.tools.javac.util.ListBuffer) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) JCVariableDecl(com.sun.tools.javac.tree.JCTree.JCVariableDecl) Name(com.sun.tools.javac.util.Name) JCTypeParameter(com.sun.tools.javac.tree.JCTree.JCTypeParameter) JCMethodInvocation(com.sun.tools.javac.tree.JCTree.JCMethodInvocation) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JavacNode(lombok.javac.JavacNode) JCModifiers(com.sun.tools.javac.tree.JCTree.JCModifiers) JCUnary(com.sun.tools.javac.tree.JCTree.JCUnary) ArrayList(java.util.ArrayList) List(com.sun.tools.javac.util.List) JCAnnotation(com.sun.tools.javac.tree.JCTree.JCAnnotation) JCArrayTypeTree(com.sun.tools.javac.tree.JCTree.JCArrayTypeTree)

Example 22 with List

use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.

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(Decl.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(), paramModel.getModel().appliedTypedReference(cls.getType(), null), ((TypeDeclaration) cls.getContainer()).getType(), FINAL | (transformClassDeclFlags(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), DelegateType.FOR_DEFAULT_VALUE);
                        cbForDevaultValues.method(mdb);
                    }
                }
            }
            boolean addOverloadedConstructor = false;
            if (generateInstantiator) {
                if (Decl.withinInterface(cls)) {
                    MethodDefinitionBuilder instBuilder = new DefaultedArgumentInstantiator(daoAbstract, cls, constructor, instantiatorDeclCb.isCompanionBuilder()).makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
                    instantiatorDeclCb.method(instBuilder);
                }
                if (!Decl.withinInterface(cls) || !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, node, paramList, delegationConstructor);
                } else {
                    dac = new DefaultedArgumentConstructor(classBuilder.addConstructor(), cls, node, paramList, delegationConstructor);
                }
                overloadBuilder = dac.makeOverload(paramList.getModel(), param.getParameterModel(), cls.getTypeParameters());
            }
        }
    }
}
Also used : TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) TypeParameter(com.redhat.ceylon.model.typechecker.model.TypeParameter) Parameter(com.redhat.ceylon.model.typechecker.model.Parameter) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) ArrayList(java.util.ArrayList) AnnotationList(com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(com.sun.tools.javac.util.List) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(com.redhat.ceylon.model.loader.model.LazyInterface) Interface(com.redhat.ceylon.model.typechecker.model.Interface)

Example 23 with List

use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.

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 : AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) DeferredSpecification(com.redhat.ceylon.compiler.java.codegen.StatementTransformer.DeferredSpecification) ArrayList(java.util.ArrayList) JCStatement(com.sun.tools.javac.tree.JCTree.JCStatement) Function(com.redhat.ceylon.model.typechecker.model.Function) JCPrimitiveTypeTree(com.sun.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) AnnotationList(com.redhat.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(com.sun.tools.javac.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) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) FunctionArgument(com.redhat.ceylon.compiler.typechecker.tree.Tree.FunctionArgument) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) BaseMemberExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) MethodDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) AttributeDeclaration(com.redhat.ceylon.compiler.typechecker.tree.Tree.AttributeDeclaration) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) LazySpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.LazySpecifierExpression) SpecifierOrInitializerExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierOrInitializerExpression) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) SpecifierExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.SpecifierExpression) BaseMemberExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression) FunctionOrValue(com.redhat.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(com.redhat.ceylon.model.loader.model.JavaBeanValue) 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) BaseMemberExpression(com.redhat.ceylon.compiler.typechecker.tree.Tree.BaseMemberExpression)

Example 24 with List

use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.

the class ExpressionTransformer method transformQualifiedInstantiation.

private JCExpression transformQualifiedInstantiation(Invocation invocation, CallBuilder callBuilder, TransformedInvocationPrimary transformedPrimary) {
    Tree.QualifiedTypeExpression qte = (Tree.QualifiedTypeExpression) invocation.getPrimary();
    Declaration declaration = qte.getDeclaration();
    invocation.location(callBuilder);
    if (Decl.isJavaStaticOrInterfacePrimary(invocation.getPrimary())) {
        callBuilder.instantiate(transformedPrimary.expr);
    } else if (!Strategy.generateInstantiator(declaration)) {
        if (Decl.isConstructorPrimary(invocation.getPrimary())) {
            if (Decl.getConstructedClass(invocation.getPrimaryDeclaration()).isMember()) /*&& invocation.getPrimary() instanceof Tree.QualifiedTypeExpression
                        && !(((Tree.QualifiedTypeExpression)invocation.getPrimary()).getPrimary() instanceof Tree.BaseTypeExpression)*/
            {
                callBuilder.instantiate(new ExpressionAndType(transformedPrimary.expr, null), makeJavaType(invocation.getReturnType(), JT_CLASS_NEW | (transformedPrimary.expr == null ? 0 : JT_NON_QUALIFIED)));
            } else {
                callBuilder.instantiate(makeJavaType(invocation.getReturnType(), JT_CLASS_NEW));
            }
        } else {
            JCExpression qualifier;
            JCExpression qualifierType;
            if (declaration.getContainer() instanceof Interface) {
                // When doing qualified invocation through an interface we need
                // to get the companion.
                Interface qualifyingInterface = (Interface) declaration.getContainer();
                qualifier = transformedPrimary.expr;
                qualifierType = makeJavaType(qualifyingInterface.getType(), JT_COMPANION);
            } else {
                qualifier = transformedPrimary.expr;
                if (declaration.getContainer() instanceof TypeDeclaration) {
                    qualifierType = makeJavaType(((TypeDeclaration) declaration.getContainer()).getType());
                } else {
                    qualifierType = null;
                }
            }
            Type classType = (Type) qte.getTarget();
            JCExpression type;
            // special case for package-qualified things that are not really qualified
            if (qualifier == null) {
                type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW);
            } else {
                // Note: here we're not fully qualifying the class name because the JLS says that if "new" is qualified the class name
                // is qualified relative to it
                type = makeJavaType(classType, AbstractTransformer.JT_CLASS_NEW | AbstractTransformer.JT_NON_QUALIFIED);
            }
            callBuilder.instantiate(new ExpressionAndType(qualifier, qualifierType), type);
        }
    } else {
        // instantiator
        callBuilder.typeArguments(List.<JCExpression>nil());
        java.util.List<Type> typeModels = qte.getTypeArguments().getTypeModels();
        if (typeModels != null) {
            for (Type tm : typeModels) {
                callBuilder.typeArgument(makeJavaType(tm, AbstractTransformer.JT_TYPE_ARGUMENT));
            }
        }
        callBuilder.invoke(naming.makeInstantiatorMethodName(transformedPrimary.expr, Decl.getConstructedClass(declaration)));
    }
    JCExpression result = callBuilder.build();
    if (Strategy.isInstantiatorUntyped(declaration)) {
        result = make().TypeCast(makeJavaType(invocation.getReturnType()), result);
    }
    return result;
}
Also used : Type(com.redhat.ceylon.model.typechecker.model.Type) JCExpression(com.sun.tools.javac.tree.JCTree.JCExpression) JCTree(com.sun.tools.javac.tree.JCTree) Tree(com.redhat.ceylon.compiler.typechecker.tree.Tree) List(com.sun.tools.javac.util.List) CondList(com.redhat.ceylon.compiler.java.codegen.StatementTransformer.CondList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) Interface(com.redhat.ceylon.model.typechecker.model.Interface) ClassOrInterface(com.redhat.ceylon.model.typechecker.model.ClassOrInterface)

Example 25 with List

use of com.sun.tools.javac.util.List in project ceylon-compiler by ceylon.

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)) {
            if (Decl.getConstructedClass(declaration).isToplevel()) {
                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 (Decl.isEnumeratedConstructor(Decl.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 : Reference(com.redhat.ceylon.model.typechecker.model.Reference) TypedReference(com.redhat.ceylon.model.typechecker.model.TypedReference) Function(com.redhat.ceylon.model.typechecker.model.Function) 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) Class(com.redhat.ceylon.model.typechecker.model.Class) JCNewClass(com.sun.tools.javac.tree.JCTree.JCNewClass) List(com.sun.tools.javac.util.List) CondList(com.redhat.ceylon.compiler.java.codegen.StatementTransformer.CondList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) ParameterList(com.redhat.ceylon.model.typechecker.model.ParameterList) TypedDeclaration(com.redhat.ceylon.model.typechecker.model.TypedDeclaration) Declaration(com.redhat.ceylon.model.typechecker.model.Declaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration) TypeDeclaration(com.redhat.ceylon.model.typechecker.model.TypeDeclaration)

Aggregations

List (com.sun.tools.javac.util.List)25 JCExpression (com.sun.tools.javac.tree.JCTree.JCExpression)16 ArrayList (java.util.ArrayList)11 JCStatement (com.sun.tools.javac.tree.JCTree.JCStatement)9 ListBuffer (com.sun.tools.javac.util.ListBuffer)7 ParameterList (com.redhat.ceylon.model.typechecker.model.ParameterList)5 TypeDeclaration (com.redhat.ceylon.model.typechecker.model.TypeDeclaration)5 TypedDeclaration (com.redhat.ceylon.model.typechecker.model.TypedDeclaration)5 JCTree (com.sun.tools.javac.tree.JCTree)5 ImmutableList (com.google.common.collect.ImmutableList)4 Tree (com.redhat.ceylon.compiler.typechecker.tree.Tree)4 Class (com.redhat.ceylon.model.typechecker.model.Class)4 Declaration (com.redhat.ceylon.model.typechecker.model.Declaration)4 Value (com.redhat.ceylon.model.typechecker.model.Value)4 LombokImmutableList (lombok.core.LombokImmutableList)4 ClassOrInterface (com.redhat.ceylon.model.typechecker.model.ClassOrInterface)3 Function (com.redhat.ceylon.model.typechecker.model.Function)3 FunctionOrValue (com.redhat.ceylon.model.typechecker.model.FunctionOrValue)3 Interface (com.redhat.ceylon.model.typechecker.model.Interface)3 Parameter (com.redhat.ceylon.model.typechecker.model.Parameter)3