Class: Opal::Nodes::ScopeNode
Direct Known Subclasses
Constant Summary
Constants included from Helpers
Helpers::BASIC_IDENTIFIER_RULES, Helpers::ES3_RESERVED_WORD_EXCLUSIVE, Helpers::ES51_RESERVED_WORD, Helpers::IMMUTABLE_PROPS
Instance Attribute Summary collapse
- 
  
    
      #block_name  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
The given block name for a def scope.
 - 
  
    
      #catch_return  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
Returns the value of attribute catch_return.
 - 
  
    
      #defs  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
true if singleton def, false otherwise.
 - 
  
    
      #gvars  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    
Returns the value of attribute gvars.
 - 
  
    
      #ivars  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    
Returns the value of attribute ivars.
 - 
  
    
      #methods  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    
used by modules to know what methods to donate to includees.
 - 
  
    
      #mid  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
Returns the value of attribute mid.
 - 
  
    
      #name  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
The class or module name if this scope is a class scope.
 - 
  
    
      #parent  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
Every scope can have a parent scope.
 - 
  
    
      #scope_name  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    
Returns the value of attribute scope_name.
 - 
  
    
      #uses_super  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
uses parents super method.
 - 
  
    
      #uses_zuper  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    
Returns the value of attribute uses_zuper.
 
Attributes inherited from Base
Instance Method Summary collapse
- #add_arg(arg) ⇒ Object
 - #add_proto_ivar(ivar) ⇒ Object
 - #add_scope_gvar(gvar) ⇒ Object
 - #add_scope_ivar(ivar) ⇒ Object
 - #add_scope_local(local) ⇒ Object
 - #add_scope_temp(*tmps) ⇒ Object
 - 
  
    
      #class?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
Returns true if this is strictly a class scope.
 - 
  
    
      #class_scope?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
Returns true if this scope is a class/module body scope.
 - #def? ⇒ Boolean
 - 
  
    
      #def_in_class?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
Is this a normal def method directly inside a class? This is used for optimizing ivars as we can set them to nil in the class body.
 - #find_parent_def ⇒ Object
 - #get_super_chain ⇒ Object
 - #has_local?(local) ⇒ Boolean
 - #has_temp?(tmp) ⇒ Boolean
 - #identify! ⇒ Object
 - #identity ⇒ Object
 - #in_scope(&block) ⇒ Object
 - #in_while? ⇒ Boolean
 - 
  
    
      #initialize  ⇒ ScopeNode 
    
    
  
  
  
    constructor
  
  
  
  
  
  
  
    
A new instance of ScopeNode.
 - 
  
    
      #iter?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
True if a block/iter scope.
 - 
  
    
      #module?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
True if this is a module scope.
 - #new_temp ⇒ Object
 - #next_temp ⇒ Object
 - #pop_while ⇒ Object
 - 
  
    
      #proto  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Inside a class or module scope, the javascript variable name returned by this function points to the classes' prototype.
 - #push_while ⇒ Object
 - #queue_temp(name) ⇒ Object
 - #sclass? ⇒ Boolean
 - 
  
    
      #to_vars  ⇒ Object 
    
    
  
  
  
  
  
  
  
  
  
    
Vars to use inside each scope.
 - 
  
    
      #top?  ⇒ Boolean 
    
    
  
  
  
  
  
  
  
  
  
    
Returns true if this is a top scope (main file body).
 - #uses_block! ⇒ Object
 - #uses_block? ⇒ Boolean
 
Methods inherited from Base
#add_gvar, #add_ivar, #add_local, #add_temp, #children, children, #compile, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #helper, #process, #push, #recv, #recv?, #s, #scope, #stmt, #stmt?, #unshift, #while_loop, #with_temp, #wrap
Methods included from Helpers
#current_indent, #empty_line, #indent, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #lvar_to_js, #mid_to_jsid, #property, #valid_name?, #variable
Constructor Details
#initialize ⇒ ScopeNode
Returns a new instance of ScopeNode
      34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 34 def initialize(*) super @locals = [] @temps = [] @args = [] @ivars = [] @gvars = [] @parent = nil @queue = [] @unique = 'a' @while_stack = [] @identity = nil @defs = nil @methods = [] @uses_block = false # used by classes to store all ivars used in direct def methods @proto_ivars = [] end  | 
  
