Class: JSObfu::Hoister
- Inherits:
-
RKelly::Visitors::Visitor
- Object
- RKelly::Visitors::Visitor
- JSObfu::Hoister
- Defined in:
- lib/jsobfu/hoister.rb
Overview
Walks a Javascript AST and finds the immediate members of the root scope, which is useful for "hoisting" var and function declaration to the top of the function.
Although the auto-hoisting is no longer used, this class is used to "discover" a function's variables and scope.
Instance Attribute Summary (collapse)
-
- (Array<String>) functions
readonly
The function names in the first level of this closure.
-
- (Hash) scope
readonly
The scope maintained while walking the ast.
Instance Method Summary (collapse)
-
- (Hoister) initialize(opts = {})
constructor
A new instance of Hoister.
-
- (String) scope_declaration(opts = {})
Javascript that declares the discovered variables.
- - (Object) visit_FunctionDeclNode(o)
- - (Object) visit_SourceElementsNode(o)
- - (Object) visit_VarDeclNode(o)
Constructor Details
- (Hoister) initialize(opts = {})
Returns a new instance of Hoister
20 21 22 23 24 25 26 27 |
# File 'lib/jsobfu/hoister.rb', line 20 def initialize(opts={}) @parent_scope = opts.fetch(:parent_scope, nil) @max_depth = 1 @depth = 0 @scope = {} @functions = [] super() end |
Instance Attribute Details
- (Array<String>) functions (readonly)
Returns the function names in the first level of this closure
15 16 17 |
# File 'lib/jsobfu/hoister.rb', line 15 def functions @functions end |
- (Hash) scope (readonly)
Returns the scope maintained while walking the ast
12 13 14 |
# File 'lib/jsobfu/hoister.rb', line 12 def scope @scope end |
Instance Method Details
- (String) scope_declaration(opts = {})
Returns Javascript that declares the discovered variables
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/jsobfu/hoister.rb', line 71 def scope_declaration(opts={}) keys = scope.keys.dup if opts.fetch(:shuffle, true) keys = keys.shuffle end keys.delete_if { |k| functions.include? k } if @parent_scope keys.delete_if { |k| @parent_scope.has_key? k } keys.map! { |k| @parent_scope.renames[k.to_s] || k } end if keys.empty? then '' else "var #{keys.join(",")};" end end |
- (Object) visit_FunctionDeclNode(o)
40 41 42 43 |
# File 'lib/jsobfu/hoister.rb', line 40 def visit_FunctionDeclNode(o) functions << o.value scope[o.value] = o end |
- (Object) visit_SourceElementsNode(o)
29 30 31 32 33 34 |
# File 'lib/jsobfu/hoister.rb', line 29 def visit_SourceElementsNode(o) return if @max_depth and @depth >= @max_depth @depth += 1 o.value.each { |x| x.accept(self) } @depth -= 1 end |
- (Object) visit_VarDeclNode(o)
36 37 38 |
# File 'lib/jsobfu/hoister.rb', line 36 def visit_VarDeclNode(o) scope[o.name] = o end |