Class: Opal::Nodes::ScopeNode
Direct Known Subclasses
BeginNode, ModuleNode, NodeWithArgs, SingletonClassNode, TopNode
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. 
- 
  
    
      #has_break  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    Returns the value of attribute has_break. 
- 
  
    
      #identity  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute identity. 
- 
  
    
      #ivars  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute ivars. 
- 
  
    
      #locals  ⇒ Object 
    
    
  
  
  
  
    
      readonly
    
    
  
  
  
  
  
  
    Returns the value of attribute locals. 
- 
  
    
      #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. 
- 
  
    
      #rescue_else_sexp  ⇒ Object 
    
    
  
  
  
  
    
    
  
  
  
  
  
  
    Returns the value of attribute rescue_else_sexp. 
- 
  
    
      #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(tmp) ⇒ 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
- #has_local?(local) ⇒ Boolean
- #has_rescue_else? ⇒ Boolean
- #has_temp?(tmp) ⇒ Boolean
- #identify!(name = nil) ⇒ Object
- #in_ensure ⇒ Object
- #in_ensure? ⇒ Boolean
- #in_scope ⇒ 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
- #push_while ⇒ Object
- #queue_temp(name) ⇒ Object
- #sclass? ⇒ Boolean
- #super_chain ⇒ Object
- 
  
    
      #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, #class_variable_owner, #class_variable_owner_nesting_level, #comments, #compile, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #helper, #process, #push, #recv, #recv?, #s, #scope, #stmt, #stmt?, truthy_optimize?, #unshift, #while_loop, #with_temp, #wrap
