/** * 4.10: Subtyping * * @author Martin Bravenboer <martin@cs.uu.nl> */ module dryad/jls/types/Subtyping imports dryad/jls/types/Parameterized dryad/jls/types/Primitive dryad/jls/types/Reference dryad/model/- dryad/util/jtree-overlays strategies /** * Checks if the current term is a subtype of the specified type. * * @param t Type * @type Type -> Type */ is-subtype(|type) = where(supertypes; fetch(?type)) /** * The special Null type is a subtype of every type. * * @todo I think null is only a subtype of reference types. Submitted. (4.10) */ is-subtype(|type) = ?Null() ; where(<is-reference-type> type) is-proper-subtype(|type) = where(proper-supertypes; fetch(?type)) /** * Returns all (not just the direct) proper supertypes of the given Type. * * @type Type -> List(Type) */ supertypes = ![<id> | <proper-supertypes>] /** * Returns all (not just the direct) proper supertypes of the given Type. * * @type Type -> List(Type) */ proper-supertypes = ?type ; direct-supertypes => types ; new-iset ; iset-addlist(|types) ; iset-fixpoint(direct-supertypes) ; iset-elements /** * Checks if the current term is a proper supertype of the specified type */ is-proper-supertype(|of) = ?type ; where(<proper-supertypes> of; fetch(?type)) /** * Checks if the two type arguments have a subtype relation. * * @param Type * @param Type */ have-subtype-relation(|t1, t2) = <is-subtype(|t2)> t1 + <is-subtype(|t1)> t2 /** * 4.10.1: Subtyping among Primitive Types */ strategies /** * Returns the direct supertypes of a type. * * @type Type -> List(Type) */ direct-supertypes : Double() -> [] direct-supertypes : Float() -> [Double()] direct-supertypes : Long() -> [Float()] direct-supertypes : Int() -> [Long()] direct-supertypes : Char() -> [Int()] direct-supertypes : Short() -> [Int()] direct-supertypes : Byte() -> [Short()] direct-supertypes : Boolean() -> [] /** * 4.10.2: Subtyping among Class and Interface Types * * @todo Supertypes of intersection types. * @todo Supertypes of null is not supported (all reference types) * @todo A type variable is a direct supertype of its lower bound. Yikes: DRY-155 * @todo Parameterized types with wildcards. */ strategies /** * Case: Class, raw or unparameterized. */ direct-supertypes = ?type@ClassType(tn, None()) ; <log-lookup-class> tn ; direct-supertypes-of-class-helper(|type) /** * Case: Interface, raw or unparameterized. */ direct-supertypes = ?type@InterfaceType(tn, None()) ; <log-lookup-class> tn ; direct-supertypes-of-interface-helper(|type) /** * Case: Class, parameterized. * * @todo The second 'contains' option. * @todo Check the number of arguments (invoke separate strategy) */ direct-supertypes = ?type@ClassType(tn, Some(TypeArgs(args))) ; <log-lookup-class> tn ; direct-supertypes-of-class-helper(|type) ; ![ClassType(tn, None()) | <id>] /** * Case: Interface, parameterized. */ direct-supertypes = ?type@InterfaceType(tn, Some(TypeArgs(args))) ; <log-lookup-class> tn ; direct-supertypes-of-interface-helper(|type) ; ![InterfaceType(tn, None()) | <id>] strategies direct-supertypes-of-class-helper(|type) = ?class ; <get-superinterfaces(|type)> class => superinterfaces ; if <get-superclass(|type)> class => superclass then ![superclass | superinterfaces] else if not(!type => TypeObject) then log(|Error(), "Cannot find superclass of", type) end end direct-supertypes-of-interface-helper(|type) = ?class ; <get-superinterfaces(|type)> class => superinterfaces ; if !superinterfaces => [] then ![TypeObject() | <id>] end /** * Direct supertypes of type variables. * * @todo Need information about the type in which this typevar occurs. * In other words: get-upper-bound needs an 'in' argument. */ strategies direct-supertypes = ?TypeVar(Fresh(_), _) ; FreshTypeVarUpperBound direct-supertypes = ?TypeVar(qualifier, _) ; lookup-type-parameter ; get-upper-bound /** * 4.10.3: Subtyping among Array Types * * Terminology: component type (can be array) and element type (not array) */ strategies direct-supertypes = ?ArrayType(component) ; if <is-reference-type> component then <direct-supertypes> component ; map(!ArrayType(<id>)) else ![] end ; if !component => TypeObject() then ![TypeObject(), TypeCloneable(), TypeSerializable() | <id>] end ; if <is-primitive-type> component then ![TypeObject(), TypeCloneable, TypeSerializable() | <id> ] end