Class: Opal::Nodes::TopNode

Inherits:
ScopeNode show all
Defined in:
opal/lib/opal/nodes/top.rb

Overview

Generates code for an entire file, i.e. the base sexp

Instance Attribute Summary

Attributes inherited from ScopeNode

#await_encountered, #block_name, #catch_return, #defs, #gvars, #has_break, #has_retry, #identity, #ivars, #locals, #methods, #mid, #name, #parent, #rescue_else_sexp, #scope_name

Attributes inherited from Base

#compiler, #sexp, #type

Instance Method Summary collapse

Methods inherited from ScopeNode

#accepts_using?, #add_arg, #add_proto_ivar, #add_scope_gvar, #add_scope_ivar, #add_scope_local, #add_scope_temp, #class?, #class_scope?, #collect_refinements_temps, #current_rescue, #def?, #def_in_class?, #defines_lambda, #find_parent_def, #gen_retry_id, #has_local?, #has_rescue_else?, #has_temp?, #identify!, #in_ensure, #in_ensure?, #in_resbody, #in_resbody?, #in_rescue, #in_scope, #in_while?, #initialize, #is_lambda!, #iter?, #lambda?, #lambda_definition?, #module?, #nesting, #new_refinements_temp, #new_temp, #next_temp, #pop_while, #prepare_block, #push_while, #queue_temp, #refinements_temp, #relative_access, #sclass?, #scope_locals, #self, #super_chain, #to_vars, #top?, #uses_block!, #uses_block?

Methods inherited from Base

#add_gvar, #add_ivar, #add_local, #add_temp, #children, children, #class_variable_owner, #class_variable_owner_nesting_level, #comments, #compile_to_fragments, #error, #expr, #expr?, #expr_or_nil, #fragment, handle, handlers, #has_rescue_else?, #helper, #in_ensure, #in_ensure?, #in_resbody, #in_resbody?, #in_rescue, #in_while?, #initialize, #process, #push, #recv, #recv?, #s, #scope, #source_location, #stmt, #stmt?, #top_scope, truthy_optimize?, #unshift, #while_loop, #with_temp, #wrap

Methods included from Helpers

#current_indent, #empty_line, #indent, #js_truthy, #js_truthy_optimize, #line, #mid_to_jsid, #property, #valid_name?

Constructor Details

This class inherits a constructor from Opal::Nodes::ScopeNode

Instance Method Details

#absolute_constObject

Returns '$$$', but also ensures that the '$$$' variable is set



100
101
102
103
# File 'opal/lib/opal/nodes/top.rb', line 100

def absolute_const
  @define_absolute_const = true
  '$$$'
end

#add_used_helpersObject



111
112
113
# File 'opal/lib/opal/nodes/top.rb', line 111

def add_used_helpers
  compiler.helpers.to_a.each { |h| add_temp "$#{h} = Opal.#{h}" }
end

#closingObject



85
86
87
88
89
90
91
92
93
# File 'opal/lib/opal/nodes/top.rb', line 85

def closing
  if compiler.requirable?
    line "};\n"
  elsif compiler.eval?
    line "})(Opal, self);"
  else
    line "});\n"
  end
end

#compileObject



15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'opal/lib/opal/nodes/top.rb', line 15

def compile
  compiler.top_scope = self
  compiler.dynamic_cache_result = true if sexp.meta[:dynamic_cache_result]

  push version_comment

  helper :return_val if compiler.eof_content

  if body == s(:nil)
    # A shortpath for empty (stub?) modules.
    if compiler.requirable? || compiler.esm? || compiler.eval?
      unshift 'Opal.return_val(Opal.nil); '
      definition
    else
      unshift 'Opal.nil; '
    end
  else
    in_scope do
      line '"use strict";' if compiler.use_strict?

      body_code = stmt(stmts)
      body_code = [body_code] unless body_code.is_a?(Array)

      if compiler.eval?
        add_temp '$nesting = self.$$is_a_module ? [self] : [self.$$class]' if @define_nesting
      else
        add_temp 'self = Opal.top' if @define_self
        add_temp '$nesting = []' if @define_nesting
      end
      add_temp '$$ = Opal.$r($nesting)' if @define_relative_access

      add_temp 'nil = Opal.nil'
      add_temp '$$$ = Opal.$$$' if @define_absolute_const

      add_used_helpers
      line scope.to_vars

      compile_method_stubs
      compile_irb_vars
      compile_end_construct

      line body_code
    end

    opening
    definition
    closing
  end
end

#compile_end_constructObject

Any special END content in code



124
125
126
127
128
129
# File 'opal/lib/opal/nodes/top.rb', line 124

def compile_end_construct
  if content = compiler.eof_content
    line 'var $__END__ = Opal.Object.$new();'
    line "$__END__.$read = $return_val(#{content.inspect});"
  end
end

#compile_irb_varsObject



105
106
107
108
109
# File 'opal/lib/opal/nodes/top.rb', line 105

def compile_irb_vars
  if compiler.irb?
    line 'if (!Opal.irb_vars) { Opal.irb_vars = {}; }'
  end
end

#compile_method_stubsObject



115
116
117
118
119
120
121
# File 'opal/lib/opal/nodes/top.rb', line 115

def compile_method_stubs
  if compiler.method_missing?
    calls = compiler.method_calls
    stubs = calls.to_a.map(&:to_s).join(',')
    line "Opal.add_stubs('#{stubs}');" unless stubs.empty?
  end
end

#definitionObject



65
66
67
68
69
70
71
# File 'opal/lib/opal/nodes/top.rb', line 65

def definition
  if compiler.requirable?
    unshift "Opal.modules[#{Opal::Compiler.module_name(compiler.file).inspect}] = "
  elsif compiler.esm?
    unshift 'export default '
  end
end

#openingObject



73
74
75
76
77
78
79
80
81
82
83
# File 'opal/lib/opal/nodes/top.rb', line 73

def opening
  async_prefix = "async " if await_encountered

  if compiler.requirable?
    unshift "#{async_prefix}function(Opal) {"
  elsif compiler.eval?
    unshift "(#{async_prefix}function(Opal, self) {"
  else
    unshift "Opal.queue(#{async_prefix}function(Opal) {"
  end
end

#stmtsObject



95
96
97
# File 'opal/lib/opal/nodes/top.rb', line 95

def stmts
  compiler.returns(body)
end

#version_commentObject



131
132
133
# File 'opal/lib/opal/nodes/top.rb', line 131

def version_comment
  "/* Generated by Opal #{Opal::VERSION} */"
end