herb 0.11.1 → 0.11.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Rakefile +4 -2
- data/config.yml +6 -0
- data/ext/herb/extconf.rb +8 -31
- data/ext/herb/nodes.c +75 -75
- data/ext/herb/parser_options_helpers.c +26 -0
- data/lib/herb/analysis/partial_index.rb +1 -1
- data/lib/herb/analysis/partial_resolution.rb +27 -0
- data/lib/herb/ast/helpers.rb +1 -1
- data/lib/herb/configuration.rb +11 -1
- data/lib/herb/dev/classifier.rb +1 -1
- data/lib/herb/engine/compiler.rb +5 -8
- data/lib/herb/engine/slots/dynamics_compiler.rb +53 -14
- data/lib/herb/engine/slots/subtree_compiler.rb +1 -1
- data/lib/herb/engine/slots/visitor.rb +32 -4
- data/lib/herb/engine/visitors/instrumentation_visitor.rb +18 -6
- data/lib/herb/parser_options.rb +6 -3
- data/lib/herb/project.rb +19 -8
- data/lib/herb/version.rb +1 -1
- data/lib/herb.rb +1 -1
- data/sig/herb/analysis/partial_resolution.rbs +8 -0
- data/sig/herb/configuration.rbs +3 -0
- data/sig/herb/engine/slots/dynamics_compiler.rbs +24 -7
- data/sig/herb/engine/slots/visitor.rbs +14 -0
- data/sig/herb/engine/visitors/instrumentation_visitor.rbs +5 -1
- data/sig/herb/parser_options.rbs +6 -4
- data/sig/herb.rbs +2 -2
- data/src/analyze/action_view/attribute_extraction_helpers.c +40 -21
- data/src/analyze/action_view/generated_handlers.c +36 -36
- data/src/analyze/action_view/image_tag.c +7 -3
- data/src/analyze/action_view/javascript_include_tag.c +6 -3
- data/src/analyze/action_view/link_to.c +23 -23
- data/src/analyze/action_view/registry.c +7 -3
- data/src/analyze/action_view/tag_helper_node_builders.c +6 -13
- data/src/analyze/action_view/tag_helpers.c +139 -90
- data/src/analyze/action_view/turbo_frame_tag.c +5 -4
- data/src/analyze/analyze.c +35 -19
- data/src/analyze/analyze_helpers.c +161 -188
- data/src/analyze/analyzed_ruby.c +8 -7
- data/src/analyze/control_type.c +29 -22
- data/src/analyze/herb_directives.c +16 -20
- data/src/analyze/iteration_nodes.c +69 -24
- data/src/analyze/parse_errors.c +32 -22
- data/src/analyze/postfix_conditionals.c +23 -13
- data/src/analyze/prism_annotate.c +29 -28
- data/src/analyze/render_nodes.c +51 -41
- data/src/analyze/strict_locals.c +14 -15
- data/src/analyze/ternary_conditionals.c +14 -10
- data/src/herb.c +10 -8
- data/src/include/analyze/action_view/tag_helper_handler.h +1 -1
- data/src/include/analyze/action_view/tag_helper_node_builders.h +1 -0
- data/src/include/analyze/action_view/tag_helpers.h +1 -1
- data/src/include/analyze/analyze.h +3 -2
- data/src/include/analyze/analyzed_ruby.h +4 -2
- data/src/include/analyze/helpers.h +6 -6
- data/src/include/herb.h +3 -2
- data/src/include/parser/parser_options.h +5 -0
- data/src/include/prism/prism_context.h +12 -12
- data/src/include/prism/prism_helpers.h +30 -0
- data/src/include/prism_version.h +11 -0
- data/src/include/version.h +1 -1
- data/src/parser/parser_helpers.c +1 -2
- data/src/parser.c +6 -7
- data/src/parser_options_defaults.c +1 -0
- data/src/prism/prism_helpers.c +84 -50
- data/src/prism/ruby_parser.c +20 -20
- data/templates/ext/herb/nodes.c.erb +5 -5
- data/templates/ext/herb/parser_options_helpers.c.erb +33 -0
- data/templates/java/nodes.c.erb +6 -6
- data/templates/java/parser_options_helpers.c.erb +41 -2
- data/templates/java/parser_options_helpers.h.erb +2 -1
- data/templates/javascript/packages/node/extension/nodes.cpp.erb +5 -5
- data/templates/javascript/packages/node/extension/parser_options_helpers.cpp.erb +34 -2
- data/templates/javascript/packages/node/extension/parser_options_helpers.h.erb +1 -1
- data/templates/lib/herb/parser_options.rb.erb +1 -1
- data/templates/rust/src/prism/generated_deserialize.rs.erb +90 -44
- data/templates/rust/src/prism/generated_prettyprint.rs.erb +18 -27
- data/templates/src/analyze/action_view/generated_handlers.c.erb +23 -22
- data/templates/src/include/parser/parser_options.h.erb +10 -0
- data/templates/src/include/prism_version.h.erb +17 -0
- data/templates/src/parser_options_defaults.c.erb +1 -1
- data/templates/template.rb +17 -2
- data/templates/wasm/nodes.cpp.erb +5 -5
- data/templates/wasm/parser_options_helpers.cpp.erb +24 -0
- data/vendor/prism/Rakefile +76 -7
- data/vendor/prism/config.yml +174 -161
- data/vendor/prism/include/prism/arena.h +45 -0
- data/vendor/prism/include/prism/arena.hpp +42 -0
- data/vendor/prism/include/prism/ast.h +2738 -611
- data/vendor/prism/include/prism/ast.hpp +641 -0
- data/vendor/prism/include/prism/buffer.h +60 -0
- data/vendor/prism/include/prism/buffer.hpp +55 -0
- data/vendor/prism/include/prism/comments.h +72 -0
- data/vendor/prism/include/prism/compiler/accel.h +26 -0
- data/vendor/prism/include/prism/compiler/align.h +36 -0
- data/vendor/prism/include/prism/compiler/assume.h +25 -0
- data/vendor/prism/include/prism/compiler/branch.h +26 -0
- data/vendor/prism/include/prism/compiler/bswap.h +46 -0
- data/vendor/prism/include/prism/compiler/cplusplus.hpp +16 -0
- data/vendor/prism/include/prism/compiler/endianness.h +34 -0
- data/vendor/prism/include/prism/compiler/exceptions.hpp +17 -0
- data/vendor/prism/include/prism/compiler/exported.h +24 -0
- data/vendor/prism/include/prism/compiler/fallthrough.h +22 -0
- data/vendor/prism/include/prism/compiler/filesystem.h +32 -0
- data/vendor/prism/include/prism/compiler/flex_array.h +19 -0
- data/vendor/prism/include/prism/compiler/force_inline.h +21 -0
- data/vendor/prism/include/prism/compiler/format.h +27 -0
- data/vendor/prism/include/prism/compiler/inline.h +17 -0
- data/vendor/prism/include/prism/compiler/lifetimebound.hpp +25 -0
- data/vendor/prism/include/prism/compiler/nodiscard.h +22 -0
- data/vendor/prism/include/prism/compiler/nonnull.h +18 -0
- data/vendor/prism/include/prism/compiler/unused.h +18 -0
- data/vendor/prism/include/prism/constant_pool.h +106 -0
- data/vendor/prism/include/prism/diagnostic.h +55 -402
- data/vendor/prism/include/prism/errors_format.h +61 -0
- data/vendor/prism/include/prism/excludes.h +29 -0
- data/vendor/prism/include/prism/integer.h +41 -0
- data/vendor/prism/include/prism/internal/allocator.h +68 -0
- data/vendor/prism/include/prism/internal/allocator_debug.h +88 -0
- data/vendor/prism/include/prism/internal/arena.h +108 -0
- data/vendor/prism/include/prism/internal/bit.h +42 -0
- data/vendor/prism/include/prism/internal/buffer.h +94 -0
- data/vendor/prism/include/prism/internal/char.h +145 -0
- data/vendor/prism/include/prism/internal/comments.h +54 -0
- data/vendor/prism/include/prism/internal/constant_pool.h +152 -0
- data/vendor/prism/include/prism/internal/diagnostic.h +389 -0
- data/vendor/prism/include/prism/{encoding.h → internal/encoding.h} +27 -68
- data/vendor/prism/include/prism/internal/integer.h +68 -0
- data/vendor/prism/include/prism/internal/isinf.h +16 -0
- data/vendor/prism/include/prism/internal/line_offset_list.h +34 -0
- data/vendor/prism/include/prism/{util/pm_list.h → internal/list.h} +11 -52
- data/vendor/prism/include/prism/internal/magic_comments.h +23 -0
- data/vendor/prism/include/prism/internal/memchr.h +15 -0
- data/vendor/prism/include/prism/internal/node.h +42 -0
- data/vendor/prism/include/prism/internal/options.h +232 -0
- data/vendor/prism/include/prism/internal/parser.h +1015 -0
- data/vendor/prism/include/prism/internal/regexp.h +26 -0
- data/vendor/prism/include/prism/internal/serialize.h +39 -0
- data/vendor/prism/include/prism/internal/source.h +72 -0
- data/vendor/prism/include/prism/internal/static_literals.h +60 -0
- data/vendor/prism/include/prism/internal/stringy.h +30 -0
- data/vendor/prism/include/prism/{util/pm_strncasecmp.h → internal/strncasecmp.h} +3 -17
- data/vendor/prism/include/prism/{util/pm_strpbrk.h → internal/strpbrk.h} +7 -20
- data/vendor/prism/include/prism/internal/tokens.h +11 -0
- data/vendor/prism/include/prism/internal/xxh3.h +16 -0
- data/vendor/prism/include/prism/json.h +40 -0
- data/vendor/prism/include/prism/line_offset_list.h +69 -0
- data/vendor/prism/include/prism/magic_comments.h +53 -0
- data/vendor/prism/include/prism/node.h +59 -49
- data/vendor/prism/include/prism/node.hpp +272 -0
- data/vendor/prism/include/prism/node_type.hpp +38 -0
- data/vendor/prism/include/prism/options.h +154 -279
- data/vendor/prism/include/prism/options.hpp +43 -0
- data/vendor/prism/include/prism/parser.h +367 -870
- data/vendor/prism/include/prism/parser.hpp +274 -0
- data/vendor/prism/include/prism/prettyprint.h +14 -9
- data/vendor/prism/include/prism/serialize.h +123 -0
- data/vendor/prism/include/prism/source.h +163 -0
- data/vendor/prism/include/prism/stream.h +36 -0
- data/vendor/prism/include/prism/string_query.h +82 -0
- data/vendor/prism/include/prism/stringy.h +61 -0
- data/vendor/prism/include/prism/stringy.hpp +31 -0
- data/vendor/prism/include/prism/version.h +20 -3
- data/vendor/prism/include/prism.h +35 -320
- data/vendor/prism/include/prism.hpp +24 -0
- data/vendor/prism/src/arena.c +122 -0
- data/vendor/prism/src/{util/pm_buffer.c → buffer.c} +53 -21
- data/vendor/prism/src/{util/pm_char.c → char.c} +28 -57
- data/vendor/prism/src/comments.c +455 -0
- data/vendor/prism/src/constant_pool.c +406 -0
- data/vendor/prism/src/diagnostic.c +120 -68
- data/vendor/prism/src/encoding.c +8 -3
- data/vendor/prism/src/errors_format.c +519 -0
- data/vendor/prism/src/{util/pm_integer.c → integer.c} +38 -22
- data/vendor/prism/src/json.c +5733 -0
- data/vendor/prism/src/line_offset_list.c +100 -0
- data/vendor/prism/src/list.c +24 -0
- data/vendor/prism/src/{util/pm_memchr.c → memchr.c} +8 -6
- data/vendor/prism/src/node.c +3465 -7787
- data/vendor/prism/src/options.c +161 -54
- data/vendor/prism/src/parser.c +371 -0
- data/vendor/prism/src/prettyprint.c +421 -354
- data/vendor/prism/src/prism.c +8522 -7280
- data/vendor/prism/src/regexp.c +960 -45
- data/vendor/prism/src/serialize.c +2434 -2048
- data/vendor/prism/src/source.c +524 -0
- data/vendor/prism/src/static_literals.c +303 -360
- data/vendor/prism/src/string_query.c +180 -0
- data/vendor/prism/src/stringy.c +61 -0
- data/vendor/prism/src/{util/pm_strncasecmp.c → strncasecmp.c} +5 -4
- data/vendor/prism/src/strpbrk.c +447 -0
- data/vendor/prism/src/{token_type.c → tokens.c} +39 -18
- data/vendor/prism/src/xxh3.c +292 -0
- data/vendor/prism/templates/ext/prism/api_node.c.erb +58 -44
- data/vendor/prism/templates/include/prism/ast.h.erb +67 -17
- data/vendor/prism/templates/include/prism/ast.hpp.erb +31 -0
- data/vendor/prism/templates/include/prism/internal/diagnostic.h.erb +60 -0
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/AbstractNodeVisitor.java.erb +1 -1
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Loader.java.erb +232 -133
- data/vendor/prism/templates/java/{org → api/src/main/java-templates/org/ruby_lang}/prism/Nodes.java.erb +62 -23
- data/vendor/prism/templates/javascript/src/deserialize.js.erb +153 -146
- data/vendor/prism/templates/javascript/src/nodes.js.erb +4 -9
- data/vendor/prism/templates/lib/prism/compiler.rb.erb +14 -5
- data/vendor/prism/templates/lib/prism/dispatcher.rb.erb +20 -12
- data/vendor/prism/templates/lib/prism/dot_visitor.rb.erb +37 -11
- data/vendor/prism/templates/lib/prism/dsl.rb.erb +43 -4
- data/vendor/prism/templates/lib/prism/inspect_visitor.rb.erb +26 -10
- data/vendor/prism/templates/lib/prism/mutation_compiler.rb.erb +5 -2
- data/vendor/prism/templates/lib/prism/node.rb.erb +283 -105
- data/vendor/prism/templates/lib/prism/reflection.rb.erb +11 -2
- data/vendor/prism/templates/lib/prism/serialize.rb.erb +291 -134
- data/vendor/prism/templates/lib/prism/visitor.rb.erb +18 -0
- data/vendor/prism/templates/src/diagnostic.c.erb +114 -63
- data/vendor/prism/templates/src/json.c.erb +130 -0
- data/vendor/prism/templates/src/node.c.erb +79 -236
- data/vendor/prism/templates/src/prettyprint.c.erb +24 -13
- data/vendor/prism/templates/src/serialize.c.erb +369 -183
- data/vendor/prism/templates/src/{token_type.c.erb → tokens.c.erb} +22 -11
- data/vendor/prism/templates/template.rb +193 -91
- metadata +100 -42
- data/vendor/prism/include/prism/defines.h +0 -260
- data/vendor/prism/include/prism/pack.h +0 -163
- data/vendor/prism/include/prism/regexp.h +0 -43
- data/vendor/prism/include/prism/static_literals.h +0 -121
- data/vendor/prism/include/prism/util/pm_buffer.h +0 -236
- data/vendor/prism/include/prism/util/pm_char.h +0 -204
- data/vendor/prism/include/prism/util/pm_constant_pool.h +0 -218
- data/vendor/prism/include/prism/util/pm_integer.h +0 -130
- data/vendor/prism/include/prism/util/pm_memchr.h +0 -29
- data/vendor/prism/include/prism/util/pm_newline_list.h +0 -113
- data/vendor/prism/include/prism/util/pm_string.h +0 -200
- data/vendor/prism/src/pack.c +0 -509
- data/vendor/prism/src/util/pm_constant_pool.c +0 -342
- data/vendor/prism/src/util/pm_list.c +0 -49
- data/vendor/prism/src/util/pm_newline_list.c +0 -125
- data/vendor/prism/src/util/pm_string.c +0 -381
- data/vendor/prism/src/util/pm_strpbrk.c +0 -206
- data/vendor/prism/templates/include/prism/diagnostic.h.erb +0 -130
- data/vendor/prism/templates/rbi/prism/dsl.rbi.erb +0 -68
- data/vendor/prism/templates/rbi/prism/node.rbi.erb +0 -167
- data/vendor/prism/templates/rbi/prism/visitor.rbi.erb +0 -18
- data/vendor/prism/templates/sig/prism/_private/dot_visitor.rbs.erb +0 -45
- data/vendor/prism/templates/sig/prism/dsl.rbs.erb +0 -31
- data/vendor/prism/templates/sig/prism/mutation_compiler.rbs.erb +0 -7
- data/vendor/prism/templates/sig/prism/node.rbs.erb +0 -136
- data/vendor/prism/templates/sig/prism/visitor.rbs.erb +0 -17
- data/vendor/prism/templates/sig/prism.rbs.erb +0 -92
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
1
4
|
module Prism
|
|
2
5
|
# A compiler is a visitor that returns the value of each node as it visits.
|
|
3
6
|
# This is as opposed to a visitor which will only walk the tree. This can be
|
|
@@ -18,24 +21,30 @@ module Prism
|
|
|
18
21
|
#
|
|
19
22
|
class Compiler < Visitor
|
|
20
23
|
# Visit an individual node.
|
|
21
|
-
|
|
24
|
+
#
|
|
25
|
+
#: (node?) -> untyped
|
|
26
|
+
def visit(node) # :nodoc:
|
|
22
27
|
node&.accept(self)
|
|
23
28
|
end
|
|
24
29
|
|
|
25
30
|
# Visit a list of nodes.
|
|
26
|
-
|
|
31
|
+
#
|
|
32
|
+
#: (Array[node?]) -> untyped
|
|
33
|
+
def visit_all(nodes) # :nodoc:
|
|
27
34
|
nodes.map { |node| node&.accept(self) }
|
|
28
35
|
end
|
|
29
36
|
|
|
30
37
|
# Visit the child nodes of the given node.
|
|
31
|
-
|
|
38
|
+
#
|
|
39
|
+
#: (node) -> Array[untyped]
|
|
40
|
+
def visit_child_nodes(node) # :nodoc:
|
|
32
41
|
node.each_child_node.map { |node| node.accept(self) }
|
|
33
42
|
end
|
|
34
43
|
|
|
35
44
|
<%- nodes.each_with_index do |node, index| -%>
|
|
36
45
|
<%= "\n" if index != 0 -%>
|
|
37
|
-
|
|
38
|
-
def visit_<%= node.human %>(node)
|
|
46
|
+
#: (<%= node.name %>) -> Array[untyped]
|
|
47
|
+
def visit_<%= node.human %>(node) # :nodoc:
|
|
39
48
|
node.each_child_node.map { |node| node.accept(self) }
|
|
40
49
|
end
|
|
41
50
|
<%- end -%>
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
1
4
|
module Prism
|
|
2
5
|
# The dispatcher class fires events for nodes that are found while walking an
|
|
3
6
|
# AST to all registered listeners. It's useful for performing different types
|
|
@@ -32,17 +35,20 @@ module Prism
|
|
|
32
35
|
# dispatcher.dispatch_once(integer)
|
|
33
36
|
#
|
|
34
37
|
class Dispatcher < Visitor
|
|
35
|
-
#
|
|
36
|
-
|
|
38
|
+
# A hash mapping event names to arrays of listeners that should be notified
|
|
39
|
+
# when that event is fired.
|
|
40
|
+
attr_reader :listeners #: Hash[Symbol, Array[untyped]]
|
|
37
41
|
|
|
38
42
|
# Initialize a new dispatcher.
|
|
43
|
+
#
|
|
44
|
+
#: () -> void
|
|
39
45
|
def initialize
|
|
40
46
|
@listeners = {}
|
|
41
47
|
end
|
|
42
48
|
|
|
43
49
|
# Register a listener for one or more events.
|
|
44
50
|
#
|
|
45
|
-
|
|
51
|
+
#: (untyped, *Symbol) -> void
|
|
46
52
|
def register(listener, *events)
|
|
47
53
|
register_events(listener, events)
|
|
48
54
|
end
|
|
@@ -50,32 +56,31 @@ module Prism
|
|
|
50
56
|
# Register all public methods of a listener that match the pattern
|
|
51
57
|
# `on_<node_name>_(enter|leave)`.
|
|
52
58
|
#
|
|
53
|
-
|
|
59
|
+
#: (untyped) -> void
|
|
54
60
|
def register_public_methods(listener)
|
|
55
61
|
register_events(listener, listener.public_methods(false).grep(/\Aon_.+_(?:enter|leave)\z/))
|
|
56
62
|
end
|
|
57
63
|
|
|
58
64
|
# Register a listener for the given events.
|
|
59
|
-
|
|
65
|
+
#
|
|
66
|
+
#: (untyped, Array[Symbol]) -> void
|
|
67
|
+
private def register_events(listener, events) # :nodoc:
|
|
60
68
|
events.each { |event| (listeners[event] ||= []) << listener }
|
|
61
69
|
end
|
|
62
70
|
|
|
63
71
|
# Walks `root` dispatching events to all registered listeners.
|
|
64
|
-
#
|
|
65
|
-
# def dispatch: (Node) -> void
|
|
66
72
|
alias dispatch visit
|
|
67
73
|
|
|
68
74
|
# Dispatches a single event for `node` to all registered listeners.
|
|
69
75
|
#
|
|
70
|
-
|
|
76
|
+
#: (node node) -> void
|
|
71
77
|
def dispatch_once(node)
|
|
72
78
|
node.accept(DispatchOnce.new(listeners))
|
|
73
79
|
end
|
|
74
80
|
<%- nodes.each do |node| -%>
|
|
75
81
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
def visit_<%= node.human %>(node)
|
|
82
|
+
#: (<%= node.name %> node) -> void
|
|
83
|
+
def visit_<%= node.human %>(node) # :nodoc:
|
|
79
84
|
listeners[:on_<%= node.human %>_enter]&.each { |listener| listener.on_<%= node.human %>_enter(node) }
|
|
80
85
|
super
|
|
81
86
|
listeners[:on_<%= node.human %>_leave]&.each { |listener| listener.on_<%= node.human %>_leave(node) }
|
|
@@ -83,14 +88,17 @@ module Prism
|
|
|
83
88
|
<%- end -%>
|
|
84
89
|
|
|
85
90
|
class DispatchOnce < Visitor # :nodoc:
|
|
86
|
-
attr_reader :listeners
|
|
91
|
+
attr_reader :listeners #: Hash[Symbol, Array[untyped]]
|
|
87
92
|
|
|
93
|
+
#: (Hash[Symbol, Array[untyped]] listeners) -> void
|
|
88
94
|
def initialize(listeners)
|
|
89
95
|
@listeners = listeners
|
|
90
96
|
end
|
|
91
97
|
<%- nodes.each do |node| -%>
|
|
92
98
|
|
|
93
99
|
# Dispatch enter and leave events for <%= node.name %> nodes.
|
|
100
|
+
#
|
|
101
|
+
#: (<%= node.name %> node) -> void
|
|
94
102
|
def visit_<%= node.human %>(node)
|
|
95
103
|
listeners[:on_<%= node.human %>_enter]&.each { |listener| listener.on_<%= node.human %>_enter(node) }
|
|
96
104
|
listeners[:on_<%= node.human %>_leave]&.each { |listener| listener.on_<%= node.human %>_leave(node) }
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
1
4
|
require "cgi/escape"
|
|
2
5
|
require "cgi/util" unless defined?(CGI::EscapeExt)
|
|
3
6
|
|
|
@@ -6,14 +9,18 @@ module Prism
|
|
|
6
9
|
# subtree into a graphviz dot graph.
|
|
7
10
|
class DotVisitor < Visitor
|
|
8
11
|
class Field # :nodoc:
|
|
9
|
-
attr_reader :name
|
|
12
|
+
attr_reader :name #: String
|
|
13
|
+
attr_reader :value #: String?
|
|
14
|
+
attr_reader :port #: bool
|
|
10
15
|
|
|
16
|
+
#: (String name, String? value, bool port) -> void
|
|
11
17
|
def initialize(name, value, port)
|
|
12
18
|
@name = name
|
|
13
19
|
@value = value
|
|
14
20
|
@port = port
|
|
15
21
|
end
|
|
16
22
|
|
|
23
|
+
#: () -> String
|
|
17
24
|
def to_dot
|
|
18
25
|
if port
|
|
19
26
|
"<tr><td align=\"left\" colspan=\"2\" port=\"#{name}\">#{name}</td></tr>"
|
|
@@ -24,17 +31,21 @@ module Prism
|
|
|
24
31
|
end
|
|
25
32
|
|
|
26
33
|
class Table # :nodoc:
|
|
27
|
-
attr_reader :name
|
|
34
|
+
attr_reader :name #: String
|
|
35
|
+
attr_reader :fields #: Array[Field]
|
|
28
36
|
|
|
37
|
+
#: (String name) -> void
|
|
29
38
|
def initialize(name)
|
|
30
39
|
@name = name
|
|
31
40
|
@fields = []
|
|
32
41
|
end
|
|
33
42
|
|
|
43
|
+
#: (String name, ?String? value, ?port: bool) -> void
|
|
34
44
|
def field(name, value = nil, port: false)
|
|
35
45
|
fields << Field.new(name, value, port)
|
|
36
46
|
end
|
|
37
47
|
|
|
48
|
+
#: () -> String
|
|
38
49
|
def to_dot
|
|
39
50
|
dot = <<~DOT
|
|
40
51
|
<table border="0" cellborder="1" cellspacing="0" cellpadding="4">
|
|
@@ -50,26 +61,31 @@ module Prism
|
|
|
50
61
|
end
|
|
51
62
|
|
|
52
63
|
class Digraph # :nodoc:
|
|
53
|
-
attr_reader :nodes, :waypoints, :edges
|
|
64
|
+
attr_reader :nodes, :waypoints, :edges #: Array[String]
|
|
54
65
|
|
|
66
|
+
#: () -> void
|
|
55
67
|
def initialize
|
|
56
68
|
@nodes = []
|
|
57
69
|
@waypoints = []
|
|
58
70
|
@edges = []
|
|
59
71
|
end
|
|
60
72
|
|
|
73
|
+
#: (String value) -> void
|
|
61
74
|
def node(value)
|
|
62
75
|
nodes << value
|
|
63
76
|
end
|
|
64
77
|
|
|
78
|
+
#: (String value) -> void
|
|
65
79
|
def waypoint(value)
|
|
66
80
|
waypoints << value
|
|
67
81
|
end
|
|
68
82
|
|
|
83
|
+
#: (String value) -> void
|
|
69
84
|
def edge(value)
|
|
70
85
|
edges << value
|
|
71
86
|
end
|
|
72
87
|
|
|
88
|
+
#: () -> String
|
|
73
89
|
def to_dot
|
|
74
90
|
<<~DOT
|
|
75
91
|
digraph "Prism" {
|
|
@@ -93,21 +109,25 @@ module Prism
|
|
|
93
109
|
private_constant :Field, :Table, :Digraph
|
|
94
110
|
|
|
95
111
|
# The digraph that is being built.
|
|
96
|
-
attr_reader :digraph
|
|
112
|
+
attr_reader :digraph #: Digraph
|
|
97
113
|
|
|
98
114
|
# Initialize a new dot visitor.
|
|
115
|
+
#
|
|
116
|
+
#: () -> void
|
|
99
117
|
def initialize
|
|
100
118
|
@digraph = Digraph.new
|
|
101
119
|
end
|
|
102
120
|
|
|
103
121
|
# Convert this visitor into a graphviz dot graph string.
|
|
122
|
+
#
|
|
123
|
+
#: () -> String
|
|
104
124
|
def to_dot
|
|
105
125
|
digraph.to_dot
|
|
106
126
|
end
|
|
107
127
|
<%- nodes.each do |node| -%>
|
|
108
128
|
|
|
109
|
-
|
|
110
|
-
def visit_<%= node.human %>(node)
|
|
129
|
+
#: (<%= node.name %>) -> void
|
|
130
|
+
def visit_<%= node.human %>(node) # :nodoc:
|
|
111
131
|
table = Table.new("<%= node.name %>")
|
|
112
132
|
id = node_id(node)
|
|
113
133
|
<%- if (node_flags = node.flags) -%>
|
|
@@ -152,7 +172,7 @@ module Prism
|
|
|
152
172
|
<%- end -%>
|
|
153
173
|
<%- end -%>
|
|
154
174
|
|
|
155
|
-
digraph.
|
|
175
|
+
digraph.node(<<~DOT)
|
|
156
176
|
#{id} [
|
|
157
177
|
label=<#{table.to_dot.gsub(/\n/, "\n ")}>
|
|
158
178
|
];
|
|
@@ -165,19 +185,25 @@ module Prism
|
|
|
165
185
|
private
|
|
166
186
|
|
|
167
187
|
# Generate a unique node ID for a node throughout the digraph.
|
|
168
|
-
|
|
188
|
+
#
|
|
189
|
+
#: (node) -> String
|
|
190
|
+
def node_id(node) # :nodoc:
|
|
169
191
|
"Node_#{node.object_id}"
|
|
170
192
|
end
|
|
171
193
|
|
|
172
|
-
# Inspect a location to display the start and end line and
|
|
173
|
-
|
|
194
|
+
# Inspect a location to display the start and end line and columns in bytes.
|
|
195
|
+
#
|
|
196
|
+
#: (Location) -> String
|
|
197
|
+
def location_inspect(location) # :nodoc:
|
|
174
198
|
"(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column})"
|
|
175
199
|
end
|
|
176
200
|
<%- flags.each do |flag| -%>
|
|
177
201
|
|
|
178
202
|
# Inspect a node that has <%= flag.human %> flags to display the flags as a
|
|
179
203
|
# comma-separated list.
|
|
180
|
-
|
|
204
|
+
#
|
|
205
|
+
#: (<%= nodes.filter_map { |node| node.name if node.flags == flag }.join(" | ") %> node) -> String
|
|
206
|
+
def <%= flag.human %>_inspect(node) # :nodoc:
|
|
181
207
|
flags = [] #: Array[String]
|
|
182
208
|
<%- flag.values.each do |value| -%>
|
|
183
209
|
flags << "<%= value.name.downcase %>" if node.<%= value.name.downcase %>?
|
|
@@ -1,8 +1,11 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
1
4
|
module Prism
|
|
2
5
|
# The DSL module provides a set of methods that can be used to create prism
|
|
3
6
|
# nodes in a more concise manner. For example, instead of writing:
|
|
4
7
|
#
|
|
5
|
-
# source = Prism::Source.for("[1]")
|
|
8
|
+
# source = Prism::Source.for("[1]", 1, [0])
|
|
6
9
|
#
|
|
7
10
|
# Prism::ArrayNode.new(
|
|
8
11
|
# source,
|
|
@@ -56,17 +59,31 @@ module Prism
|
|
|
56
59
|
extend self
|
|
57
60
|
|
|
58
61
|
# Create a new Source object.
|
|
62
|
+
#
|
|
63
|
+
#: (String string) -> Source
|
|
59
64
|
def source(string)
|
|
60
|
-
Source.for(string)
|
|
65
|
+
Source.for(string, 1, build_offsets(string))
|
|
61
66
|
end
|
|
62
67
|
|
|
63
68
|
# Create a new Location object.
|
|
69
|
+
#
|
|
70
|
+
#: (?source: Source, ?start_offset: Integer, ?length: Integer) -> Location
|
|
64
71
|
def location(source: default_source, start_offset: 0, length: 0)
|
|
65
72
|
Location.new(source, start_offset, length)
|
|
66
73
|
end
|
|
67
74
|
<%- nodes.each do |node| -%>
|
|
75
|
+
<%-
|
|
76
|
+
params = [
|
|
77
|
+
["source", "Source"],
|
|
78
|
+
["node_id", "Integer"],
|
|
79
|
+
["location", "Location"],
|
|
80
|
+
["flags", "Integer"]
|
|
81
|
+
].concat(node.fields.map { |field| [field.name, field.rbs_class] })
|
|
82
|
+
-%>
|
|
68
83
|
|
|
69
84
|
# Create a new <%= node.name %> node.
|
|
85
|
+
#
|
|
86
|
+
#: (<%= params.map { |(name, type)| "?#{name}: #{type}" }.join(", ") %>) -> <%= node.name %>
|
|
70
87
|
def <%= node.human %>(<%= ["source: default_source", "node_id: 0", "location: default_location", "flags: 0", *node.fields.map { |field|
|
|
71
88
|
case field
|
|
72
89
|
when Prism::Template::NodeField
|
|
@@ -100,6 +117,8 @@ module Prism
|
|
|
100
117
|
<%- flags.each do |flag| -%>
|
|
101
118
|
|
|
102
119
|
# Retrieve the value of one of the <%= flag.name %> flags.
|
|
120
|
+
#
|
|
121
|
+
#: (Symbol name) -> Integer
|
|
103
122
|
def <%= flag.human.chomp("s") %>(name)
|
|
104
123
|
case name
|
|
105
124
|
<%- flag.values.each do |value| -%>
|
|
@@ -114,20 +133,40 @@ module Prism
|
|
|
114
133
|
|
|
115
134
|
# The default source object that gets attached to nodes and locations if no
|
|
116
135
|
# source is specified.
|
|
136
|
+
#
|
|
137
|
+
#: () -> Source
|
|
117
138
|
def default_source
|
|
118
|
-
Source.for("")
|
|
139
|
+
Source.for("", 1, [0])
|
|
119
140
|
end
|
|
120
141
|
|
|
121
142
|
# The default location object that gets attached to nodes if no location is
|
|
122
143
|
# specified, which uses the given source.
|
|
144
|
+
#
|
|
145
|
+
#: () -> Location
|
|
123
146
|
def default_location
|
|
124
147
|
Location.new(default_source, 0, 0)
|
|
125
148
|
end
|
|
126
149
|
|
|
127
150
|
# The default node that gets attached to nodes if no node is specified for a
|
|
128
151
|
# required node field.
|
|
152
|
+
#
|
|
153
|
+
#: (Source source, Location location) -> node
|
|
129
154
|
def default_node(source, location)
|
|
130
|
-
|
|
155
|
+
ErrorRecoveryNode.new(source, -1, location, 0, nil)
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
private
|
|
159
|
+
|
|
160
|
+
# Build the newline byte offset array for the given source string.
|
|
161
|
+
#
|
|
162
|
+
#: (String source) -> Array[Integer]
|
|
163
|
+
def build_offsets(source)
|
|
164
|
+
offsets = [0]
|
|
165
|
+
start = 0
|
|
166
|
+
while (index = source.byteindex("\n", start))
|
|
167
|
+
offsets << (start = index + 1)
|
|
168
|
+
end
|
|
169
|
+
offsets
|
|
131
170
|
end
|
|
132
171
|
end
|
|
133
172
|
end
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
1
4
|
module Prism
|
|
2
5
|
# This visitor is responsible for composing the strings that get returned by
|
|
3
6
|
# the various #inspect methods defined on each of the nodes.
|
|
@@ -7,8 +10,9 @@ module Prism
|
|
|
7
10
|
# when we hit an element in that list. In this case, we have a special
|
|
8
11
|
# command that replaces the subsequent indent with the given value.
|
|
9
12
|
class Replace # :nodoc:
|
|
10
|
-
attr_reader :value
|
|
13
|
+
attr_reader :value #: String
|
|
11
14
|
|
|
15
|
+
#: (String value) -> void
|
|
12
16
|
def initialize(value)
|
|
13
17
|
@value = value
|
|
14
18
|
end
|
|
@@ -17,19 +21,25 @@ module Prism
|
|
|
17
21
|
private_constant :Replace
|
|
18
22
|
|
|
19
23
|
# The current prefix string.
|
|
20
|
-
|
|
24
|
+
# :stopdoc:
|
|
25
|
+
attr_reader :indent #: String
|
|
26
|
+
# :startdoc:
|
|
21
27
|
|
|
22
28
|
# The list of commands that we need to execute in order to compose the
|
|
23
29
|
# final string.
|
|
24
|
-
|
|
30
|
+
#: stopdoc:
|
|
31
|
+
attr_reader :commands #: Array[[String | node | Replace, String]]
|
|
32
|
+
# :startdoc:
|
|
25
33
|
|
|
26
|
-
|
|
27
|
-
def initialize(indent = +"")
|
|
34
|
+
#: (?String indent) -> void
|
|
35
|
+
def initialize(indent = +"") # :nodoc:
|
|
28
36
|
@indent = indent
|
|
29
37
|
@commands = []
|
|
30
38
|
end
|
|
31
39
|
|
|
32
40
|
# Compose an inspect string for the given node.
|
|
41
|
+
#
|
|
42
|
+
#: (node node) -> String
|
|
33
43
|
def self.compose(node)
|
|
34
44
|
visitor = new
|
|
35
45
|
node.accept(visitor)
|
|
@@ -37,7 +47,9 @@ module Prism
|
|
|
37
47
|
end
|
|
38
48
|
|
|
39
49
|
# Compose the final string.
|
|
40
|
-
|
|
50
|
+
#
|
|
51
|
+
#: () -> String
|
|
52
|
+
def compose # :nodoc:
|
|
41
53
|
buffer = +""
|
|
42
54
|
replace = nil
|
|
43
55
|
|
|
@@ -66,8 +78,8 @@ module Prism
|
|
|
66
78
|
end
|
|
67
79
|
<%- nodes.each do |node| -%>
|
|
68
80
|
|
|
69
|
-
|
|
70
|
-
def visit_<%= node.human %>(node)
|
|
81
|
+
#: (<%= node.name %> node) -> void
|
|
82
|
+
def visit_<%= node.human %>(node) # :nodoc:
|
|
71
83
|
commands << [inspect_node(<%= node.name.inspect %>, node), indent]
|
|
72
84
|
<%- (fields = [node.flags || Prism::Template::Flags.empty, *node.fields]).each_with_index do |field, index| -%>
|
|
73
85
|
<%- pointer = index == fields.length - 1 ? "└── " : "├── " -%>
|
|
@@ -114,13 +126,17 @@ module Prism
|
|
|
114
126
|
private
|
|
115
127
|
|
|
116
128
|
# Compose a header for the given node.
|
|
117
|
-
|
|
129
|
+
#
|
|
130
|
+
#: (String name, node node) -> String
|
|
131
|
+
def inspect_node(name, node) # :nodoc:
|
|
118
132
|
location = node.location
|
|
119
133
|
"@ #{name} (location: (#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column}))\n"
|
|
120
134
|
end
|
|
121
135
|
|
|
122
136
|
# Compose a string representing the given inner location field.
|
|
123
|
-
|
|
137
|
+
#
|
|
138
|
+
#: (Location? location) -> String
|
|
139
|
+
def inspect_location(location) # :nodoc:
|
|
124
140
|
if location
|
|
125
141
|
"(#{location.start_line},#{location.start_column})-(#{location.end_line},#{location.end_column}) = #{location.slice.inspect}"
|
|
126
142
|
else
|
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
#--
|
|
2
|
+
# rbs_inline: enabled
|
|
3
|
+
|
|
1
4
|
module Prism
|
|
2
5
|
# This visitor walks through the tree and copies each node as it is being
|
|
3
6
|
# visited. This is useful for consumers that want to mutate the tree, as you
|
|
@@ -5,8 +8,8 @@ module Prism
|
|
|
5
8
|
class MutationCompiler < Compiler
|
|
6
9
|
<%- nodes.each_with_index do |node, index| -%>
|
|
7
10
|
<%= "\n" if index != 0 -%>
|
|
8
|
-
|
|
9
|
-
def visit_<%= node.human %>(node)
|
|
11
|
+
#: (<%= node.name %>) -> node?
|
|
12
|
+
def visit_<%= node.human %>(node) # :nodoc:
|
|
10
13
|
<%- fields = node.fields.select { |field| [Prism::Template::NodeField, Prism::Template::OptionalNodeField, Prism::Template::NodeListField].include?(field.class) } -%>
|
|
11
14
|
<%- if fields.any? -%>
|
|
12
15
|
node.copy(<%= fields.map { |field| "#{field.name}: #{field.is_a?(Prism::Template::NodeListField) ? "visit_all" : "visit"}(node.#{field.name})" }.join(", ") %>)
|