X-Git-Url: http://nitlanguage.org diff --git a/src/typing.nit b/src/typing.nit index edb1c89..d2cc5fa 100644 --- a/src/typing.nit +++ b/src/typing.nit @@ -51,6 +51,11 @@ private class TypeVisitor var selfvariable: Variable = new Variable("self") + # Is `self` use restricted? + # * no explicit `self` + # * method called on the implicit self must be top-level + var is_toplevel_context = false + init(modelbuilder: ModelBuilder, mmodule: MModule, mpropdef: nullable MPropDef) do self.modelbuilder = modelbuilder @@ -67,6 +72,11 @@ private class TypeVisitor var selfvariable = new Variable("self") self.selfvariable = selfvariable selfvariable.declared_type = mclass.mclass_type + + var mprop = mpropdef.mproperty + if mprop isa MMethod and mprop.is_toplevel then + is_toplevel_context = true + end end end @@ -241,6 +251,15 @@ private class TypeVisitor end assert mproperty isa MMethod + + if is_toplevel_context and recv_is_self and not mproperty.is_toplevel and name != "sys" and name != "exit" then + # FIXME named methods are here as a workaround + error(node, "Error: '{name}' is not a top-level method, thus need a receiver.") + end + if not recv_is_self and mproperty.is_toplevel then + error(node, "Error: cannot call '{name}', a top-level method, with a receiver.") + end + if mproperty.visibility == protected_visibility and not recv_is_self and self.mmodule.visibility_for(mproperty.intro_mclassdef.mmodule) < intrude_visibility and not modelbuilder.toolcontext.opt_ignore_visibility.value then self.modelbuilder.error(node, "Error: Method '{name}' is protected and can only acceded by self.") return null @@ -265,7 +284,7 @@ private class TypeVisitor var erasure_cast = false var rettype = mpropdef.msignature.return_mtype if not recv_is_self and rettype != null then - if rettype isa MNullableType then rettype = rettype.mtype + rettype = rettype.as_notnullable if rettype isa MParameterType then var erased_rettype = msignature.return_mtype assert erased_rettype != null @@ -833,7 +852,7 @@ redef class AForExpr if objcla == null then return # check iterator method - var itdef = v.get_method(self, mtype, "iterator", true) + var itdef = v.get_method(self, mtype, "iterator", n_expr isa ASelfExpr) if itdef == null then v.error(self, "Type Error: 'for' expects a type providing 'iterator' method, got '{mtype}'.") return @@ -886,7 +905,7 @@ redef class AForExpr # anchor formal and virtual types if mtype.need_anchor then mtype = v.anchor_to(mtype) - if mtype isa MNullableType then mtype = mtype.mtype + mtype = mtype.as_notnullable self.coltype = mtype.as(MClassType) # get methods is_ok, next, item @@ -989,9 +1008,7 @@ redef class AOrElseExpr return # Skip error end - if t1 isa MNullableType then - t1 = t1.mtype - end + t1 = t1.as_notnullable var t = v.merge_types(self, [t1, t2]) if t == null then @@ -1062,7 +1079,7 @@ redef class ASuperstringExpr if mclass == null then return # Forward error self.mtype = mclass.mclass_type for nexpr in self.n_exprs do - var t = v.visit_expr(nexpr) + v.visit_expr_subtype(nexpr, v.mmodule.object_type) end end end @@ -1175,6 +1192,8 @@ redef class AAsNotnullExpr redef fun accept_typing(v) do var mtype = v.visit_expr(self.n_expr) + if mtype == null then return # Forward error + if mtype isa MNullType then v.error(self, "Type error: as(not null) on null") return @@ -1183,8 +1202,18 @@ redef class AAsNotnullExpr self.mtype = mtype.mtype return end - # TODO: warn on useless as not null self.mtype = mtype + + if mtype isa MClassType then + v.modelbuilder.warning(self, "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}`.") + return + end end end @@ -1199,6 +1228,9 @@ redef class ASelfExpr redef var its_variable: nullable Variable redef fun accept_typing(v) do + if v.is_toplevel_context and not self isa AImplicitSelfExpr then + v.error(self, "Error: self cannot be used in top-level method.") + end var variable = v.selfvariable self.its_variable = variable self.mtype = v.get_variable(self, variable)