X-Git-Url: http://nitlanguage.org diff --git a/src/syntax/control_flow.nit b/src/syntax/control_flow.nit index 50fcb57..f044cd1 100644 --- a/src/syntax/control_flow.nit +++ b/src/syntax/control_flow.nit @@ -29,6 +29,17 @@ redef class MMSrcModule end end +redef class Variable + # Is the variable must be set before being used ? + meth must_be_set: Bool do return false +end + +redef class VarVariable + redef meth must_be_set do return true +end + + + # Control flow visitor # * Check reachability in methods # * Associate breaks and continues @@ -41,14 +52,14 @@ special AbsSyntaxVisitor end # Number of nested once - readable writable attr _once_count: Int + readable writable attr _once_count: Int = 0 # Current knowledge about variables types readable writable attr _control_flow_ctx: ControlFlowContext meth check_is_set(n: PNode, v: Variable) do - if not control_flow_ctx.is_set(v) then + if v.must_be_set and not control_flow_ctx.is_set(v) then error(n, "Error: variable '{v}' is possibly unset.") var cfc = control_flow_ctx while cfc != null do @@ -70,15 +81,12 @@ private class ControlFlowContext # Previous control flow context if any readable attr _prev: ControlFlowContext - # Is a return met? - readable writable attr _has_return: Bool - # Is a control flow break met? (return, break, continue) - readable writable attr _unreash: Bool + readable writable attr _unreash: Bool = false # Is a control flow already broken? # Used to avoid repeating the same error message - readable writable attr _already_unreash: Bool + readable writable attr _already_unreash: Bool = false # Current controlable block (for or while) readable writable attr _base_block: AControlableBlock @@ -94,17 +102,16 @@ private class ControlFlowContext meth sub: ControlFlowContext do - return new ControlFlowContext.with(self) + return new ControlFlowContext.with_prev(self) end init do end - init with(p: ControlFlowContext) + init with_prev(p: ControlFlowContext) do _prev = p - _has_return = p.has_return _unreash = p.unreash _already_unreash = p.already_unreash _base_block = p.base_block @@ -132,20 +139,12 @@ redef class AConcreteMethPropdef redef meth accept_control_flow(v) do super - if v.control_flow_ctx.has_return == false and method.signature.return_type != null then - v.error(self, "Control error: Reached end of function.") + if v.control_flow_ctx.unreash == false and method.signature.return_type != null then + v.error(self, "Control error: Reached end of function (a 'return' with a value was expected).") end end end -redef class PParam - redef meth accept_control_flow(v) - do - super - v.mark_is_set(variable) - end -end - redef class AVardeclExpr redef meth accept_control_flow(v) do @@ -171,7 +170,6 @@ redef class AReturnExpr redef meth accept_control_flow(v) do super - v.control_flow_ctx.has_return = true v.control_flow_ctx.unreash = true end end @@ -214,7 +212,6 @@ redef class AAbortExpr redef meth accept_control_flow(v) do super - v.control_flow_ctx.has_return = true v.control_flow_ctx.unreash = true end end @@ -241,7 +238,6 @@ redef class AIfExpr v.visit(n_else) # Merge then and else in the old control_flow - old_control_flow_ctx.has_return = v.control_flow_ctx.has_return and then_control_flow_ctx.has_return old_control_flow_ctx.unreash = v.control_flow_ctx.unreash and then_control_flow_ctx.unreash if v.control_flow_ctx.unreash then v.control_flow_ctx = then_control_flow_ctx @@ -282,15 +278,6 @@ redef class AForExpr special AControlableBlock end -redef class AForVardeclExpr - redef meth accept_control_flow(v) - do - super - v.mark_is_set(variable) - end -end - - redef class AVarExpr redef meth accept_control_flow(v) do