ni: fixed crash on empty class comment
[nit.git] / src / syntax / scope.nit
index 2fa457a..85140d0 100644 (file)
@@ -37,11 +37,6 @@ class ScopeContext
        # Used for debuging
        var _variables: Array[Variable] = new Array[Variable]
 
-       # Known labels
-       # (all labels, even out of scopes ones)
-       # Used to find duplicates
-       var _labels: Array[ALabel] = new Array[ALabel]
-
        # Return the variable associated with a name
        fun [](n: Symbol): nullable Variable
        do
@@ -81,14 +76,17 @@ class ScopeContext
                _stack.push(block)
                if n_label != null then
                        var lab = n_label.n_id.to_symbol
-                       for nl in _labels do
-                               if n_label != nl and lab == nl.n_id.to_symbol then
-                                       visitor.error(n_label, "Syntax error: label {lab} already defined at {nl.location.relative_to(n_label.location)}.")
+                       var i = _stack.length - 1
+                       while i >= 0 do
+                               var b = _stack[i]
+                               if b isa EscapableBlock and b.lab == lab then
+                                       visitor.error(n_label, "Syntax error: label {lab} already defined at {b.lab_location.relative_to(n_label.location)}.")
                                        return
                                end
+                               i -= 1
                        end
-                       _labels.add(n_label)
                        block._lab = lab
+                       block._lab_location = n_label.location
                end
        end
 
@@ -174,11 +172,14 @@ end
 # labeled 'do' uses the BreakOnlyEscapableBlock subclass
 # closures uses the EscapableClosure subclass
 class EscapableBlock
-special ScopeBlock
+       super ScopeBlock
        # The label of the block (if any)
        # Set by the push in EscapableContext
        readable var _lab: nullable Symbol
 
+       # The location of the label (if any)
+       readable var _lab_location: nullable Location
+
        # Is self a break closure ?
        fun is_break_block: Bool do return false
 
@@ -201,7 +202,7 @@ end
 
 # specific EscapableBlock where only labelled break can be used
 class BreakOnlyEscapableBlock
-special EscapableBlock
+       super EscapableBlock
        redef fun is_break_block: Bool do return true
 
        init(node: ANode) do super
@@ -209,7 +210,7 @@ end
 
 # specific EscapableBlock for closures
 class EscapableClosure
-special EscapableBlock
+       super EscapableBlock
        # The associated closure
        readable var _closure: MMClosure
 
@@ -229,8 +230,8 @@ end
 
 ###############################################################################
 
-class AEscapeExpr
-special ALabelable
+abstract class AEscapeExpr
+       super ALabelable
        # The associated escapable block
        readable var _escapable: nullable EscapableBlock
 
@@ -256,12 +257,12 @@ special ALabelable
 end
 
 redef class AContinueExpr
-special AEscapeExpr
+       super AEscapeExpr
        redef fun kwname do return "continue"
 end
 
 redef class ABreakExpr
-special AEscapeExpr
+       super AEscapeExpr
        redef fun kwname do return "break"
 end