X-Git-Url: http://nitlanguage.org?ds=sidebyside diff --git a/src/semantize/typing.nit b/src/semantize/typing.nit index 462fe04..25fa0d6 100644 --- a/src/semantize/typing.nit +++ b/src/semantize/typing.nit @@ -101,9 +101,9 @@ private class TypeVisitor end # Check that `sub` is a subtype of `sup`. - # If `sub` is not a valud suptype, then display an error on `node` an return null. + # 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 insafe subtype (ie an imlicit cast is required), then return `sup`. + # If `sub` is an unsafe subtype (ie an implicit cast is required), then return `sup`. # # The point of the return type is to determinate the usable type on an expression: # If the suptype is safe, then the return type is the one on the expression typed by `sub`. @@ -112,7 +112,7 @@ private class TypeVisitor do if self.is_subtype(sub, sup) then return sub if self.is_subtype(sub, self.anchor_to(sup)) then - # FIXME workarround to the current unsafe typing policy. To remove once fixed virtual types exists. + # FIXME workaround to the current unsafe typing policy. To remove once fixed virtual types exists. #node.debug("Unsafe typing: expected {sup}, got {sub}") return sup end @@ -188,9 +188,9 @@ private class TypeVisitor if sup == null then return null # Forward error if sup == sub then - self.modelbuilder.warning(node, "Warning: Expression is already a {sup}.") + self.modelbuilder.warning(node, "useless-type-test", "Warning: Expression is already a {sup}.") else if self.is_subtype(sub, sup) then - self.modelbuilder.warning(node, "Warning: Expression is already a {sup} since it is a {sub}.") + self.modelbuilder.warning(node, "useless-type-test", "Warning: Expression is already a {sup} since it is a {sub}.") end return sup end @@ -262,6 +262,16 @@ private class TypeVisitor return null end + var info = mproperty.deprecation + if info != null and self.mpropdef.mproperty.deprecation == null then + var mdoc = info.mdoc + if mdoc != null then + self.modelbuilder.warning(node, "deprecated-method", "Deprecation Warning: Method '{name}' is deprecated: {mdoc.content.first}") + else + self.modelbuilder.warning(node, "deprecated-method", "Deprecation Warning: Method '{name}' is deprecated.") + end + end + var propdefs = mproperty.lookup_definitions(self.mmodule, unsafe_type) var mpropdef if propdefs.length == 0 then @@ -270,7 +280,7 @@ private class TypeVisitor else if propdefs.length == 1 then mpropdef = propdefs.first else - self.modelbuilder.warning(node, "Warning: confliting property definitions for property {name} in {unsafe_type}: {propdefs.join(" ")}") + self.modelbuilder.warning(node, "property-conflict", "Warning: conflicting property definitions for property {name} in {unsafe_type}: {propdefs.join(" ")}") mpropdef = mproperty.intro end @@ -294,7 +304,7 @@ private class TypeVisitor return callsite end - # Visit the expressions of args and cheik their conformity with the corresponding typi in signature + # Visit the expressions of args and check their conformity with the corresponding type in signature # The point of this method is to handle varargs correctly # Note: The signature must be correctly adapted fun check_signature(node: ANode, args: Array[AExpr], name: String, msignature: MSignature): Bool @@ -399,7 +409,7 @@ end # A specific method call site with its associated informations. class CallSite - # The assiciated node for location + # The associated node for location var node: ANode # The static type of the receiver (possibly unresolved) @@ -412,7 +422,7 @@ class CallSite var anchor: nullable MClassType # Is the receiver self? - # If "for_self", virtual types of the signature are keeped + # If "for_self", virtual types of the signature are kept # If "not_for_self", virtual type are erased var recv_is_self: Bool @@ -447,7 +457,7 @@ redef class FlowContext # Adapt the variable to a static type # Warning1: do not modify vars directly. - # Warning2: sub-flow may have cached a unadapted variabial + # Warning2: sub-flow may have cached a unadapted variable private fun set_var(variable: Variable, mtype: nullable MType) do self.vars[variable] = mtype @@ -491,7 +501,7 @@ redef class APropdef do end - # The variable associated to the reciever (if any) + # The variable associated to the receiver (if any) var selfvariable: nullable Variable end @@ -1087,19 +1097,37 @@ redef class AArrayExpr redef fun accept_typing(v) do + var mtype: nullable MType = null + var ntype = self.n_type + if ntype != null then + mtype = v.resolve_mtype(ntype) + if mtype == null then return # Skip error + end var mtypes = new Array[nullable MType] + var useless = false for e in self.n_exprs.n_exprs do var t = v.visit_expr(e) if t == null then return # Skip error end - mtypes.add(t) + if mtype != null then + if v.check_subtype(e, t, mtype) == null then return # Skip error + if t == mtype then useless = true + else + mtypes.add(t) + end + end + if mtype == null then + mtype = v.merge_types(self, mtypes) end - var mtype = v.merge_types(self, mtypes) if mtype == null then v.error(self, "Type Error: ambiguous array type {mtypes.join(" ")}") return end + if useless then + assert ntype != null + v.modelbuilder.warning(ntype, "useless-type", "Warning: useless type declaration `{mtype}` in literal Array since it can be inferred from the elements type.") + end var mclass = v.get_mclass(self, "Array") if mclass == null then return # Forward error var array_mtype = mclass.get_mtype([mtype]) @@ -1202,13 +1230,13 @@ redef class AAsNotnullExpr self.mtype = mtype if mtype isa MClassType then - v.modelbuilder.warning(self, "Warning: expression is already not null, since it is a `{mtype}`.") + v.modelbuilder.warning(self, "useless-type-test", "Warning: expression is already not null, since it is a `{mtype}`.") return end assert mtype.need_anchor var u = v.anchor_to(mtype) if not u isa MNullableType then - v.modelbuilder.warning(self, "Warning: expression is already not null, since it is a `{mtype}: {u}`.") + v.modelbuilder.warning(self, "useless-type-test", "Warning: expression is already not null, since it is a `{mtype}: {u}`.") return end end @@ -1355,6 +1383,9 @@ end redef class AStarExpr redef fun property_name do return "*" end +redef class AStarstarExpr + redef fun property_name do return "**" +end redef class ASlashExpr redef fun property_name do return "/" end @@ -1476,14 +1507,16 @@ redef class ASuperExpr redef fun accept_typing(v) do - var recvtype = v.anchor + var anchor = v.anchor + assert anchor != null + var recvtype = v.get_variable(self, v.selfvariable) assert recvtype != null var mproperty = v.mpropdef.mproperty if not mproperty isa MMethod then v.error(self, "Error: super only usable in a method") return end - var superprops = mproperty.lookup_super_definitions(v.mmodule, recvtype) + var superprops = mproperty.lookup_super_definitions(v.mmodule, anchor) if superprops.length == 0 then if mproperty.is_init and v.mpropdef.is_intro then process_superinit(v) @@ -1509,18 +1542,20 @@ redef class ASuperExpr private fun process_superinit(v: TypeVisitor) do - var recvtype = v.anchor + var anchor = v.anchor + assert anchor != null + var recvtype = v.get_variable(self, v.selfvariable) assert recvtype != null var mpropdef = v.mpropdef assert mpropdef isa MMethodDef var mproperty = mpropdef.mproperty var superprop: nullable MMethodDef = null for msupertype in mpropdef.mclassdef.supertypes do - msupertype = msupertype.anchor_to(v.mmodule, recvtype) + msupertype = msupertype.anchor_to(v.mmodule, anchor) var errcount = v.modelbuilder.toolcontext.error_count var candidate = v.try_get_mproperty_by_name2(self, msupertype, mproperty.name).as(nullable MMethod) if candidate == null then - if v.modelbuilder.toolcontext.error_count > errcount then return # Forard error + if v.modelbuilder.toolcontext.error_count > errcount then return # Forward error continue # Try next super-class end if superprop != null and candidate.is_root_init then @@ -1530,13 +1565,13 @@ redef class ASuperExpr v.error(self, "Error: conflicting super constructor to call for {mproperty}: {candidate.full_name}, {superprop.mproperty.full_name}") return end - var candidatedefs = candidate.lookup_definitions(v.mmodule, recvtype) + var candidatedefs = candidate.lookup_definitions(v.mmodule, anchor) if superprop != null and superprop.mproperty == candidate then if superprop == candidatedefs.first then continue candidatedefs.add(superprop) end if candidatedefs.length > 1 then - v.error(self, "Error: confliting property definitions for property {mproperty} in {recvtype}: {candidatedefs.join(", ")}") + v.error(self, "Error: conflicting property definitions for property {mproperty} in {recvtype}: {candidatedefs.join(", ")}") return end superprop = candidatedefs.first @@ -1728,7 +1763,7 @@ redef class ADebugTypeExpr var mtype = v.resolve_mtype(ntype) if mtype != null and mtype != expr then var umtype = v.anchor_to(mtype) - v.modelbuilder.warning(self, "Found type {expr} (-> {unsafe}), expected {mtype} (-> {umtype})") + v.modelbuilder.warning(self, "debug", "Found type {expr} (-> {unsafe}), expected {mtype} (-> {umtype})") end self.is_typed = true end