137 lines
4.1 KiB
Ruby
137 lines
4.1 KiB
Ruby
module RKelly
|
|
module Visitors
|
|
class Visitor
|
|
TERMINAL_NODES = %w{
|
|
Break Continue EmptyStatement False Null Number Parameter Regexp Resolve
|
|
String This True
|
|
}
|
|
SINGLE_VALUE_NODES = %w{
|
|
Parenthetical AssignExpr BitwiseNot Block Delete Element ExpressionStatement
|
|
FunctionBody LogicalNot Return Throw TypeOf UnaryMinus UnaryPlus Void
|
|
}
|
|
BINARY_NODES = %w{
|
|
Add BitAnd BitOr BitXOr CaseClause Comma Divide DoWhile Equal Greater
|
|
GreaterOrEqual In InstanceOf LeftShift Less LessOrEqual LogicalAnd
|
|
LogicalOr Modulus Multiply NotEqual NotStrictEqual OpAndEqual
|
|
OpDivideEqual OpEqual OpLShiftEqual OpMinusEqual OpModEqual
|
|
OpMultiplyEqual OpOrEqual OpPlusEqual OpRShiftEqual OpURShiftEqual
|
|
OpXOrEqual RightShift StrictEqual Subtract Switch UnsignedRightShift
|
|
While With
|
|
}
|
|
ARRAY_VALUE_NODES = %w{
|
|
Arguments Array CaseBlock ConstStatement ObjectLiteral SourceElements
|
|
VarStatement
|
|
}
|
|
NAME_VALUE_NODES = %w{
|
|
Label Property GetterProperty SetterProperty VarDecl
|
|
}
|
|
PREFIX_POSTFIX_NODES = %w{ Postfix Prefix }
|
|
CONDITIONAL_NODES = %w{ If Conditional }
|
|
FUNC_CALL_NODES = %w{ NewExpr FunctionCall }
|
|
FUNC_DECL_NODES = %w{ FunctionExpr FunctionDecl }
|
|
ALL_NODES = %w{ For ForIn Try BracketAccessor DotAccessor } +
|
|
TERMINAL_NODES + SINGLE_VALUE_NODES + BINARY_NODES + ARRAY_VALUE_NODES +
|
|
NAME_VALUE_NODES + PREFIX_POSTFIX_NODES + CONDITIONAL_NODES +
|
|
FUNC_CALL_NODES + FUNC_DECL_NODES
|
|
|
|
def accept(target)
|
|
target.accept(self)
|
|
end
|
|
|
|
TERMINAL_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") { |o| o.value }
|
|
end
|
|
|
|
BINARY_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
[o.left && o.left.accept(self), o.value && o.value.accept(self)]
|
|
end
|
|
end
|
|
|
|
ARRAY_VALUE_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
o.value && o.value.map { |v| v ? v.accept(self) : nil }
|
|
end
|
|
end
|
|
|
|
NAME_VALUE_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
[o.name.to_s.to_sym, o.value ? o.value.accept(self) : nil]
|
|
end
|
|
end
|
|
|
|
SINGLE_VALUE_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
o.value.accept(self) if o.value
|
|
end
|
|
end
|
|
|
|
PREFIX_POSTFIX_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
o.operand.accept(self)
|
|
end
|
|
end
|
|
|
|
CONDITIONAL_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
[ o.conditions.accept(self),
|
|
o.value.accept(self),
|
|
o.else ? o.else.accept(self) : nil
|
|
]
|
|
end
|
|
end
|
|
FUNC_CALL_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
[o.value.accept(self), o.arguments.accept(self)]
|
|
end
|
|
end
|
|
FUNC_DECL_NODES.each do |type|
|
|
define_method(:"visit_#{type}Node") do |o|
|
|
[
|
|
o.value ? o.value : nil,
|
|
o.arguments.map { |x| x.accept(self) },
|
|
o.function_body.accept(self)
|
|
]
|
|
end
|
|
end
|
|
|
|
def visit_ForNode(o)
|
|
[
|
|
o.init ? o.init.accept(self) : nil,
|
|
o.test ? o.test.accept(self) : nil,
|
|
o.counter ? o.counter.accept(self) : nil,
|
|
o.value.accept(self)
|
|
]
|
|
end
|
|
|
|
def visit_ForInNode(o)
|
|
[
|
|
o.left.accept(self),
|
|
o.right.accept(self),
|
|
o.value.accept(self)
|
|
]
|
|
end
|
|
|
|
def visit_TryNode(o)
|
|
[
|
|
o.value.accept(self),
|
|
o.catch_var ? o.catch_var : nil,
|
|
o.catch_block ? o.catch_block.accept(self) : nil,
|
|
o.finally_block ? o.finally_block.accept(self) : nil
|
|
]
|
|
end
|
|
|
|
def visit_BracketAccessorNode(o)
|
|
[
|
|
o.value.accept(self),
|
|
o.accessor.accept(self)
|
|
]
|
|
end
|
|
|
|
def visit_DotAccessorNode(o)
|
|
o.value.accept(self)
|
|
end
|
|
end
|
|
end
|
|
end
|