From 8c96cf694bea41704433f991a7604ae5160ad641 Mon Sep 17 00:00:00 2001 From: Jean Privat Date: Tue, 10 Jun 2014 22:00:17 -0400 Subject: [PATCH] typing: check correct usage of top-level methods First, the body of top-level methods has two constraints: * no explicit self * implicit self can only call other top-level methods Second, only self can invoke top-level methods. Eg. no `6.print("hello")` Signed-off-by: Jean Privat --- src/typing.nit | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/src/typing.nit b/src/typing.nit index 3a8194a..5db0ada 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" and name != "args" 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 @@ -1199,6 +1218,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) -- 1.7.9.5