Class: Jsrb::JSStatementContext

Inherits:
Object
  • Object
show all
Defined in:
lib/jsrb/js_statement_context.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeJSStatementContext

Returns a new instance of JSStatementContext.



7
8
9
10
# File 'lib/jsrb/js_statement_context.rb', line 7

def initialize
  @var_count = 0
  @stacks = [[]]
end

Instance Attribute Details

#stacksObject (readonly)

Returns the value of attribute stacks.



5
6
7
# File 'lib/jsrb/js_statement_context.rb', line 5

def stacks
  @stacks
end

Instance Method Details

#gen_var_name!Object



12
13
14
15
# File 'lib/jsrb/js_statement_context.rb', line 12

def gen_var_name!
  @var_count += 1
  "_v#{@var_count}"
end

#new_blockObject



26
27
28
29
30
31
32
# File 'lib/jsrb/js_statement_context.rb', line 26

def new_block
  _result, statements = in_new_context { yield }
  {
    type: 'BlockStatement',
    body: statements
  }
end

#new_expression(object = nil) ⇒ Object



22
23
24
# File 'lib/jsrb/js_statement_context.rb', line 22

def new_expression(object = nil)
  ExprChain.new(self, object)
end

#push(*stmt) ⇒ Object



17
18
19
20
# File 'lib/jsrb/js_statement_context.rb', line 17

def push(*stmt)
  @stacks.last.push(*stmt)
  nil
end

#ruby_to_js_ast(rbv) ⇒ Object

rubocop:disable Metrics/MethodLength rubocop:disable Metrics/CyclomaticComplexity rubocop:disable Metrics/AbcSize



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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/jsrb/js_statement_context.rb', line 37

def ruby_to_js_ast(rbv)
  case rbv
  when ExprChain
    rbv.unwrap!
  when Proc
    chainables = rbv.parameters.map do |_type, name|
      new_expression.member!(name.to_s)
    end
    result, statements = in_new_context { rbv.call(*chainables) }
    if result
      statements.push(
        type: 'ReturnStatement',
        argument: ruby_to_js_ast(result)
      )
    end
    {
      type: 'FunctionExpression',
      id: nil,
      params: chainables.map { |arg| ruby_to_js_ast(arg) },
      body: {
        type: 'BlockStatement',
        body: statements
      }
    }
  when Hash
    var_name = gen_var_name!
    statements = rbv.map do |key, v|
      {
        type: 'ExpressionStatement',
        expression: new_expression.member!(var_name).member!(key).assign!(v).unwrap!
      }
    end
    {
      type: 'CallExpression',
      callee: {
        type: 'FunctionExpression',
        id: nil,
        params: [new_expression.member!(var_name).unwrap!],
        body: {
          type: 'BlockStatement',
          body: statements.concat(
            [
              {
                type: 'ReturnStatement',
                argument: new_expression.member!(var_name).unwrap!
              }
            ]
          )
        }
      },
      arguments: [
        {
          type: 'ObjectExpression',
          properties: []
        }
      ]
    }
  when Array
    {
      type: 'ArrayExpression',
      elements: rbv.map { |v| ruby_to_js_ast(v) }
    }
  when TrueClass, FalseClass, String, NilClass
    build_literal_ast(rbv)
  when Float::INFINITY
    new_expression.member!('Number').member!('POSITIVE_INFINITY').unwrap!
  when -Float::INFINITY
    new_expression.member!('Number').member!('NEGATIVE_INFINITY').unwrap!
  when Float
    if rbv.nan?
      new_expression.member!('Number').member!('NaN').unwrap!
    else
      build_finite_number_ast(rbv)
    end
  when Integer
    build_finite_number_ast(rbv)
  when Symbol
    ruby_to_js_ast(rbv.to_s)
  else
    raise "Can't convert to JavaScript AST from: #{rbv.inspect}"
  end
end