Instance Attribute Details
#block_name ⇒ Object
The given block name for a def scope
      14 15 16  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 14 def block_name @block_name end  | 
  
#catch_return ⇒ Object
Returns the value of attribute catch_return
      32 33 34  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 32 def catch_return @catch_return end  | 
  
#defs ⇒ Object
true if singleton def, false otherwise
      23 24 25  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 23 def defs @defs end  | 
  
#gvars ⇒ Object (readonly)
Returns the value of attribute gvars
      18 19 20  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 18 def gvars @gvars end  | 
  
#ivars ⇒ Object (readonly)
Returns the value of attribute ivars
      17 18 19  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 17 def ivars @ivars end  | 
  
#methods ⇒ Object (readonly)
used by modules to know what methods to donate to includees
      26 27 28  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 26 def methods @methods end  | 
  
#mid ⇒ Object
Returns the value of attribute mid
      20 21 22  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 20 def mid @mid end  | 
  
#name ⇒ Object
The class or module name if this scope is a class scope
      11 12 13  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 11 def name @name end  | 
  
#parent ⇒ Object
Every scope can have a parent scope
      8 9 10  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 8 def parent @parent end  | 
  
#scope_name ⇒ Object (readonly)
Returns the value of attribute scope_name
      16 17 18  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 16 def scope_name @scope_name end  | 
  
#uses_super ⇒ Object
uses parents super method
      29 30 31  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 29 def uses_super @uses_super end  | 
  
#uses_zuper ⇒ Object
Returns the value of attribute uses_zuper
      30 31 32  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 30 def uses_zuper @uses_zuper end  | 
  
Instance Method Details
#add_arg(arg) ⇒ Object
      159 160 161 162  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 159 def add_arg(arg) @args << arg unless @args.include? arg arg end  | 
  
#add_proto_ivar(ivar) ⇒ Object
      155 156 157  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 155 def add_proto_ivar(ivar) @proto_ivars << ivar unless @proto_ivars.include? ivar end  | 
  
#add_scope_gvar(gvar) ⇒ Object
      151 152 153  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 151 def add_scope_gvar(gvar) @gvars << gvar unless @gvars.include? gvar end  | 
  
#add_scope_ivar(ivar) ⇒ Object
      143 144 145 146 147 148 149  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 143 def add_scope_ivar(ivar) if def_in_class? @parent.add_proto_ivar ivar else @ivars << ivar unless @ivars.include? ivar end end  | 
  
#add_scope_local(local) ⇒ Object
      164 165 166 167 168  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 164 def add_scope_local(local) return if has_local? local @locals << local end  | 
  
#add_scope_temp(*tmps) ⇒ Object
      177 178 179  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 177 def add_scope_temp(*tmps) @temps.push(*tmps) end  | 
  
#class? ⇒ Boolean
Returns true if this is strictly a class scope
      72 73 74  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 72 def class? @type == :class end  | 
  
#class_scope? ⇒ Boolean
Returns true if this scope is a class/module body scope
      67 68 69  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 67 def class_scope? @type == :class or @type == :module end  | 
  
#def? ⇒ Boolean
      95 96 97  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 95 def def? @type == :def end  | 
  
#def_in_class? ⇒ Boolean
Is this a normal def method directly inside a class? This is used for optimizing ivars as we can set them to nil in the class body
      102 103 104  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 102 def def_in_class? !@defs && @type == :def && @parent && @parent.class? end  | 
  
#find_parent_def ⇒ Object
      239 240 241 242 243 244 245 246 247 248  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 239 def find_parent_def scope = self while scope = scope.parent if scope.def? return scope end end nil end  | 
  
