# A local variable (including parameters, automatic variables and self)
class Variable
# The name of the variable (as used in the program)
- var name: String
+ var name: String is writable
# Alias of `name`
redef fun to_s do return self.name
# The declaration of the variable, if any
- var location: nullable Location = null
+ var location: nullable Location = null is writable
# Is the local variable not read and need a warning?
var warn_unread = false is writable
end
end
+redef class AAssertExpr
+ redef fun accept_scope_visitor(v)
+ do
+ v.enter_visit(n_expr)
+ v.enter_visit_block(n_else, null)
+ end
+end
+
redef class AVarFormExpr
# The associated variable
- var variable: nullable Variable
+ var variable: nullable Variable is writable
end
redef class ACallFormExpr
#debug("recv: {recvtype} (aka {unsafe_type})")
if recvtype isa MNullType then
- # `null` only accepts some methods of object.
- if name == "==" or name == "!=" or name == "is_same_instance" then
- var objclass = get_mclass(node, "Object")
- if objclass == null then return null # Forward error
- unsafe_type = objclass.mclass_type
- else
- self.error(node, "Error: method `{name}` called on `null`.")
- return null
- end
+ var objclass = get_mclass(node, "Object")
+ if objclass == null then return null # Forward error
+ unsafe_type = objclass.mclass_type
end
var mproperty = self.try_get_mproperty_by_name2(node, unsafe_type, name)
assert mproperty isa MMethod
+ # `null` only accepts some methods of object.
+ if recvtype isa MNullType and not mproperty.is_null_safe then
+ self.error(node, "Error: method `{name}` called on `null`.")
+ return null
+ else if unsafe_type isa MNullableType and not mproperty.is_null_safe then
+ modelbuilder.advice(node, "call-on-nullable", "Warning: method call on a nullable receiver `{recvtype}`.")
+ end
+
if is_toplevel_context and recv_is_self and not mproperty.is_toplevel then
error(node, "Error: `{name}` is not a top-level method, thus need a receiver.")
end
redef class Variable
# The declared type of the variable
- var declared_type: nullable MType
+ var declared_type: nullable MType is writable
# Was the variable type-adapted?
# This is used to speedup type retrieval while it remains `false`
v.set_variable(self, variable, rettype)
- self.is_typed = true
+ self.is_typed = rettype != null
end
end
else
v.visit_expr(nexpr)
v.error(nexpr, "Error: `return` with value in a procedure.")
+ return
end
else if ret_type != null then
v.error(self, "Error: `return` without value in a function.")
+ return
end
self.is_typed = true
end
end
end
+redef class AByteExpr
+ redef fun accept_typing(v)
+ do
+ var mclass = v.get_mclass(self, "Byte")
+ if mclass == null then return # Forward error
+ self.mtype = mclass.mclass_type
+ end
+end
+
redef class AFloatExpr
redef fun accept_typing(v)
do
var mtype = self.attr_type
v.visit_expr_subtype(self.n_value, mtype)
- self.is_typed = true
+ self.is_typed = mtype != null
end
end
var mtype = self.attr_type
if mtype == null then return # Skip error
- self.resolve_reassignment(v, mtype, mtype)
+ var rettype = self.resolve_reassignment(v, mtype, mtype)
- self.is_typed = true
+ self.is_typed = rettype != null
end
end