Class: JsxRosetta::AST::Node
- Inherits:
-
Object
- Object
- JsxRosetta::AST::Node
show all
- Defined in:
- lib/jsx_rosetta/ast/node.rb
Overview
Base class for every Babel-shaped AST node. Wraps the raw JSON hash and provides:
* Field access via `node[:opening_element]` (snake_case symbols or
camelCase strings — both resolve to the same field).
* Source location accessors (`loc`, `range`, `start_pos`, `end_pos`).
* Tree traversal via `each_child` / `walk`.
* Pattern-matching support via `deconstruct_keys`.
Specific Babel node types may register subclasses that add named accessors (e.g. JSXElement#opening_element). Unknown types fall through to the generic Node class so the parser doesn’t crash on ESNext additions.
Direct Known Subclasses
File, JSXAttribute, JSXClosingElement, JSXClosingFragment, JSXElement, JSXEmptyExpression, JSXExpressionContainer, JSXFragment, JSXIdentifier, JSXMemberExpression, JSXNamespacedName, JSXOpeningElement, JSXOpeningFragment, JSXSpreadAttribute, JSXSpreadChild, JSXText, Program
Constant Summary
collapse
- TYPE_REGISTRY =
rubocop:disable Style/MutableConstant
{}
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
Constructor Details
#initialize(raw) ⇒ Node
Returns a new instance of Node.
44
45
46
|
# File 'lib/jsx_rosetta/ast/node.rb', line 44
def initialize(raw)
@raw = raw
end
|
Instance Attribute Details
#raw ⇒ Object
Returns the value of attribute raw.
22
23
24
|
# File 'lib/jsx_rosetta/ast/node.rb', line 22
def raw
@raw
end
|
Class Method Details
.register(*type_names) ⇒ Object
24
25
26
|
# File 'lib/jsx_rosetta/ast/node.rb', line 24
def self.register(*type_names)
type_names.each { |name| TYPE_REGISTRY[name] = self }
end
|
.wrap(value) ⇒ Object
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
|
# File 'lib/jsx_rosetta/ast/node.rb', line 28
def self.wrap(value)
case value
when Hash
if value.key?("type")
klass = TYPE_REGISTRY.fetch(value["type"], Node)
klass.new(value)
else
value
end
when Array
value.map { |element| wrap(element) }
else
value
end
end
|
Instance Method Details
#==(other) ⇒ Object
Also known as:
eql?
119
120
121
|
# File 'lib/jsx_rosetta/ast/node.rb', line 119
def ==(other)
other.is_a?(Node) && other.raw == @raw
end
|
#[](key) ⇒ Object
Field access. Accepts snake_case symbols/strings (translated to camelCase) and camelCase strings (used verbatim).
70
71
72
73
74
75
76
|
# File 'lib/jsx_rosetta/ast/node.rb', line 70
def [](key)
raw_key = key.to_s
return Node.wrap(@raw[raw_key]) if @raw.key?(raw_key)
camel_key = Inflector.camelize(raw_key)
Node.wrap(@raw[camel_key])
end
|
#children ⇒ Object
92
93
94
|
# File 'lib/jsx_rosetta/ast/node.rb', line 92
def children
each_child.to_a
end
|
#deconstruct_keys(keys) ⇒ Object
Pattern-matching support. Returns a hash with snake_case symbol keys; values are wrapped (Node instances or arrays of Node/raw values).
105
106
107
108
109
110
111
112
113
114
115
116
117
|
# File 'lib/jsx_rosetta/ast/node.rb', line 105
def deconstruct_keys(keys)
if keys.nil?
@raw.each_with_object({}) do |(k, v), out|
out[Inflector.underscore(k).to_sym] = Node.wrap(v)
end
else
keys.each_with_object({}) do |key, out|
camel_key = Inflector.camelize(key.to_s)
actual_key = @raw.key?(key.to_s) ? key.to_s : camel_key
out[key] = Node.wrap(@raw[actual_key]) if @raw.key?(actual_key)
end
end
end
|
#dig(*keys) ⇒ Object
78
79
80
81
82
83
84
|
# File 'lib/jsx_rosetta/ast/node.rb', line 78
def dig(*keys)
keys.reduce(self) do |current, key|
break nil if current.nil?
current[key]
end
end
|
#each_child(&block) ⇒ Object
86
87
88
89
90
|
# File 'lib/jsx_rosetta/ast/node.rb', line 86
def each_child(&block)
return enum_for(:each_child) unless block
@raw.each_value { |value| yield_descendant_nodes(value, &block) }
end
|
#end_pos ⇒ Object
64
65
66
|
# File 'lib/jsx_rosetta/ast/node.rb', line 64
def end_pos
@raw["end"]
end
|
#hash ⇒ Object
124
125
126
|
# File 'lib/jsx_rosetta/ast/node.rb', line 124
def hash
@raw.hash
end
|
#inspect ⇒ Object
128
129
130
|
# File 'lib/jsx_rosetta/ast/node.rb', line 128
def inspect
"#<#{self.class.name || "JsxRosetta::AST::Node"} type=#{type.inspect} loc=#{loc_summary}>"
end
|
#loc ⇒ Object
52
53
54
|
# File 'lib/jsx_rosetta/ast/node.rb', line 52
def loc
@raw["loc"]
end
|
#range ⇒ Object
56
57
58
|
# File 'lib/jsx_rosetta/ast/node.rb', line 56
def range
@raw["range"]
end
|
#start_pos ⇒ Object
60
61
62
|
# File 'lib/jsx_rosetta/ast/node.rb', line 60
def start_pos
@raw["start"]
end
|
#type ⇒ Object
48
49
50
|
# File 'lib/jsx_rosetta/ast/node.rb', line 48
def type
@raw["type"]
end
|
#walk {|_self| ... } ⇒ Object
96
97
98
99
100
101
|
# File 'lib/jsx_rosetta/ast/node.rb', line 96
def walk(&block)
return enum_for(:walk) unless block
yield self
each_child { |child| child.walk(&block) }
end
|