Search in sources :

Example 71 with Constructor

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

the class PhasedUnit method analyseFlow.

public synchronized void analyseFlow() {
    if (!flowAnalyzed) {
        rootNode.visit(new TypeHierarchyVisitor().setExceptionHandler(this));
        // System.out.println("Validate control flow for " + fileName);
        rootNode.visit(new ControlFlowVisitor().setExceptionHandler(this));
        // System.out.println("Validate specification for " + fileName);
        for (Declaration d : unit.getDeclarations()) {
            if (d.getName() != null || d instanceof Constructor) {
                rootNode.visit(new SpecificationVisitor(d).setExceptionHandler(this));
                if (d instanceof TypeDeclaration) {
                    TypeDeclaration td = (TypeDeclaration) d;
                    rootNode.visit(new SelfReferenceVisitor(td).setExceptionHandler(this));
                }
            }
        }
        flowAnalyzed = true;
    }
}
Also used : SpecificationVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.SpecificationVisitor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ControlFlowVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.ControlFlowVisitor) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) SelfReferenceVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.SelfReferenceVisitor) TypeHierarchyVisitor(org.eclipse.ceylon.compiler.typechecker.analyzer.TypeHierarchyVisitor)

Example 72 with Constructor

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

the class AbstractModelLoader method complete.

