class JSObfu::Hoister

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.

Attributes

functions[R]

@return [Array<String>] the function names in the first level of this closure

scope[R]

@return [Hash] the scope maintained while walking the ast

Public Class Methods

new(opts={}) click to toggle source

@param opts [Hash] the options hash @option opts [Integer] :max_depth the maximum depth to hoist (1) @option opts [Scope] :parent_scope the owner's scope

Calls superclass method
# 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

Public Instance Methods

scope_declaration(opts={}) click to toggle source

@return [String] Javascript that declares the discovered variables

# 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
visit_FunctionDeclNode(o) click to toggle source
# File lib/jsobfu/hoister.rb, line 40
def visit_FunctionDeclNode(o)    
  functions << o.value
  scope[o.value] = o
end
visit_SourceElementsNode(o) click to toggle source
# 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
visit_VarDeclNode(o) click to toggle source
# File lib/jsobfu/hoister.rb, line 36
def visit_VarDeclNode(o)
  scope[o.name] = o
end