Package com.redhat.ceylon.compiler.typechecker.model

Examples of com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration


    protected ProducedType getParameterTypeForValueType(ProducedReference producedReference, Parameter param) {
        // we need to find the interface for this method
        ProducedType paramType = param.getModel().getReference().getFullType().getType();
        Scope paramContainer = param.getModel().getContainer();
        if(paramContainer instanceof TypedDeclaration){
            TypedDeclaration method = (TypedDeclaration) paramContainer;
            if(method.getContainer() instanceof TypeDeclaration){
                TypeDeclaration container = (TypeDeclaration) method.getContainer();
                ProducedType qualifyingType = producedReference.getQualifyingType();
                ProducedType supertype = qualifyingType.getSupertype(container);
                return paramType.substitute(supertype.getTypeArguments());
            }
        }
View Full Code Here


     * case we want the refined decl to be the one with the non-erased type.
     * - The third special case is when we implement a declaration via multiple super types, without having any refining
     * declarations in those supertypes, simply by instantiating a common super type with different type parameters
     */
    private ProducedTypedReference getRefinedDeclaration(ProducedTypedReference typedReference, ProducedType currentType) {
        TypedDeclaration decl = typedReference.getDeclaration();
        TypedDeclaration modelRefinedDecl = (TypedDeclaration)decl.getRefinedDeclaration();
        ProducedType referenceQualifyingType = typedReference.getQualifyingType();
        boolean forMixinMethod =
                currentType != null
                && decl.getContainer() instanceof ClassOrInterface
                && referenceQualifyingType != null
                && !Decl.equal(referenceQualifyingType.getDeclaration(), currentType.getDeclaration());
        // quick exit
        if (Decl.equal(decl, modelRefinedDecl) && !forMixinMethod)
            return null;
        // modelRefinedDecl exists, but perhaps it's the toplevel refinement and not the one Java will look at
        if(!forMixinMethod)
            modelRefinedDecl = getFirstRefinedDeclaration(decl);
        TypeDeclaration qualifyingDeclaration = currentType.getDeclaration();
        if(qualifyingDeclaration instanceof ClassOrInterface){
            // if both are returning unboxed void we're good
            if(Decl.isUnboxedVoid(decl)
                    && Decl.isUnboxedVoid(modelRefinedDecl))
                return null;
            // only try to find better if we're erasing to Object and we're not returning a type param
            if(willEraseToObject(typedReference.getType())
                        || isWideningTypeArguments(decl.getType(), modelRefinedDecl.getType(), true)
                    && !isTypeParameter(typedReference.getType())){
                ClassOrInterface declaringType = (ClassOrInterface) qualifyingDeclaration;
                Set<TypedDeclaration> refinedMembers = getRefinedMembers(declaringType, decl.getName(),
                        com.redhat.ceylon.compiler.typechecker.model.Util.getSignature(decl), false);
                // now we must select a different refined declaration if we refine it more than once
                if(refinedMembers.size() > (forMixinMethod ? 0 : 1)){
                    // first case
                    for(TypedDeclaration refinedDecl : refinedMembers){
                        // get the type reference to see if any eventual type param is instantiated in our inheritance of this type/method
                        ProducedTypedReference refinedTypedReference = getRefinedTypedReference(typedReference, refinedDecl);
                        // if it is not instantiated, that's the one we're looking for
                        if(isTypeParameter(refinedTypedReference.getType()))
                            return refinedTypedReference;
                    }
                    // second case
                    for(TypedDeclaration refinedDecl : refinedMembers){
                        // get the type reference to see if any eventual type param is instantiated in our inheritance of this type/method
                        ProducedTypedReference refinedTypedReference = getRefinedTypedReference(typedReference, refinedDecl);
                        // if we're not erasing this one to Object let's select it
                        if(!willEraseToObject(refinedTypedReference.getType()) && !isWideningTypeArguments(refinedDecl.getType(), modelRefinedDecl.getType(), true))
                            return refinedTypedReference;
                    }
                    // third case
                    if(isTypeParameter(modelRefinedDecl.getType())){
                        // it can happen that we have inherited a method twice from a single refined declaration
                        // via different supertype instantiations, without having ever refined them in supertypes
                        // so we try each super type to see if we already have a matching typed reference
                        // first super type
                        ProducedType extendedType = declaringType.getExtendedType();
                        if(extendedType != null){
                            ProducedTypedReference refinedTypedReference = getRefinedTypedReference(extendedType, modelRefinedDecl);
                            ProducedType refinedType = refinedTypedReference.getType();
                            if(!isTypeParameter(refinedType)
                                    && !willEraseToObject(refinedType))
                                return refinedTypedReference;
                        }
                        // then satisfied interfaces
                        for(ProducedType satisfiedType : declaringType.getSatisfiedTypes()){
                            ProducedTypedReference refinedTypedReference = getRefinedTypedReference(satisfiedType, modelRefinedDecl);
                            ProducedType refinedType = refinedTypedReference.getType();
                            if(!isTypeParameter(refinedType)
                                    && !willEraseToObject(refinedType))
                                return refinedTypedReference;
                        }
                    }
                }
            }
            /*
             * Now there's another crazy case:
             *
             * interface Top<out Element> {
             *  Top<Element> ret => nothing;
             * }
             * interface Left satisfies Top<Integer> {}
             * interface Right satisfies Top<String> {}
             * class Bottom() satisfies Left&Right {}
             *
             * Where Bottom.ret does not exist and is typed as returning Integer&String which is Nothing, erased to Object,
             * and we look at what it refines and find only a single definition Top.ret typed as returning Integer&String (Nothing),
             * so we think there's no widening, but Java will only see Top<Integer>.ret from Left, and that's the one we want
             * to use for determining widening.
             * See https://github.com/ceylon/ceylon-compiler/issues/1765
             */
            ProducedType firstInstantiation = isInheritedWithDifferentTypeArguments(modelRefinedDecl.getContainer(), currentType);
            if(firstInstantiation != null){
                ProducedTypedReference firstInstantiationTypedReference = getRefinedTypedReference(firstInstantiation, modelRefinedDecl);
                ProducedType firstInstantiationType = firstInstantiationTypedReference.getType();
                if(isWidening(decl.getType(), firstInstantiationType)
                        || isWideningTypeArguments(decl.getType(), firstInstantiationType, true))
View Full Code Here

            return decl;
        java.util.List<ProducedType> signature = com.redhat.ceylon.compiler.typechecker.model.Util.getSignature(decl);
        ClassOrInterface container = (ClassOrInterface) decl.getContainer();
        HashSet<TypeDeclaration> visited = new HashSet<TypeDeclaration>();
        // start looking for it, but skip this type, only lookup upwards of it
        TypedDeclaration firstRefinedDeclaration = getFirstRefinedDeclaration(container, decl, signature, visited, true);
        // only keep the first refined decl if its type can be trusted: if it is not itself widening
        if(firstRefinedDeclaration != null){
            if(CodegenUtil.hasUntrustedType(firstRefinedDeclaration))
                firstRefinedDeclaration = getFirstRefinedDeclaration(firstRefinedDeclaration);
        }
View Full Code Here

            java.util.List<ProducedType> signature, HashSet<TypeDeclaration> visited,
            boolean skipType) {
        if(!visited.add(typeDecl))
            return null;
        if(!skipType){
            TypedDeclaration member = (TypedDeclaration) typeDecl.getDirectMember(decl.getName(), signature, false);
            if(member != null)
                return member;
        }
        // look up
        // first look in super types
        if(typeDecl.getExtendedTypeDeclaration() != null){
            TypedDeclaration refinedDecl = getFirstRefinedDeclaration(typeDecl.getExtendedTypeDeclaration(), decl, signature, visited, false);
            if(refinedDecl != null)
                return refinedDecl;
        }
        // look in interfaces
        for(TypeDeclaration interf : typeDecl.getSatisfiedTypeDeclarations()){
            TypedDeclaration refinedDecl = getFirstRefinedDeclaration(interf, decl, signature, visited, false);
            if(refinedDecl != null)
                return refinedDecl;
        }
        // not found
        return null;
View Full Code Here

            for (ProducedType st: decl.getSatisfiedTypes()) {
                collectRefinedMembers(st, name, signature, ellipsis, visited, ret, false);
            }
            // we're collecting refined members, not the refining one
            if(!ignoreFirst){
                TypedDeclaration found = (TypedDeclaration) decl.getDirectMember(name, signature, ellipsis);
                if(found instanceof Method){
                    // do not trust getDirectMember because if you ask it for [Integer,String] and it has [Integer,E] it does not
                    // know that E=String and will not make it match, and will just return any member when there is overloading,
                    // including one with signature [String] when you asked for [Integer,String]
                    java.util.List<ProducedType> typedSignature = getTypedSignature(currentType, found);
View Full Code Here

        if (producedReference == null) {
            return parameter.getType();
        }
        final ProducedTypedReference producedTypedReference = producedReference.getTypedParameter(parameter);
        final ProducedType type = functional ? producedTypedReference.getFullType() : producedTypedReference.getType();
        final TypedDeclaration producedParameterDecl = producedTypedReference.getDeclaration();
        final ProducedType declType = producedParameterDecl.getType();
        // be more resilient to upstream errors
        if(declType == null)
            return typeFact.getUnknownType();
        final TypeDeclaration declTypeDecl = declType.getDeclaration();
        if(isJavaVariadic(parameter) && (flags & TP_SEQUENCED_TYPE) == 0){
View Full Code Here

        }
       
        // Try to find the original declaration, in case we have conditionals that refine the type of objects without us
        // creating a tmp variable (in which case we have a substitution for it)
        while(decl instanceof TypedDeclaration){
            TypedDeclaration typedDecl = (TypedDeclaration) decl;
            if(!naming.isSubstituted(decl) && typedDecl.getOriginalDeclaration() != null){
                decl = ((TypedDeclaration) decl).getOriginalDeclaration();
            }else{
                break;
            }
        }
       
        // Explanation: primaryExpr and qualExpr both specify what is to come before the selector
        // but the important difference is that primaryExpr is used for those situations where
        // the result comes from the actual Ceylon code while qualExpr is used for those situations
        // where we need to refer to synthetic objects (like wrapper classes for toplevel methods)
       
        JCExpression qualExpr = null;
        String selector = null;
        // true for Java interop using fields, and for super constructor parameters, which must use
        // parameters rather than getter methods
        boolean mustUseField = false;
        // true for default parameter methods
        boolean mustUseParameter = false;
        if (decl instanceof Functional
                && (!(decl instanceof Method) || !decl.isParameter()
                        || functionalParameterRequiresCallable((Method)decl, expr))
                && isFunctionalResult(expr.getTypeModel())) {
            result = transformFunctional(expr, (Functional)decl);
        } else if (Decl.isGetter(decl)) {
            // invoke the getter
            if (decl.isToplevel()) {
                primaryExpr = null;
                qualExpr = naming.makeName((Value)decl, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER);
                selector = null;
            } else if (Decl.withinClassOrInterface(decl) && !Decl.isLocalToInitializer(decl)) {
                selector = naming.selector((Value)decl);
            } else {
                // method local attr
                if (!isRecursiveReference(expr)) {
                    primaryExpr = naming.makeQualifiedName(primaryExpr, (Value)decl, Naming.NA_Q_LOCAL_INSTANCE);
                }
                selector = naming.selector((Value)decl);
            }
        } else if (Decl.isValueOrSharedOrCapturedParam(decl)) {
            if (decl.isToplevel()) {
                // ERASURE
                if ("null".equals(decl.getName())) {
                    // FIXME this is a pretty brain-dead way to go about erase I think
                    result = makeNull();
                } else if (isBooleanTrue(decl)) {
                    result = makeBoolean(true);
                } else if (isBooleanFalse(decl)) {
                    result = makeBoolean(false);
                } else {
                    // it's a toplevel attribute
                    primaryExpr = naming.makeName((TypedDeclaration)decl, Naming.NA_FQ | Naming.NA_WRAPPER);
                    selector = naming.selector((TypedDeclaration)decl);
                }
            } else if (Decl.isClassAttribute(decl) || Decl.isClassParameter(decl)) {
                mustUseField = Decl.isJavaField(decl)
                        || (isWithinSuperInvocation()
                                && primaryExpr == null
                                && withinSuperInvocation == decl.getContainer());
                mustUseParameter = (primaryExpr == null && isWithinDefaultParameterExpression(decl.getContainer()));
                if (mustUseField || mustUseParameter){
                    if(decl instanceof FieldValue) {
                        selector = ((FieldValue)decl).getRealName();
                    } else if (isWithinSuperInvocation()
                            && ((Value)decl).isVariable()
                            && ((Value)decl).isCaptured()) {
                        selector = Naming.getAliasedParameterName(((Value)decl).getInitializerParameter());
                    } else {
                        selector = decl.getName();
                    }
                } else {
                    // invoke the getter, using the Java interop form of Util.getGetterName because this is the only case
                    // (Value inside a Class) where we might refer to JavaBean properties
                    selector = naming.selector((TypedDeclaration)decl);
                }
            } else if (decl.isCaptured() || decl.isShared()) {
                TypedDeclaration typedDecl = ((TypedDeclaration)decl);
                TypeDeclaration typeDecl = typedDecl.getType().getDeclaration();
                mustUseField = Decl.isBoxedVariable((TypedDeclaration)decl);
                if (Decl.isLocalNotInitializer(typeDecl)
                        && typeDecl.isAnonymous()
                        // we need the box if it's a captured object
                        && !typedDecl.isSelfCaptured()) {
                    // accessing a local 'object' declaration, so don't need a getter
                } else if (decl.isCaptured()
                        && !((TypedDeclaration) decl).isVariable()
                        // captured objects are never variable but need the box
                        && !typedDecl.isSelfCaptured()) {
                    // accessing a local that is not getter wrapped
                } else {
                    primaryExpr = naming.makeQualifiedName(primaryExpr, (TypedDeclaration)decl, Naming.NA_Q_LOCAL_INSTANCE);
                    selector = naming.selector((TypedDeclaration)decl);
                }
View Full Code Here

       
        // FIXME: can this be anything else than a Tree.MemberOrTypeExpression or Tree.ParameterizedExpression?
        final JCExpression rhs;
        BoxingStrategy boxing;
        if (leftTerm instanceof Tree.MemberOrTypeExpression) {
            TypedDeclaration decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression)leftTerm).getDeclaration();
            boxing = CodegenUtil.getBoxingStrategy(decl);
            rhs = transformExpression(rightTerm, boxing, leftTerm.getTypeModel(),
                                      decl.hasUncheckedNullType() ? EXPR_TARGET_ACCEPTS_NULL : 0);
        } else {
            // instanceof Tree.ParameterizedExpression
            boxing = CodegenUtil.getBoxingStrategy(leftTerm);
            Tree.ParameterizedExpression paramExpr = (Tree.ParameterizedExpression)leftTerm;
            Method decl = (Method) ((Tree.MemberOrTypeExpression)paramExpr.getPrimary()).getDeclaration();
            CallableBuilder callableBuilder = CallableBuilder.anonymous(
                    gen(),
                    (Tree.Expression)rightTerm,
                    paramExpr.getParameterLists(),
                    paramExpr.getPrimary().getTypeModel(),
                    !decl.isDeferred());
            rhs = callableBuilder.build();
        }

        if (tmpInStatement) {
            return transformAssignment(op, leftTerm, rhs);
View Full Code Here

   
    private JCExpression transformAssignment(Node op, Tree.Term leftTerm, JCExpression lhs, JCExpression rhs) {
        JCExpression result = null;

        // FIXME: can this be anything else than a Tree.StaticMemberOrTypeExpression or Tree.ParameterizedExpression?
        TypedDeclaration decl;
        if (leftTerm instanceof Tree.StaticMemberOrTypeExpression) {
            decl = (TypedDeclaration) ((Tree.StaticMemberOrTypeExpression)leftTerm).getDeclaration();
            lhs = addInterfaceImplAccessorIfRequired(lhs, (Tree.StaticMemberOrTypeExpression) leftTerm, decl);
        } else {
            // instanceof Tree.ParameterizedExpression
            decl = (TypedDeclaration) ((Tree.MemberOrTypeExpression)((Tree.ParameterizedExpression)leftTerm).getPrimary()).getDeclaration();
        }

        boolean variable = decl.isVariable();
       
        at(op);
        String selector = naming.selector(decl, Naming.NA_SETTER);
        if (decl.isToplevel()) {
            // must use top level setter
            lhs = naming.makeName(decl, Naming.NA_FQ | Naming.NA_WRAPPER);
        } else if (Decl.isGetter(decl)) {
            if (Decl.isTransient(decl) && !decl.isVariable()) {
                JCExpression attr = gen().transformAttributeGetter(decl, rhs);
                result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER), attr);
            } else {
                // must use the setter
                if (Decl.isLocal(decl)) {
                    lhs = naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER | Naming.NA_SETTER);
                } else if (decl.isStaticallyImportable()) {
                    lhs = naming.makeTypeDeclarationExpression(null, (TypeDeclaration)decl.getContainer(), DeclNameFlag.QUALIFIED);
                }
            }
        } else if (decl instanceof Method && Decl.isDeferred(decl)) {
            if (Decl.isLocal(decl)) {
                // Deferred method initialization of a local function
                // The Callable field has the same name as the method, so use NA_MEMBER
                result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER_UNQUOTED | Naming.NA_MEMBER), rhs);
            } else {
                // Deferred method initialization of a class function
                result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_MEMBER), rhs);
            }
        } else if ((variable || decl.isLate()) && (Decl.isClassAttribute(decl))) {
            // must use the setter, nothing to do, unless it's a java field
            if(Decl.isJavaField(decl)){
                if (decl.isStaticallyImportable()) {
                    // static field
                    result = at(op).Assign(naming.makeName(decl, Naming.NA_FQ | Naming.NA_WRAPPER_UNQUOTED), rhs);
                }else{
                    // normal field
                    result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_IDENT), rhs);
                }
            }

        } else if (variable && (decl.isCaptured() || decl.isShared())) {
            // must use the qualified setter
            if (Decl.isBoxedVariable(decl)) {
                result = at(op).Assign(naming.makeName(decl, Naming.NA_Q_LOCAL_INSTANCE | Naming.NA_MEMBER | Naming.NA_SETTER), rhs);
            } else if (Decl.isLocalNotInitializer(decl)) {
                lhs = naming.makeQualifiedName(lhs, decl, Naming.NA_WRAPPER);
            } else if (isWithinSuperInvocation()
                    && decl.isCaptured()
                    && decl.isVariable()) {
                lhs = naming.makeUnquotedIdent(Naming.getAliasedParameterName(((Value)decl).getInitializerParameter()));
                result = at(op).Assign(lhs, rhs);
            }
        } else {
            result = at(op).Assign(naming.makeQualifiedName(lhs, decl, Naming.NA_IDENT), rhs);
View Full Code Here

        if (that instanceof Tree.MemberOrTypeExpression) {
            final Declaration decl = ((Tree.MemberOrTypeExpression) that).getDeclaration();
            if (!(decl instanceof TypedDeclaration)) {
                return;
            }
            TypedDeclaration d = (TypedDeclaration) decl;
            if (Decl.equal(d, declaration)) {
                if (Decl.isParameter(d)) {
                    // a reference from a default argument
                    // expression of the same parameter
                    // list does not capture a parameter
                    boolean sameScope = d.getContainer().equals(that.getScope());
                    if (!sameScope || methodSpecifier || inLazySpecifierExpression) {
                        ((MethodOrValue)d).setCaptured(true);
                    }
                   
                    // Accessing another instance's member passed to a class initializer
View Full Code Here

TOP

Related Classes of com.redhat.ceylon.compiler.typechecker.model.TypedDeclaration

Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.