private void complete(ClassOrInterface klass, ClassMirror classMirror) {
    boolean isFromJDK = isFromJDK(classMirror);
    boolean isCeylon = (classMirror.getAnnotation(CEYLON_CEYLON_ANNOTATION) != null);
    boolean isNativeHeaderMember = klass.isNativeHeader();
    // now that everything has containers, do the inner classes
    if (klass instanceof Class == false || !klass.isOverloaded()) {
        // this will not load inner classes of overloads, but that's fine since we want them in the
        // abstracted super class (the real one)
        addInnerClasses(klass, classMirror);
    }
    // Java classes with multiple constructors get turned into multiple Ceylon classes
    // Here we get the specific constructor that was assigned to us (if any)
    MethodMirror constructor = null;
    if (klass instanceof LazyClass) {
        constructor = ((LazyClass) klass).getConstructor();
        setHasJpaConstructor((LazyClass) klass, classMirror);
    }
    // Set up enumerated constructors before looking at getters,
    // because the type of the getter is the constructor's type
    Boolean hasConstructors = hasConstructors(classMirror);
    // only add constructors to the abstraction class
    if (hasConstructors != null && hasConstructors && !klass.isOverloaded()) {
        HashMap<String, MethodMirror> m = new HashMap<>();
        MethodMirrorFilter methodFilter;
        // collect
        if (klass.isAbstraction()) {
            methodFilter = namedConstructorOnly;
        } else {
            methodFilter = constructorOnly;
        }
        // Get all the java constructors...
        for (MethodMirror ctorMirror : getClassConstructors(classMirror, classMirror, methodFilter)) {
            m.put(getCtorName(ctorMirror), ctorMirror);
        }
        for (MethodMirror ctor : getClassConstructors(classMirror, classMirror.getEnclosingClass() != null ? classMirror.getEnclosingClass() : classMirror, new ValueConstructorGetter(classMirror))) {
            Object name = getAnnotationValue(ctor, CEYLON_NAME_ANNOTATION);
            MethodMirror ctorMirror = m.remove(name);
            Constructor c;
            // When for each value constructor getter we can add a Value+Constructor
            if (ctorMirror == null) {
                // Only add a Constructor using the getter if we couldn't find a matching java constructor
                c = addConstructor((Class) klass, classMirror, ctor, isNativeHeaderMember);
            } else {
                c = addConstructor((Class) klass, classMirror, ctorMirror, isNativeHeaderMember);
            }
            FunctionOrValue fov = addConstructorMethorOrValue((Class) klass, classMirror, ctor, c, isNativeHeaderMember);
            if (isCeylon && shouldCreateNativeHeader(c, klass)) {
                Constructor hdr;
                if (ctorMirror == null) {
                    hdr = addConstructor((Class) klass, classMirror, ctor, true);
                } else {
                    hdr = addConstructor((Class) klass, classMirror, ctorMirror, true);
                }
                FunctionOrValue hdrfov = addConstructorMethorOrValue((Class) klass, classMirror, ctorMirror, hdr, true);
                initNativeHeader(hdr, c);
                initNativeHeader(hdrfov, fov);
            } else if (isCeylon && shouldLinkNatives(c)) {
                initNativeHeaderMember(c);
                initNativeHeaderMember(fov);
            }
        }
        // Everything left must be a callable constructor, so add Function+Constructor
        for (MethodMirror ctorMirror : m.values()) {
            Constructor c = addConstructor((Class) klass, classMirror, ctorMirror, isNativeHeaderMember);
            FunctionOrValue fov = addConstructorMethorOrValue((Class) klass, classMirror, ctorMirror, c, isNativeHeaderMember);
            if (isCeylon && shouldCreateNativeHeader(c, klass)) {
                Constructor hdr = addConstructor((Class) klass, classMirror, ctorMirror, true);
                FunctionOrValue hdrfov = addConstructorMethorOrValue((Class) klass, classMirror, ctorMirror, hdr, true);
                initNativeHeader(hdr, c);
                initNativeHeader(hdrfov, fov);
            } else if (isCeylon && shouldLinkNatives(c)) {
                initNativeHeaderMember(c);
                initNativeHeaderMember(fov);
            }
        }
    }
    // Turn a list of possibly overloaded methods into a map
    // of lists that contain methods with the same name
    Map<String, List<MethodMirror>> methods = new LinkedHashMap<String, List<MethodMirror>>();
    collectMethods(classMirror.getDirectMethods(), methods, isCeylon, isFromJDK);
    if (isCeylon && klass instanceof LazyInterface && JvmBackendUtil.isCompanionClassNeeded(klass)) {
        ClassMirror companionClass = ((LazyInterface) klass).companionClass;
        if (companionClass != null)
            collectMethods(companionClass.getDirectMethods(), methods, isCeylon, isFromJDK);
        else
            logWarning("CompanionClass missing for " + klass);
    }
    boolean seenStringAttribute = false;
    boolean seenHashAttribute = false;
    boolean seenStringGetter = false;
    boolean seenHashGetter = false;
    MethodMirror stringSetter = null;
    MethodMirror hashSetter = null;
    Map<String, List<MethodMirror>> getters = new HashMap<>();
    Map<String, List<MethodMirror>> setters = new HashMap<>();
    // Collect attributes
    for (List<MethodMirror> methodMirrors : methods.values()) {
        for (MethodMirror methodMirror : methodMirrors) {
            // same tests as in isMethodOverloaded()
            if (methodMirror.isConstructor() || isInstantiator(methodMirror)) {
                break;
            } else if (isGetter(methodMirror)) {
                String name = getJavaAttributeName(methodMirror);
                putMultiMap(getters, name, methodMirror);
            } else if (isSetter(methodMirror)) {
                String name = getJavaAttributeName(methodMirror);
                putMultiMap(setters, name, methodMirror);
            } else if (isHashAttribute(methodMirror)) {
                putMultiMap(getters, "hash", methodMirror);
                seenHashAttribute = true;
            } else if (isStringAttribute(methodMirror)) {
                putMultiMap(getters, "string", methodMirror);
                seenStringAttribute = true;
            } else {
                // we never map getString to a property, or generate one
                if (isStringGetter(methodMirror))
                    seenStringGetter = true;
                else // same for getHash
                if (isHashGetter(methodMirror))
                    seenHashGetter = true;
                else if (isStringSetter(methodMirror)) {
                    stringSetter = methodMirror;
                    // we will perhaps add it later
                    continue;
                } else if (isHashSetter(methodMirror)) {
                    hashSetter = methodMirror;
                    // we will perhaps add it later
                    continue;
                }
            }
        }
    }
    // now figure out which properties to add
    NEXT_PROPERTY: for (Map.Entry<String, List<MethodMirror>> getterEntry : getters.entrySet()) {
        String propertyName = getterEntry.getKey();
        List<MethodMirror> getterList = getterEntry.getValue();
        for (MethodMirror getterMethod : getterList) {
            // if it's hashCode() or toString() they win
            if (isHashAttribute(getterMethod)) {
                // ERASURE
                // Un-erasing 'hash' attribute from 'hashCode' method
                Declaration decl = addValue(klass, getterMethod, "hash", isCeylon, isNativeHeaderMember);
                if (isCeylon && shouldCreateNativeHeader(decl, klass)) {
                    Declaration hdr = addValue(klass, getterMethod, "hash", true, true);
                    setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                    initNativeHeader(hdr, decl);
                } else if (isCeylon && shouldLinkNatives(decl)) {
                    initNativeHeaderMember(decl);
                }
                // remove it as a method and add all other getters with the same name
                // as methods
                removeMultiMap(methods, getterMethod.getName(), getterMethod);
                // next property
                continue NEXT_PROPERTY;
            }
            if (isStringAttribute(getterMethod)) {
                // ERASURE
                // Un-erasing 'string' attribute from 'toString' method
                Declaration decl = addValue(klass, getterMethod, "string", isCeylon, isNativeHeaderMember);
                if (isCeylon && shouldCreateNativeHeader(decl, klass)) {
                    Declaration hdr = addValue(klass, getterMethod, "string", true, true);
                    setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                    initNativeHeader(hdr, decl);
                } else if (isCeylon && shouldLinkNatives(decl)) {
                    initNativeHeaderMember(decl);
                }
                // remove it as a method and add all other getters with the same name
                // as methods
                removeMultiMap(methods, getterMethod.getName(), getterMethod);
                // next property
                continue NEXT_PROPERTY;
            }
        }
        // we've weeded out toString/hashCode, now if we have a single property it's easy we just add it
        if (getterList.size() == 1) {
            // FTW!
            MethodMirror getterMethod = getterList.get(0);
            // simple attribute
            Declaration decl = addValue(klass, getterMethod, propertyName, isCeylon, isNativeHeaderMember);
            if (isCeylon && shouldCreateNativeHeader(decl, klass)) {
                Declaration hdr = addValue(klass, getterMethod, propertyName, true, true);
                setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                initNativeHeader(hdr, decl);
            } else if (isCeylon && shouldLinkNatives(decl)) {
                initNativeHeaderMember(decl);
            }
            // remove it as a method
            removeMultiMap(methods, getterMethod.getName(), getterMethod);
            // next property
            continue NEXT_PROPERTY;
        }
        // we have more than one
        // if we have a setter let's favour the one that matches the setter
        List<MethodMirror> matchingSetters = setters.get(propertyName);
        if (matchingSetters != null) {
            if (matchingSetters.size() == 1) {
                // single setter will tell us what we need
                MethodMirror matchingSetter = matchingSetters.get(0);
                MethodMirror bestGetter = null;
                boolean booleanSetter = matchingSetter.getParameters().get(0).getType().getKind() == TypeKind.BOOLEAN;
                /*
                     * Getters do not support overloading since they have no parameters, so they can only differ based on
                     * name. For boolean properties we favour "is" getters, otherwise "get" getters.
                     */
                for (MethodMirror getterMethod : getterList) {
                    if (propertiesMatch(klass, getterMethod, matchingSetter)) {
                        if (bestGetter == null)
                            bestGetter = getterMethod;
                        else {
                            // we have two getters, find the best one
                            if (booleanSetter) {
                                // favour the "is" getter
                                if (getterMethod.getName().startsWith("is"))
                                    bestGetter = getterMethod;
                            // else keep the current best, it must be an "is" getter
                            } else {
                                // favour the "get" getter
                                if (getterMethod.getName().startsWith("get"))
                                    bestGetter = getterMethod;
                            // else keep the current best, it must be a "get" getter
                            }
                            break;
                        }
                    }
                }
                if (bestGetter != null) {
                    // got it!
                    // simple attribute
                    Declaration decl = addValue(klass, bestGetter, propertyName, isCeylon, isNativeHeaderMember);
                    if (isCeylon && shouldCreateNativeHeader(decl, klass)) {
                        Declaration hdr = addValue(klass, bestGetter, propertyName, true, true);
                        setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                        initNativeHeader(hdr, decl);
                    } else if (isCeylon && shouldLinkNatives(decl)) {
                        initNativeHeaderMember(decl);
                    }
                    // remove it as a method and add all other getters with the same name
                    // as methods
                    removeMultiMap(methods, bestGetter.getName(), bestGetter);
                    // next property
                    continue NEXT_PROPERTY;
                }
            // else we cannot find the right getter thanks to the setter, keep looking
            }
        }
        // setters did not help us, we have more than one getter, one must be "is"/boolean, the other "get"
        if (getterList.size() == 2) {
            // if the "get" is also a boolean, prefer the "is"
            MethodMirror isMethod = null;
            MethodMirror getMethod = null;
            for (MethodMirror getterMethod : getterList) {
                if (getterMethod.getName().startsWith("is"))
                    isMethod = getterMethod;
                else if (getterMethod.getName().startsWith("get"))
                    getMethod = getterMethod;
            }
            if (isMethod != null && getMethod != null) {
                MethodMirror bestGetter;
                if (getMethod.getReturnType().getKind() == TypeKind.BOOLEAN) {
                    // pick the is method
                    bestGetter = isMethod;
                } else {
                    // just take the getter
                    bestGetter = getMethod;
                }
                // simple attribute
                Declaration decl = addValue(klass, bestGetter, propertyName, isCeylon, isNativeHeaderMember);
                if (isCeylon && shouldCreateNativeHeader(decl, klass)) {
                    Declaration hdr = addValue(klass, bestGetter, propertyName, true, true);
                    setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                    initNativeHeader(hdr, decl);
                } else if (isCeylon && shouldLinkNatives(decl)) {
                    initNativeHeaderMember(decl);
                }
                // remove it as a method and add all other getters with the same name
                // as methods
                removeMultiMap(methods, bestGetter.getName(), bestGetter);
                // next property
                continue NEXT_PROPERTY;
            }
        }
    }
    Set<String> fieldNames = new HashSet<String>();
    // collect field names first
    for (FieldMirror fieldMirror : classMirror.getDirectFields()) {
        if (!keepField(fieldMirror, isCeylon, isFromJDK))
            continue;
        // do not change the name case here otherwise it will appear taken by itself
        fieldNames.add(fieldMirror.getName());
    }
    // now handle fields
    for (FieldMirror fieldMirror : classMirror.getDirectFields()) {
        if (!keepField(fieldMirror, isCeylon, isFromJDK))
            continue;
        String name = fieldMirror.getName();
        if (!isCeylon && !JvmBackendUtil.isInitialLowerCase(name)) {
            String newName = NamingBase.getJavaBeanName(name);
            if (!fieldNames.contains(newName) && !addingFieldWouldConflictWithMember(klass, newName) && !methods.containsKey(newName))
                name = newName;
        }
        // skip the field if "we've already got one"
        boolean conflicts = addingFieldWouldConflictWithMember(klass, name);
        if (!conflicts) {
            Declaration decl = addValue(klass, name, fieldMirror, isCeylon, isNativeHeaderMember);
            if (isCeylon && shouldCreateNativeHeader(decl, klass)) {
                Declaration hdr = addValue(klass, name, fieldMirror, true, true);
                setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                initNativeHeader(hdr, decl);
            } else if (isCeylon && shouldLinkNatives(decl)) {
                initNativeHeaderMember(decl);
            }
        }
    }
    // Now mark all Values for which Setters exist as variable
    for (List<MethodMirror> variables : setters.values()) {
        for (MethodMirror setter : variables) {
            String name = getJavaAttributeName(setter);
            // make sure we handle private postfixes
            name = JvmBackendUtil.strip(name, isCeylon, setter.isPublic());
            Declaration decl = klass.getMember(name, null, false);
            // skip Java fields, which we only get if there is no getter method, in that case just add the setter method
            if (decl instanceof JavaBeanValue) {
                JavaBeanValue value = (JavaBeanValue) decl;
                // only add the setter if it has the same visibility as the getter
                if (setter.isPublic() && value.mirror.isPublic() || setter.isProtected() && value.mirror.isProtected() || setter.isDefaultAccess() && value.mirror.isDefaultAccess() || (!setter.isPublic() && !value.mirror.isPublic() && !setter.isProtected() && !value.mirror.isProtected() && !setter.isDefaultAccess() && !value.mirror.isDefaultAccess())) {
                    VariableMirror setterParam = setter.getParameters().get(0);
                    Module module = ModelUtil.getModuleContainer(klass);
                    Type paramType = obtainType(setterParam.getType(), setterParam, klass, module, "setter '" + setter.getName() + "'", klass);
                    NullStatus nullPolicy = getUncheckedNullPolicy(isCeylon, setterParam.getType(), setterParam);
                    // if there's no annotation on the setter param, inherit annotations from getter
                    if (nullPolicy == NullStatus.UncheckedNull)
                        nullPolicy = getUncheckedNullPolicy(isCeylon, value.mirror.getReturnType(), value.mirror);
                    switch(nullPolicy) {
                        case Optional:
                            if (!isCeylon) {
                                paramType = makeOptionalTypePreserveUnderlyingType(paramType, module);
                            }
                            break;
                    }
                    // only add the setter if it has exactly the same type as the getter
                    if (paramType.isExactly(value.getType())) {
                        value.setVariable(true);
                        value.setSetterName(setter.getName());
                        if (value.isTransient()) {
                            // must be a real setter
                            makeSetter(value, null);
                        }
                        if (!isCeylon && isCoercedMethod(setter)) {
                        // leave it as a method so we get a fake method for it
                        } else {
                            // remove it as a method
                            removeMultiMap(methods, setter.getName(), setter);
                        }
                    } else
                        logVerbose("Setter parameter type for " + name + " does not match corresponding getter type, adding setter as a method");
                } else {
                    logVerbose("Setter visibility for " + name + " does not match corresponding getter visibility, adding setter as a method");
                }
            }
        }
    }
    // special cases if we have hashCode() setHash() and no getHash()
    if (hashSetter != null) {
        if (seenHashAttribute && !seenHashGetter) {
            Declaration attr = klass.getDirectMember("hash", null, false);
            if (attr instanceof JavaBeanValue) {
                ((JavaBeanValue) attr).setVariable(true);
                ((JavaBeanValue) attr).setSetterName(hashSetter.getName());
                // remove it as a method
                removeMultiMap(methods, hashSetter.getName(), hashSetter);
            }
        }
    }
    // special cases if we have toString() setString() and no getString()
    if (stringSetter != null) {
        if (seenStringAttribute && !seenStringGetter) {
            Declaration attr = klass.getDirectMember("string", null, false);
            if (attr instanceof JavaBeanValue) {
                ((JavaBeanValue) attr).setVariable(true);
                ((JavaBeanValue) attr).setSetterName(stringSetter.getName());
                // remove it as a method
                removeMultiMap(methods, stringSetter.getName(), stringSetter);
            }
        }
    }
    // Add the methods, treat remaining getters/setters as methods
    for (List<MethodMirror> methodMirrors : methods.values()) {
        boolean isOverloaded = isMethodOverloaded(methodMirrors, isCeylon);
        List<Declaration> overloads = null;
        for (MethodMirror methodMirror : methodMirrors) {
            // normal method
            Function m = addMethod(klass, methodMirror, classMirror, isCeylon, isOverloaded, isNativeHeaderMember, false);
            if (!isOverloaded && isCeylon && shouldCreateNativeHeader(m, klass)) {
                Declaration hdr = addMethod(klass, methodMirror, classMirror, true, isOverloaded, true, false);
                setNonLazyDeclarationProperties(hdr, classMirror, classMirror, classMirror, true);
                initNativeHeader(hdr, m);
            } else if (isCeylon && shouldLinkNatives(m)) {
                initNativeHeaderMember(m);
            }
            if (m.isOverloaded()) {
                overloads = overloads == null ? new ArrayList<Declaration>(methodMirrors.size()) : overloads;
                overloads.add(m);
            }
            if (isOverloaded && !isCeylon && isCoercedMethod(methodMirror)) {
                Function coercionMethod = addMethod(klass, methodMirror, classMirror, isCeylon, isOverloaded, isNativeHeaderMember, true);
                coercionMethod.setRealFunction(m);
                overloads.add(coercionMethod);
            }
        }
        if (overloads != null && !overloads.isEmpty()) {
            // We create an extra "abstraction" method for overloaded methods
            Function abstractionMethod = addMethod(klass, methodMirrors.get(0), classMirror, isCeylon, false, false, false);
            abstractionMethod.setAbstraction(true);
            abstractionMethod.setOverloads(overloads);
            abstractionMethod.setType(newUnknownType());
        }
    }
    // Having loaded methods and values, we can now set the constructor parameters
    if (constructor != null && !isDefaultNamedCtor(classMirror, constructor) && (!(klass instanceof LazyClass) || !((LazyClass) klass).isAnonymous()))
        setParameters((Class) klass, classMirror, constructor, isCeylon, klass, klass.isCoercionPoint());
    // Now marry-up attributes and parameters)
    if (klass instanceof Class) {
        for (Declaration m : klass.getMembers()) {
            if (JvmBackendUtil.isValue(m)) {
                Value v = (Value) m;
                Parameter p = ((Class) klass).getParameter(v.getName());
                if (p != null) {
                    p.setHidden(true);
                }
            }
        }
    }
    setExtendedType(klass, classMirror);
    setSatisfiedTypes(klass, classMirror);
    setCaseTypes(klass, classMirror);
    setAnnotations(klass, classMirror, isNativeHeaderMember);
    if (klass instanceof Interface)
        klass.setSamName(isFunctionalInterfaceWithExceptions(classMirror));
    // local declarations come last, because they need all members to be completed first
    if (!klass.isAlias()) {
        ClassMirror containerMirror = classMirror;
        if (klass instanceof LazyInterface) {
            ClassMirror companionClass = ((LazyInterface) klass).companionClass;
            if (companionClass != null)
                containerMirror = companionClass;
        }
        addLocalDeclarations((LazyContainer) klass, containerMirror, classMirror);
    }
    if (!isCeylon) {
        // In java, a class can inherit a public member from a non-public supertype
        for (Declaration d : klass.getMembers()) {
            if (d.isShared()) {
                d.setVisibleScope(null);
            }
        }
    }
}
Also used : FieldMirror(org.eclipse.ceylon.model.loader.mirror.FieldMirror) HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) ArrayList(java.util.ArrayList) ClassMirror(org.eclipse.ceylon.model.loader.mirror.ClassMirror) LinkedHashMap(java.util.LinkedHashMap) MethodMirror(org.eclipse.ceylon.model.loader.mirror.MethodMirror) Function(org.eclipse.ceylon.model.typechecker.model.Function) LazyFunction(org.eclipse.ceylon.model.loader.model.LazyFunction) Entry(java.util.Map.Entry) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface) List(java.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) ArrayList(java.util.ArrayList) LinkedList(java.util.LinkedList) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) HashSet(java.util.HashSet) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) Type(org.eclipse.ceylon.model.typechecker.model.Type) UnknownType(org.eclipse.ceylon.model.typechecker.model.UnknownType) FunctionalInterfaceType(org.eclipse.ceylon.model.loader.mirror.FunctionalInterfaceType) VariableMirror(org.eclipse.ceylon.model.loader.mirror.VariableMirror) JavaParameterValue(org.eclipse.ceylon.model.loader.model.JavaParameterValue) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) LazyValue(org.eclipse.ceylon.model.loader.model.LazyValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) AnnotationProxyClass(org.eclipse.ceylon.model.loader.model.AnnotationProxyClass) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) LazyClass(org.eclipse.ceylon.model.loader.model.LazyClass) Module(org.eclipse.ceylon.model.typechecker.model.Module) LazyModule(org.eclipse.ceylon.model.loader.model.LazyModule) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 73 with Constructor

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