Methods included from Helpers
#conditional_send, #current_indent, #empty_line, #indent, #js_falsy, #js_truthy, #js_truthy_optimize, #line, #mid_to_jsid, #property, #valid_name?
Constructor Details
#initialize ⇒ ScopeNode
Returns a new instance of ScopeNode
| 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | # File 'opal/lib/opal/nodes/scope.rb', line 38 def initialize(*) super @locals = [] @temps = [] @args = [] @ivars = [] @gvars = [] @parent = nil @queue = [] @unique = 'a' @while_stack = [] @identity = nil @defs = nil @methods = [] @uses_block = false @in_ensure = 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
| 15 16 17 | # File 'opal/lib/opal/nodes/scope.rb', line 15 def block_name @block_name end | 
#catch_return ⇒ Object
Returns the value of attribute catch_return
| 34 35 36 | # File 'opal/lib/opal/nodes/scope.rb', line 34 def catch_return @catch_return end | 
#defs ⇒ Object
true if singleton def, false otherwise
| 25 26 27 | # File 'opal/lib/opal/nodes/scope.rb', line 25 def defs @defs end | 
#gvars ⇒ Object (readonly)
Returns the value of attribute gvars
| 20 21 22 | # File 'opal/lib/opal/nodes/scope.rb', line 20 def gvars @gvars end | 
#has_break ⇒ Object
Returns the value of attribute has_break
| 34 35 36 | # File 'opal/lib/opal/nodes/scope.rb', line 34 def has_break @has_break end | 
#identity ⇒ Object (readonly)
Returns the value of attribute identity
| 239 240 241 | # File 'opal/lib/opal/nodes/scope.rb', line 239 def identity @identity end | 
#ivars ⇒ Object (readonly)
Returns the value of attribute ivars
| 19 20 21 | # File 'opal/lib/opal/nodes/scope.rb', line 19 def ivars @ivars end | 
#locals ⇒ Object (readonly)
Returns the value of attribute locals
| 18 19 20 | # File 'opal/lib/opal/nodes/scope.rb', line 18 def locals @locals end | 
#methods ⇒ Object (readonly)
used by modules to know what methods to donate to includees
| 28 29 30 | # File 'opal/lib/opal/nodes/scope.rb', line 28 def methods @methods end | 
#mid ⇒ Object
Returns the value of attribute mid
| 22 23 24 | # File 'opal/lib/opal/nodes/scope.rb', line 22 def mid @mid end | 
#name ⇒ Object
The class or module name if this scope is a class scope
| 12 13 14 | # File 'opal/lib/opal/nodes/scope.rb', line 12 def name @name end | 
#parent ⇒ Object
Every scope can have a parent scope
| 9 10 11 | # File 'opal/lib/opal/nodes/scope.rb', line 9 def parent @parent end | 
#rescue_else_sexp ⇒ Object
Returns the value of attribute rescue_else_sexp
| 36 37 38 | # File 'opal/lib/opal/nodes/scope.rb', line 36 def rescue_else_sexp @rescue_else_sexp end | 
#scope_name ⇒ Object (readonly)
Returns the value of attribute scope_name
| 17 18 19 | # File 'opal/lib/opal/nodes/scope.rb', line 17 def scope_name @scope_name end | 
#uses_super ⇒ Object
uses parents super method
| 31 32 33 | # File 'opal/lib/opal/nodes/scope.rb', line 31 def uses_super @uses_super end | 
#uses_zuper ⇒ Object
Returns the value of attribute uses_zuper
| 32 33 34 | # File 'opal/lib/opal/nodes/scope.rb', line 32 def uses_zuper @uses_zuper end | 
Instance Method Details
#add_arg(arg) ⇒ Object
| 156 157 158 159 | # File 'opal/lib/opal/nodes/scope.rb', line 156 def add_arg(arg) @args << arg unless @args.include? arg arg end | 
#add_proto_ivar(ivar) ⇒ Object
| 152 153 154 | # File 'opal/lib/opal/nodes/scope.rb', line 152 def add_proto_ivar(ivar) @proto_ivars << ivar unless @proto_ivars.include? ivar end | 
#add_scope_gvar(gvar) ⇒ Object
| 148 149 150 | # File 'opal/lib/opal/nodes/scope.rb', line 148 def add_scope_gvar(gvar) @gvars << gvar unless @gvars.include? gvar end | 
#add_scope_ivar(ivar) ⇒ Object
| 140 141 142 143 144 145 146 | # File 'opal/lib/opal/nodes/scope.rb', line 140 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
| 161 162 163 164 165 | # File 'opal/lib/opal/nodes/scope.rb', line 161 def add_scope_local(local) return if has_local? local @locals << local end | 
#add_scope_temp(tmp) ⇒ Object
| 173 174 175 176 177 | # File 'opal/lib/opal/nodes/scope.rb', line 173 def add_scope_temp(tmp) return if has_temp?(tmp) @temps.push(tmp) end | 
#class? ⇒ Boolean
Returns true if this is strictly a class scope
| 77 78 79 | # File 'opal/lib/opal/nodes/scope.rb', line 77 def class? @type == :class end | 
#class_scope? ⇒ Boolean
Returns true if this scope is a class/module body scope
| 72 73 74 | # File 'opal/lib/opal/nodes/scope.rb', line 72 def class_scope? @type == :class || @type == :module end | 
#def? ⇒ Boolean
| 100 101 102 | # File 'opal/lib/opal/nodes/scope.rb', line 100 def def? @type == :def || @type == :defs 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
| 107 108 109 | # File 'opal/lib/opal/nodes/scope.rb', line 107 def def_in_class? !@defs && @type == :def && @parent && @parent.class? end | 
#find_parent_def ⇒ Object
| 241 242 243 244 245 246 247 248 249 250 | # File 'opal/lib/opal/nodes/scope.rb', line 241 def find_parent_def scope = self while scope = scope.parent if scope.def? return scope end end nil end | 
#has_local?(local) ⇒ Boolean
| 167 168 169 170 171 | # File 'opal/lib/opal/nodes/scope.rb', line 167 def has_local?(local) return true if @locals.include?(local) || @args.include?(local) || @temps.include?(local) return @parent.has_local?(local) if @parent && @type == :iter false end | 
#has_rescue_else? ⇒ Boolean
| 276 277 278 | # File 'opal/lib/opal/nodes/scope.rb', line 276 def has_rescue_else? !rescue_else_sexp.nil? end | 
#has_temp?(tmp) ⇒ Boolean
| 179 180 181 | # File 'opal/lib/opal/nodes/scope.rb', line 179 def has_temp?(tmp) @temps.include? tmp end | 
#identify!(name = nil) ⇒ Object
| 228 229 230 231 232 233 234 235 236 237 | # File 'opal/lib/opal/nodes/scope.rb', line 228 def identify!(name = nil) return @identity if @identity # Parent scope is the defining module/class name ||= [(parent && (parent.name || parent.scope_name)), mid].compact.join('_') @identity = @compiler.unique_temp(name) @parent.add_scope_temp @identity if @parent @identity end | 
#in_ensure ⇒ Object
| 280 281 282 283 284 285 286 287 288 | # File 'opal/lib/opal/nodes/scope.rb', line 280 def in_ensure return unless block_given? @in_ensure = true result = yield @in_ensure = false result end | 
#in_ensure? ⇒ Boolean
| 290 291 292 | # File 'opal/lib/opal/nodes/scope.rb', line 290 def in_ensure? @in_ensure end | 
#in_scope ⇒ Object
| 62 63 64 65 66 67 68 69 | # File 'opal/lib/opal/nodes/scope.rb', line 62 def in_scope indent do @parent = compiler.scope compiler.scope = self yield self compiler.scope = @parent end end | 
#in_while? ⇒ Boolean
| 215 216 217 | # File 'opal/lib/opal/nodes/scope.rb', line 215 def in_while? !@while_stack.empty? end | 
#iter? ⇒ Boolean
True if a block/iter scope
| 96 97 98 | # File 'opal/lib/opal/nodes/scope.rb', line 96 def iter? @type == :iter end | 
#module? ⇒ Boolean
True if this is a module scope
| 82 83 84 | # File 'opal/lib/opal/nodes/scope.rb', line 82 def module? @type == :module end | 
#new_temp ⇒ Object
| 183 184 185 186 187 188 189 | # File 'opal/lib/opal/nodes/scope.rb', line 183 def new_temp return @queue.pop unless @queue.empty? tmp = next_temp @temps << tmp tmp end | 
#next_temp ⇒ Object
| 191 192 193 194 195 196 197 198 199 | # File 'opal/lib/opal/nodes/scope.rb', line 191 def next_temp tmp = nil loop do tmp = "$#{@unique}" @unique = @unique.succ break unless has_local?(tmp) end tmp end | 
#pop_while ⇒ Object
| 211 212 213 | # File 'opal/lib/opal/nodes/scope.rb', line 211 def pop_while @while_stack.pop end | 
#push_while ⇒ Object
| 205 206 207 208 209 | # File 'opal/lib/opal/nodes/scope.rb', line 205 def push_while info = {} @while_stack.push info info end | 
#queue_temp(name) ⇒ Object
| 201 202 203 | # File 'opal/lib/opal/nodes/scope.rb', line 201 def queue_temp(name) @queue << name end | 
#sclass? ⇒ Boolean
| 86 87 88 | # File 'opal/lib/opal/nodes/scope.rb', line 86 def sclass? @type == :sclass end | 
#super_chain ⇒ Object
| 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 | # File 'opal/lib/opal/nodes/scope.rb', line 252 def 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 %i[def defs].include?(scope.type) defn = scope.identify! mid = "'#{scope.mid}'" break else break end end [chain, defn, mid] end | 
#to_vars ⇒ Object
Vars to use inside each scope
| 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 | # File 'opal/lib/opal/nodes/scope.rb', line 113 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? && !@proto_ivars.empty? pvars = @proto_ivars.map { |i| "self.$$prototype#{i}" }.join(' = ') result = "#{str}\n#{indent}#{pvars} = nil;" else result = str end fragment(result) end | 
#top? ⇒ Boolean
Returns true if this is a top scope (main file body)
| 91 92 93 | # File 'opal/lib/opal/nodes/scope.rb', line 91 def top? @type == :top end | 
#uses_block! ⇒ Object
| 219 220 221 222 223 224 225 226 | # File 'opal/lib/opal/nodes/scope.rb', line 219 def uses_block! if @type == :iter && @parent @parent.uses_block! else @uses_block = true identify! end end | 
#uses_block? ⇒ Boolean
| 272 273 274 | # File 'opal/lib/opal/nodes/scope.rb', line 272 def uses_block? @uses_block end |