#get_super_chain ⇒ Object
      250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 250 def get_super_chain chain, scope, defn, mid = [], self, 'null', 'null' while scope if scope.type == :iter chain << scope.identify! scope = scope.parent if scope.parent elsif scope.type == :def defn = scope.identify! mid = "'#{scope.mid}'" break else break end end [chain, defn, mid] end  | 
  
#has_local?(local) ⇒ Boolean
      170 171 172 173 174 175  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 170 def has_local?(local) return true if @locals.include? local or @args.include? local return @parent.has_local?(local) if @parent and @type == :iter false end  | 
  
#has_temp?(tmp) ⇒ Boolean
      181 182 183  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 181 def has_temp?(tmp) @temps.include? tmp end  | 
  
#identify! ⇒ Object
      226 227 228 229 230 231 232 233  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 226 def identify! return @identity if @identity @identity = @compiler.unique_temp @parent.add_scope_temp @identity if @parent @identity end  | 
  
#identity ⇒ Object
      235 236 237  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 235 def identity @identity end  | 
  
#in_scope(&block) ⇒ Object
      57 58 59 60 61 62 63 64  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 57 def in_scope(&block) indent do @parent = compiler.scope compiler.scope = self block.call self compiler.scope = @parent end end  | 
  
#in_while? ⇒ Boolean
      213 214 215  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 213 def in_while? !@while_stack.empty? end  | 
  
#iter? ⇒ Boolean
True if a block/iter scope
      91 92 93  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 91 def iter? @type == :iter end  | 
  
#module? ⇒ Boolean
True if this is a module scope
      77 78 79  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 77 def module? @type == :module end  | 
  
#new_temp ⇒ Object
      185 186 187 188 189 190 191  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 185 def new_temp return @queue.pop unless @queue.empty? tmp = next_temp @temps << tmp tmp end  | 
  
#next_temp ⇒ Object
      193 194 195 196 197  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 193 def next_temp tmp = "$#{@unique}" @unique = @unique.succ tmp end  | 
  
#pop_while ⇒ Object
      209 210 211  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 209 def pop_while @while_stack.pop end  | 
  
#proto ⇒ Object
Inside a class or module scope, the javascript variable name returned by this function points to the classes' prototype. This is the target to where methods are actually added inside a class body.
      109 110 111  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 109 def proto "def" end  | 
  
#push_while ⇒ Object
      203 204 205 206 207  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 203 def push_while info = {} @while_stack.push info info end  | 
  
#queue_temp(name) ⇒ Object
      199 200 201  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 199 def queue_temp(name) @queue << name end  | 
  
#sclass? ⇒ Boolean
      81 82 83  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 81 def sclass? @type == :sclass end  | 
  
#to_vars ⇒ Object
Vars to use inside each scope
      115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 115 def to_vars vars = @temps.dup vars.push(*@locals.map { |l| "#{l} = nil" }) iv = ivars.map do |ivar| "if (self#{ivar} == null) self#{ivar} = nil;\n" end gv = gvars.map do |gvar| "if ($gvars#{gvar} == null) $gvars#{gvar} = nil;\n" end indent = @compiler.parser_indent str = vars.empty? ? '' : "var #{vars.join ', '};\n" str += "#{indent}#{iv.join indent}" unless ivars.empty? str += "#{indent}#{gv.join indent}" unless gvars.empty? if class? and !@proto_ivars.empty? #raise "FIXME to_vars" pvars = @proto_ivars.map { |i| "#{proto}#{i}"}.join(' = ') result = "%s\n%s%s = nil;" % [str, indent, pvars] else result = str end fragment(result) end  | 
  
#top? ⇒ Boolean
Returns true if this is a top scope (main file body)
      86 87 88  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 86 def top? @type == :top end  | 
  
#uses_block! ⇒ Object
      217 218 219 220 221 222 223 224  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 217 def uses_block! if @type == :iter && @parent @parent.uses_block! else @uses_block = true identify! end end  | 
  
#uses_block? ⇒ Boolean
      271 272 273  | 
    
      # File 'opal/lib/opal/nodes/scope.rb', line 271 def uses_block? @uses_block end  |