the class ExpressionTransformer method addInterfaceImplAccessorIfRequired.

// 
// Array access
private JCExpression addInterfaceImplAccessorIfRequired(JCExpression qualExpr, Tree.StaticMemberOrTypeExpression expr, Declaration decl) {
    // For interfaces we sometimes need to access either the interface instance or its $impl class
    if (decl instanceof Constructor) {
        decl = (Class) decl.getContainer();
    }
    Scope declContainer = decl.getContainer();
    if (qualExpr != null && // this is only for interface containers
    declContainer instanceof Interface && // we only ever need the $impl if the declaration is not shared
    !decl.isShared() && (!(expr instanceof Tree.QualifiedMemberExpression) || !isSuperOrSuperOf(((Tree.QualifiedMemberExpression) expr).getPrimary()))) {
        Interface declaration = (Interface) declContainer;
        // access the interface $impl instance
        qualExpr = naming.makeCompanionAccessorCall(qualExpr, declaration);
        // so we need to cast it to the type of the companion
        if (Decl.isAncestorLocal(declaration)) {
            Type type;
            // try to find the best type
            if (expr instanceof Tree.QualifiedMemberOrTypeExpression)
                type = ((Tree.QualifiedMemberOrTypeExpression) expr).getPrimary().getTypeModel();
            else
                type = declaration.getType();
            qualExpr = make().TypeCast(makeJavaType(type, JT_COMPANION), qualExpr);
        }
    }
    return qualExpr;
}
Also used : UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) Scope(org.eclipse.ceylon.model.typechecker.model.Scope) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Example 74 with Constructor

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

