end
# Check that `sub` is a subtype of `sup`.
- # If `sub` is not a valid suptype, then display an error on `node` an return null.
- # If `sub` is a safe subtype of `sup` then return `sub`.
- # If `sub` is an unsafe subtype (ie an implicit cast is required), then return `sup`.
+ # If `sub` is not a valid suptype, then display an error on `node` and return `null`.
+ # If `sub` is a safe subtype of `sup`, then return `sub`.
+ # If `sub` is an unsafe subtype (i.e., an implicit cast is required), then return `sup`.
#
# The point of the return type is to determinate the usable type on an expression when `autocast` is true:
# If the suptype is safe, then the return type is the one on the expression typed by `sub`.
#node.debug("Unsafe typing: expected {sup}, got {sub}")
return sup
end
- if sup isa MBottomType then return null # Skip error
+ if sup isa MErrorType then return null # Skip error
if sub.need_anchor then
var u = anchor_to(sub)
self.modelbuilder.error(node, "Type Error: expected `{sup}`, got `{sub}: {u}`.")
flow.set_var(self, variable, mtype)
end
+ # Find the exact representable most specific common super-type in `col`.
+ #
+ # Try to find the most specific common type that is a super-type of each types
+ # in `col`.
+ # In most cases, the result is simply the most general type in `col`.
+ # If nullables types are involved, then the nullable information is correctly preserved.
+ # If incomparable super-types exists in `col`, them no solution is given and the `null`
+ # value is returned (since union types are non representable in Nit)
+ #
+ # The `null` values in `col` are ignored, nulltypes (MNullType) are considered.
+ #
+ # Returns the `null` value if:
+ #
+ # * `col` is empty
+ # * `col` only have null values
+ # * there is a conflict
+ #
+ # Example (with a diamond A,B,C,D):
+ #
+ # * merge(A,B,C) -> A, because A is the most general type in {A,B,C}
+ # * merge(C,B) -> null, there is conflict, because `B or C` cannot be represented
+ # * merge(A,nullable B) -> nullable A, because A is the most general type and
+ # the nullable information is preserved
fun merge_types(node: ANode, col: Array[nullable MType]): nullable MType
do
if col.length == 1 then return col.first
if map == null then is_broken = true
return map == null
end
+
+ # Information about the callsite to display on a node
+ fun dump_info(v: ASTDump): String do
+ return "{recv}.{mpropdef}{msignature}"
+ end
end
redef class Variable
#
# This attribute is meaning less on expressions not used as attributes.
var vararg_decl: Int = 0
+
+ redef fun dump_info(v) do
+ var res = super
+ var mtype = self.mtype
+ if mtype != null then
+ res += v.yellow(":{mtype}")
+ end
+ var ict = self.implicit_cast_to
+ if ict != null then
+ res += v.yellow("(.as({ict}))")
+ end
+ return res
+ end
end
redef class ABlockExpr
var newline: nullable CallSite = null
# Regex::extended, used for suffix `b` on `re`
var extended: nullable CallSite = null
- # NativeString::to_bytes_with_copy, used for prefix `b`
+ # CString::to_bytes_with_copy, used for prefix `b`
var to_bytes_with_copy: nullable CallSite = null
redef fun accept_typing(v) do
var mclass = v.get_mclass(self, "String")
if mclass == null then return # Forward error
if is_bytestring then
- to_bytes_with_copy = v.get_method(self, v.mmodule.native_string_type, "to_bytes_with_copy", false)
+ to_bytes_with_copy = v.get_method(self, v.mmodule.c_string_type, "to_bytes_with_copy", false)
mclass = v.get_mclass(self, "Bytes")
else if is_re then
to_re = v.get_method(self, mclass.mclass_type, "to_re", false)
do
v.check_expr_cast(self, self.n_expr, self.n_type)
end
+
+ redef fun dump_info(v) do
+ var res = super
+ var mtype = self.cast_type
+ if mtype != null then
+ res += v.yellow(".as({mtype})")
+ end
+ return res
+ end
+
end
redef class AAsCastExpr
fun raw_arguments: Array[AExpr] do return compute_raw_arguments
private fun compute_raw_arguments: Array[AExpr] is abstract
+
+ redef fun dump_info(v) do
+ var res = super
+ var callsite = self.callsite
+ if callsite != null then
+ res += v.yellow(" call="+callsite.dump_info(v))
+ end
+ return res
+ end
end
redef class ABinopExpr
self.is_typed = true
end
+
+ redef fun dump_info(v) do
+ var res = super
+ var callsite = self.callsite
+ if callsite != null then
+ res += v.yellow(" super-init="+callsite.dump_info(v))
+ end
+ var mpropdef = self.mpropdef
+ if mpropdef != null then
+ res += v.yellow(" call-next-method="+mpropdef.to_s)
+ end
+ return res
+ end
end
####
var args = n_args.to_a
callsite.check_signature(v, node, args)
end
+
+ redef fun dump_info(v) do
+ var res = super
+ var callsite = self.callsite
+ if callsite != null then
+ res += v.yellow(" call="+callsite.dump_info(v))
+ end
+ return res
+ end
end
####
attr_type = v.resolve_for(attr_type, recvtype, self.n_expr isa ASelfExpr)
self.attr_type = attr_type
end
+
+ redef fun dump_info(v) do
+ var res = super
+ var mproperty = self.mproperty
+ var attr_type = self.attr_type
+ if mproperty != null then
+ res += v.yellow(" attr={mproperty}:{attr_type or else "BROKEN"}")
+ end
+ return res
+ end
end
redef class AAttrExpr