the class ExpressionTransformer method transformMemberExpression.

private JCExpression transformMemberExpression(Tree.StaticMemberOrTypeExpression expr, JCExpression primaryExpr, TermTransformer transformer) {
    JCExpression result = null;
    // do not throw, an error will already have been reported
    Declaration decl = expr.getDeclaration();
    if (decl == null) {
        return makeErroneous(expr, "compiler bug: expression with no declaration");
    }
    // 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;
        }
    }
    // (the header might look like a field while the implementation is a getter)
    if (decl.isNativeHeader()) {
        Declaration d = ModelUtil.getNativeDeclaration(decl, Backend.Java);
        if (d != null) {
            decl = d;
        }
    }
    // 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 Class) || ((Class) decl).getParameterList() != null) && (!(decl instanceof Function) || !decl.isParameter() || functionalParameterRequiresCallable((Function) decl, expr)) && isFunctionalResult(expr.getTypeModel())) {
        result = transformFunctional(expr, (Functional) decl, expectedType);
    } else if (coerced && decl instanceof Value && isFunctionalResult(expr.getTypeModel()) && checkForFunctionalInterface(expectedType) != null) {
        result = transformFunctionalInterfaceBridge(expr, (Value) decl, expectedType);
    } else if (coerced && decl instanceof Functional && decl.isParameter() && isFunctionalResult(expr.getTypeModel()) && checkForFunctionalInterface(expectedType) != null) {
        result = transformFunctional(expr, (Functional) decl, expectedType);
    // } else if (coerced
    // && decl instanceof Value
    // && isJavaFunctionalInterfaceResult(expr.getTypeModel())
    // && expectedType != null
    // && isCeylonCallable(expectedType)) {
    // result = transformCallableBridge(expr, (Value)decl, expectedType);
    } 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.isClassOrInterfaceMember() && !ModelUtil.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 (isNullValue(decl)) {
                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 (decl.isParameter()) {
                    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 (ModelUtil.isCaptured(decl)) {
            TypedDeclaration typedDecl = ((TypedDeclaration) decl);
            TypeDeclaration typeDecl = typedDecl.getType().getDeclaration();
            mustUseField = Decl.isBoxedVariable((TypedDeclaration) decl);
            if (ModelUtil.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);
            }
        }
    } else if (Decl.isMethodOrSharedOrCapturedParam(decl)) {
        mustUseParameter = (primaryExpr == null && decl.isParameter() && isWithinDefaultParameterExpression(decl.getContainer()));
        if (!decl.isParameter() && (ModelUtil.isLocalNotInitializer(decl) || (ModelUtil.isLocalToInitializer(decl) && ((Function) decl).isDeferred()))) {
            primaryExpr = null;
            int flags = Naming.NA_MEMBER;
            if (!isRecursiveReference(expr)) {
                // Only want to quote the method name
                // e.g. enum.$enum()
                flags |= Naming.NA_WRAPPER_UNQUOTED;
            } else if (!isReferenceInSameScope(expr)) {
                // always qualify it with this
                flags |= Naming.NA_WRAPPER | Naming.NA_WRAPPER_WITH_THIS;
            }
            qualExpr = naming.makeName((Function) decl, flags);
            selector = null;
        } else if (decl.isToplevel()) {
            primaryExpr = null;
            qualExpr = naming.makeName((Function) decl, Naming.NA_FQ | Naming.NA_WRAPPER | Naming.NA_MEMBER);
            selector = null;
        } else if (!isWithinInvocation()) {
            selector = null;
        } else if (decl.isClassOrInterfaceMember()) {
            selector = naming.selector((Function) decl);
        } else {
            selector = null;
        }
    }
    boolean isCtor = decl instanceof Function && ((Function) decl).getTypeDeclaration() instanceof Constructor;
    if (result == null) {
        boolean useGetter = !(decl instanceof Function || isCtor) && !mustUseField && !mustUseParameter;
        if (qualExpr == null && selector == null && !(isCtor)) {
            useGetter = Decl.isClassAttribute(decl) && CodegenUtil.isErasedAttribute(decl.getName());
            if (useGetter) {
                selector = naming.selector((TypedDeclaration) decl);
            } else {
                selector = naming.substitute(decl);
            }
        }
        if (qualExpr == null) {
            qualExpr = primaryExpr;
        }
        // cases
        if (!mustUseParameter) {
            qualExpr = addQualifierForObjectMembersOfInterface(expr, decl, qualExpr);
            qualExpr = addInterfaceImplAccessorIfRequired(qualExpr, expr, decl);
            qualExpr = addThisOrObjectQualifierIfRequired(qualExpr, expr, decl);
            if (qualExpr == null && expr instanceof Tree.BaseMemberExpression && needDollarThis(expr)) {
                qualExpr = makeQualifiedDollarThis((Tree.BaseMemberExpression) expr);
            }
        }
        boolean isEnumeratedConstructorGetter = false;
        if ((decl instanceof Value && ModelUtil.isEnumeratedConstructor((Value) decl))) {
            Class constructedClass = ModelUtil.getConstructedClass(decl);
            // See CeylonVisitor.transformSingletonConstructor for that logic
            if (constructedClass.isToplevel() || constructedClass.isClassMember())
                isEnumeratedConstructorGetter = true;
            else {
                // Local enumerated constructor values are boxed
                // local class will use a field
                useGetter = false;
                qualExpr = naming.makeQualifiedName(primaryExpr, (TypedDeclaration) decl, Naming.NA_Q_LOCAL_INSTANCE);
                selector = naming.selector((TypedDeclaration) decl);
            }
        }
        if (qualExpr == null && (decl.isStatic() || isEnumeratedConstructorGetter) && // and not classes
        decl.getContainer() instanceof TypeDeclaration) {
            qualExpr = naming.makeTypeDeclarationExpression(null, (TypeDeclaration) decl.getContainer(), DeclNameFlag.QUALIFIED);
        }
        if (Decl.isPrivateAccessRequiringUpcast(expr)) {
            qualExpr = makePrivateAccessUpcast(expr, qualExpr);
        }
        if (transformer != null) {
            if (decl instanceof TypedDeclaration && ((TypedDeclaration) decl).getType().isTypeConstructor()) {
                // This is a bit of a hack, but we're "invoking a type constructor"
                // so recurse to get the applied expression.
                qualExpr = transformMemberExpression(expr, qualExpr, null);
                selector = null;
            }
            result = transformer.transform(qualExpr, selector);
        } else {
            Tree.Primary qmePrimary = null;
            if (expr instanceof Tree.QualifiedMemberOrTypeExpression) {
                qmePrimary = ((Tree.QualifiedMemberOrTypeExpression) expr).getPrimary();
            }
            boolean safeMemberJavaArray = expr instanceof Tree.QualifiedMemberExpression && ((Tree.QualifiedMemberExpression) expr).getMemberOperator() instanceof Tree.SafeMemberOp && isJavaArray(qmePrimary.getTypeModel());
            if ((safeMemberJavaArray || Decl.isValueTypeDecl(qmePrimary)) && // Safe operators always work on boxed things, so don't use value types
            (safeMemberJavaArray || (expr instanceof Tree.QualifiedMemberOrTypeExpression == false) || ((Tree.QualifiedMemberOrTypeExpression) expr).getMemberOperator() instanceof Tree.MemberOp) && // We never want to use value types on boxed things, unless they are java arrays
            (CodegenUtil.isUnBoxed(qmePrimary) || isJavaArray(qmePrimary.getTypeModel())) && // Java arrays length property does not go via value types
            (!isJavaArray(qmePrimary.getTypeModel()) || (!"length".equals(selector) && !"hashCode".equals(selector)))) {
                JCExpression primTypeExpr = makeJavaType(qmePrimary.getTypeModel(), JT_NO_PRIMITIVES | JT_VALUE_TYPE);
                result = makeQualIdent(primTypeExpr, selector);
                result = make().Apply(List.<JCTree.JCExpression>nil(), result, List.<JCTree.JCExpression>of(qualExpr));
            } else if (expr instanceof Tree.QualifiedMemberOrTypeExpression && isThrowableMessage((Tree.QualifiedMemberOrTypeExpression) expr)) {
                result = utilInvocation().throwableMessage(qualExpr);
            } else if (expr instanceof Tree.QualifiedMemberOrTypeExpression && isThrowableSuppressed((Tree.QualifiedMemberOrTypeExpression) expr)) {
                result = utilInvocation().suppressedExceptions(qualExpr);
            } else {
                result = makeQualIdent(qualExpr, selector);
                if (useGetter) {
                    result = make().Apply(List.<JCTree.JCExpression>nil(), result, List.<JCTree.JCExpression>nil());
                }
            }
        }
    }
    if (transformer == null && decl instanceof TypedDeclaration && ((TypedDeclaration) decl).getType().isTypeConstructor() && !expr.getTypeArguments().getTypeModels().isEmpty()) {
        // applying a type constructor
        ListBuffer<JCExpression> tds = new ListBuffer<JCExpression>();
        for (Type t : expr.getTypeArguments().getTypeModels()) {
            tds.add(makeReifiedTypeArgument(t));
        }
        result = make().Apply(null, makeQualIdent(result, Naming.Unfix.apply.toString()), List.<JCExpression>of(make().NewArray(make().Type(syms().ceylonTypeDescriptorType), List.<JCExpression>nil(), tds.toList())));
    }
    return result;
}
Also used : TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) ListBuffer(org.eclipse.ceylon.langtools.tools.javac.util.ListBuffer) Functional(org.eclipse.ceylon.model.typechecker.model.Functional) Function(org.eclipse.ceylon.model.typechecker.model.Function) UnionType(org.eclipse.ceylon.model.typechecker.model.UnionType) Type(org.eclipse.ceylon.model.typechecker.model.Type) JCExpression(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCExpression) Value(org.eclipse.ceylon.model.typechecker.model.Value) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) Class(org.eclipse.ceylon.model.typechecker.model.Class) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) FieldValue(org.eclipse.ceylon.model.loader.model.FieldValue) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)

Example 75 with Constructor

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

the class ClassTransformer method concreteMembersFromSuperinterfaces.

/**
 * Generates companion fields ($Foo$impl) and methods
 */
private void concreteMembersFromSuperinterfaces(final Class model, ClassDefinitionBuilder classBuilder, Type satisfiedType, Set<Interface> satisfiedInterfaces) {
    satisfiedType = satisfiedType.resolveAliases();
    Interface iface = (Interface) satisfiedType.getDeclaration();
    if (satisfiedInterfaces.contains(iface) || iface.isIdentifiable()) {
        return;
    }
    // then don't instantiate it...
    if (hasImpl(iface)) {
        // ... otherwise for each satisfied interface,
        // instantiate an instance of the
        // companion class in the constructor and assign it to a
        // $Interface$impl field
        transformInstantiateCompanions(classBuilder, model, iface, satisfiedType);
    }
    if (!ModelUtil.isCeylonDeclaration(iface)) {
        // let's not try to implement CMI for Java interfaces
        return;
    }
    // For each super interface
    for (Declaration member : sortedMembers(iface.getMembers())) {
        if (member instanceof Class) {
            Class klass = (Class) member;
            final Type typedMember = satisfiedType.getTypeMember(klass, Collections.<Type>emptyList());
            if (Strategy.generateInstantiator(member) && !klass.hasConstructors() && !model.isFormal() && needsCompanionDelegate(model, typedMember) && model.getDirectMember(member.getName(), null, false) == null) {
                // instantiator method implementation
                generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, null, model.getType(), !member.isFormal());
            }
            if (klass.hasConstructors()) {
                for (Declaration m : klass.getMembers()) {
                    if (m instanceof Constructor && Strategy.generateInstantiator(m)) {
                        Constructor ctor = (Constructor) m;
                        generateInstantiatorDelegate(classBuilder, satisfiedType, iface, klass, ctor, model.getType(), true);
                    }
                }
            }
        }
        // type aliases are on the $impl class
        if (member instanceof TypeAlias)
            continue;
        if (Strategy.onlyOnCompanion(member)) {
            // (they're just private methods on the $impl)
            continue;
        }
        if (member instanceof Function) {
            Function method = (Function) member;
            final TypedReference typedMember = satisfiedType.getTypedMember(method, typesOfTypeParameters(method.getTypeParameters()));
            Declaration sub = (Declaration) model.getMember(method.getName(), getSignatureIfRequired(typedMember), false, true);
            if (sub instanceof Function) /* && !sub.isAbstraction()*/
            {
                Function subMethod = (Function) sub;
                if (subMethod.getParameterLists().isEmpty()) {
                    continue;
                }
                java.util.List<java.util.List<Type>> producedTypeParameterBounds = producedTypeParameterBounds(typedMember, subMethod);
                // final TypedReference refinedTypedMember = model.getType().getTypedMember(subMethod, Collections.<Type>emptyList());
                final java.util.List<TypeParameter> typeParameters = subMethod.getTypeParameters();
                final java.util.List<Parameter> parameters = subMethod.getFirstParameterList().getParameters();
                boolean hasOverloads = false;
                if (!satisfiedInterfaces.contains((Interface) method.getContainer())) {
                    for (Parameter param : parameters) {
                        if (Strategy.hasDefaultParameterValueMethod(param) && CodegenUtil.getTopmostRefinedDeclaration(param.getModel()).getContainer().equals(member)) {
                            final TypedReference typedParameter = typedMember.getTypedParameter(param);
                            // If that method has a defaulted parameter,
                            // we need to generate a default value method
                            // which also delegates to the $impl
                            final MethodDefinitionBuilder defaultValueDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().defaultValueMethodBridge(), typeParameters, producedTypeParameterBounds, typedParameter.getFullType(), Naming.getDefaultedParamMethodName(method, param), parameters.subList(0, parameters.indexOf(param)), param.getModel().getTypeErased(), null, param);
                            classBuilder.method(defaultValueDelegate);
                        }
                        if (Strategy.hasDefaultParameterOverload(param)) {
                            if ((method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
                                MethodDefinitionBuilder overload = new DefaultedArgumentMethodTyped(new DaoThis((Tree.AnyMethod) null, null), MethodDefinitionBuilder.method(this, subMethod), typedMember, true).makeOverload(subMethod.getFirstParameterList(), param, typeParameters);
                                classBuilder.method(overload);
                            }
                            hasOverloads = true;
                        }
                    }
                }
                // delegating to the $impl instance
                if (needsCompanionDelegate(model, typedMember)) {
                    final MethodDefinitionBuilder concreteMemberDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().methodBridge(method), typeParameters, producedTypeParameterBounds, typedMember.getType(), naming.selector(method), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), null, null);
                    classBuilder.method(concreteMemberDelegate);
                }
                if (hasOverloads && (method.isDefault() || method.isShared() && !method.isFormal()) && Decl.equal(method, subMethod)) {
                    final MethodDefinitionBuilder canonicalMethod = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().canonicalMethodBridge(), subMethod.getTypeParameters(), producedTypeParameterBounds, typedMember.getType(), Naming.selector(method, Naming.NA_CANONICAL_METHOD), method.getFirstParameterList().getParameters(), ((Function) member).getTypeErased(), naming.selector(method), null);
                    classBuilder.method(canonicalMethod);
                }
            }
        } else if (member instanceof Value || member instanceof Setter) {
            TypedDeclaration attr = (TypedDeclaration) member;
            final TypedReference typedMember = satisfiedType.getTypedMember(attr, null);
            if (needsCompanionDelegate(model, typedMember)) {
                Setter setter = (member instanceof Setter) ? (Setter) member : null;
                if (member instanceof Value) {
                    Value getter = (Value) member;
                    if (member instanceof JavaBeanValue) {
                        setter = ((Value) member).getSetter();
                    }
                    final MethodDefinitionBuilder getterDelegate = makeDelegateToCompanion(iface, typedMember, model.getType(), modifierTransformation().getterBridge(getter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typedMember.getType(), Naming.getGetterName(getter), Collections.<Parameter>emptyList(), getter.getTypeErased(), null, null);
                    classBuilder.method(getterDelegate);
                }
                if (setter != null) {
                    final MethodDefinitionBuilder setterDelegate = makeDelegateToCompanion(iface, satisfiedType.getTypedMember(setter, null), model.getType(), modifierTransformation().setterBridge(setter), Collections.<TypeParameter>emptyList(), Collections.<java.util.List<Type>>emptyList(), typeFact().getAnythingType(), Naming.getSetterName(attr), Collections.<Parameter>singletonList(setter.getParameter()), setter.getTypeErased(), null, null);
                    classBuilder.method(setterDelegate);
                }
                if (Decl.isValue(member) && ((Value) attr).isVariable()) {
                    // $impl to delegate to
                    throw new BugException("assertion failed: " + member.getQualifiedNameString() + " was unexpectedly a variable value");
                }
            }
        } else {
            Reference typedMember = member instanceof TypeDeclaration ? satisfiedType.getTypeMember((TypeDeclaration) member, Collections.<Type>emptyList()) : satisfiedType.getTypedMember((TypedDeclaration) member, Collections.<Type>emptyList());
            if (needsCompanionDelegate(model, typedMember)) {
                throw new BugException("unhandled concrete interface member " + member.getQualifiedNameString() + " " + member.getClass());
            }
        }
    }
    // Add $impl instances for the whole interface hierarchy
    satisfiedInterfaces.add(iface);
    for (Type sat : iface.getSatisfiedTypes()) {
        sat = model.getType().getSupertype(sat.getDeclaration());
        concreteMembersFromSuperinterfaces(model, classBuilder, sat, satisfiedInterfaces);
    }
}
Also used : TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Function(org.eclipse.ceylon.model.typechecker.model.Function) JCPrimitiveTypeTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCPrimitiveTypeTree) JCTree(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree) Tree(org.eclipse.ceylon.compiler.typechecker.tree.Tree) ArrayList(java.util.ArrayList) AnnotationList(org.eclipse.ceylon.compiler.typechecker.tree.Tree.AnnotationList) List(org.eclipse.ceylon.langtools.tools.javac.util.List) ParameterList(org.eclipse.ceylon.model.typechecker.model.ParameterList) Declaration(org.eclipse.ceylon.model.typechecker.model.Declaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) MethodDeclaration(org.eclipse.ceylon.compiler.typechecker.tree.Tree.MethodDeclaration) TypedDeclaration(org.eclipse.ceylon.model.typechecker.model.TypedDeclaration) ThrowerCatchallConstructor(org.eclipse.ceylon.compiler.java.codegen.recovery.ThrowerCatchallConstructor) Constructor(org.eclipse.ceylon.model.typechecker.model.Constructor) TypedReference(org.eclipse.ceylon.model.typechecker.model.TypedReference) Reference(org.eclipse.ceylon.model.typechecker.model.Reference) TypeAlias(org.eclipse.ceylon.model.typechecker.model.TypeAlias) Type(org.eclipse.ceylon.model.typechecker.model.Type) Value(org.eclipse.ceylon.model.typechecker.model.Value) FunctionOrValue(org.eclipse.ceylon.model.typechecker.model.FunctionOrValue) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) Setter(org.eclipse.ceylon.model.typechecker.model.Setter) Parameter(org.eclipse.ceylon.model.typechecker.model.Parameter) TypeParameter(org.eclipse.ceylon.model.typechecker.model.TypeParameter) Class(org.eclipse.ceylon.model.typechecker.model.Class) JCNewClass(org.eclipse.ceylon.langtools.tools.javac.tree.JCTree.JCNewClass) JavaBeanValue(org.eclipse.ceylon.model.loader.model.JavaBeanValue) TypeDeclaration(org.eclipse.ceylon.model.typechecker.model.TypeDeclaration) Interface(org.eclipse.ceylon.model.typechecker.model.Interface) ClassOrInterface(org.eclipse.ceylon.model.typechecker.model.ClassOrInterface) LazyInterface(org.eclipse.ceylon.model.loader.model.LazyInterface)

Aggregations

Constructor (org.eclipse.ceylon.model.typechecker.model.Constructor)95 TypeDeclaration (org.eclipse.ceylon.model.typechecker.model.TypeDeclaration)65 Declaration (org.eclipse.ceylon.model.typechecker.model.Declaration)48 Tree (org.eclipse.ceylon.compiler.typechecker.tree.Tree)47 Type (org.eclipse.ceylon.model.typechecker.model.Type)45 Class (org.eclipse.ceylon.model.typechecker.model.Class)42 TypedDeclaration (org.eclipse.ceylon.model.typechecker.model.TypedDeclaration)42 ClassOrInterface (org.eclipse.ceylon.model.typechecker.model.ClassOrInterface)27 TypeParameter (org.eclipse.ceylon.model.typechecker.model.TypeParameter)27 Value (org.eclipse.ceylon.model.typechecker.model.Value)27 FunctionOrValue (org.eclipse.ceylon.model.typechecker.model.FunctionOrValue)26 Scope (org.eclipse.ceylon.model.typechecker.model.Scope)25 Function (org.eclipse.ceylon.model.typechecker.model.Function)23 ModelUtil.isConstructor (org.eclipse.ceylon.model.typechecker.model.ModelUtil.isConstructor)21 ArrayList (java.util.ArrayList)20 UnknownType (org.eclipse.ceylon.model.typechecker.model.UnknownType)19 Interface (org.eclipse.ceylon.model.typechecker.model.Interface)17 AnalyzerUtil.unwrapAliasedTypeConstructor (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.unwrapAliasedTypeConstructor)16 AnalyzerUtil.getPackageTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getPackageTypeDeclaration)14 AnalyzerUtil.getTypeDeclaration (org.eclipse.ceylon.compiler.typechecker.analyzer.AnalyzerUtil.getTypeDeclaration)14