summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/prism/node_ext.rb12
-rw-r--r--lib/prism/parse_result/newlines.rb56
-rw-r--r--prism/config.yml148
-rw-r--r--prism/templates/ext/prism/api_node.c.erb14
-rw-r--r--prism/templates/include/prism/ast.h.erb18
-rw-r--r--prism/templates/lib/prism/dot_visitor.rb.erb8
-rw-r--r--prism/templates/lib/prism/dsl.rb.erb6
-rw-r--r--prism/templates/lib/prism/inspect_visitor.rb.erb13
-rw-r--r--prism/templates/lib/prism/node.rb.erb70
-rw-r--r--prism/templates/lib/prism/reflection.rb.erb7
-rw-r--r--prism/templates/lib/prism/serialize.rb.erb8
-rw-r--r--prism/templates/src/node.c.erb13
-rw-r--r--prism/templates/src/prettyprint.c.erb13
-rw-r--r--prism/templates/src/serialize.c.erb3
-rwxr-xr-xprism/templates/template.rb36
-rw-r--r--test/prism/newline_test.rb2
-rw-r--r--test/prism/result/integer_base_flags_test.rb4
-rw-r--r--test/prism/snapshots/integer_operations.txt8
-rw-r--r--test/prism/snapshots/ranges.txt8
-rw-r--r--test/prism/snapshots/seattlerb/call_gt.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_lt.txt2
-rw-r--r--test/prism/snapshots/seattlerb/call_lte.txt2
-rw-r--r--test/prism/snapshots/whitequark/send_binary_op.txt8
23 files changed, 197 insertions, 264 deletions
diff --git a/lib/prism/node_ext.rb b/lib/prism/node_ext.rb
index fe36be8541..30ab652384 100644
--- a/lib/prism/node_ext.rb
+++ b/lib/prism/node_ext.rb
@@ -21,7 +21,10 @@ module Prism
# Returns a numeric value that represents the flags that were used to create
# the regular expression.
def options
- o = flags & (RegularExpressionFlags::IGNORE_CASE | RegularExpressionFlags::EXTENDED | RegularExpressionFlags::MULTI_LINE)
+ o = 0
+ o |= Regexp::IGNORECASE if flags.anybits?(RegularExpressionFlags::IGNORE_CASE)
+ o |= Regexp::EXTENDED if flags.anybits?(RegularExpressionFlags::EXTENDED)
+ o |= Regexp::MULTILINE if flags.anybits?(RegularExpressionFlags::MULTI_LINE)
o |= Regexp::FIXEDENCODING if flags.anybits?(RegularExpressionFlags::EUC_JP | RegularExpressionFlags::WINDOWS_31J | RegularExpressionFlags::UTF_8)
o |= Regexp::NOENCODING if flags.anybits?(RegularExpressionFlags::ASCII_8BIT)
o
@@ -87,6 +90,7 @@ module Prism
InterpolatedXStringNode.new(
source,
location,
+ flags,
opening_loc,
[StringNode.new(source, content_loc, 0, nil, content_loc, nil, unescaped)],
closing_loc
@@ -117,7 +121,7 @@ module Prism
if denominator == 1
IntegerNode.new(source, location.chop, flags, numerator)
else
- FloatNode.new(source, location.chop, numerator.to_f / denominator)
+ FloatNode.new(source, location.chop, 0, numerator.to_f / denominator)
end
end
end
@@ -195,7 +199,7 @@ module Prism
# continue to supply that API.
def child
deprecated("name", "name_loc")
- name ? ConstantReadNode.new(source, name_loc, name) : MissingNode.new(source, location)
+ name ? ConstantReadNode.new(source, name_loc, 0, name) : MissingNode.new(source, location, 0)
end
end
@@ -231,7 +235,7 @@ module Prism
# continue to supply that API.
def child
deprecated("name", "name_loc")
- name ? ConstantReadNode.new(source, name_loc, name) : MissingNode.new(source, location)
+ name ? ConstantReadNode.new(source, name_loc, 0, name) : MissingNode.new(source, location, 0)
end
end
diff --git a/lib/prism/parse_result/newlines.rb b/lib/prism/parse_result/newlines.rb
index 808a129a6b..a04fa78a75 100644
--- a/lib/prism/parse_result/newlines.rb
+++ b/lib/prism/parse_result/newlines.rb
@@ -45,7 +45,7 @@ module Prism
# Mark if/unless nodes as newlines.
def visit_if_node(node)
- node.newline!(@lines)
+ node.newline_flag!(@lines)
super(node)
end
@@ -54,7 +54,7 @@ module Prism
# Permit statements lists to mark newlines within themselves.
def visit_statements_node(node)
node.body.each do |child|
- child.newline!(@lines)
+ child.newline_flag!(@lines)
end
super(node)
end
@@ -62,93 +62,93 @@ module Prism
end
class Node
- def newline? # :nodoc:
- @newline ? true : false
+ def newline_flag? # :nodoc:
+ @newline_flag ? true : false
end
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
line = location.start_line
unless lines[line]
lines[line] = true
- @newline = true
+ @newline_flag = true
end
end
end
class BeginNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
# Never mark BeginNode with a newline flag, mark children instead.
end
end
class ParenthesesNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
# Never mark ParenthesesNode with a newline flag, mark children instead.
end
end
class IfNode < Node
- def newline!(lines) # :nodoc:
- predicate.newline!(lines)
+ def newline_flag!(lines) # :nodoc:
+ predicate.newline_flag!(lines)
end
end
class UnlessNode < Node
- def newline!(lines) # :nodoc:
- predicate.newline!(lines)
+ def newline_flag!(lines) # :nodoc:
+ predicate.newline_flag!(lines)
end
end
class UntilNode < Node
- def newline!(lines) # :nodoc:
- predicate.newline!(lines)
+ def newline_flag!(lines) # :nodoc:
+ predicate.newline_flag!(lines)
end
end
class WhileNode < Node
- def newline!(lines) # :nodoc:
- predicate.newline!(lines)
+ def newline_flag!(lines) # :nodoc:
+ predicate.newline_flag!(lines)
end
end
class RescueModifierNode < Node
- def newline!(lines) # :nodoc:
- expression.newline!(lines)
+ def newline_flag!(lines) # :nodoc:
+ expression.newline_flag!(lines)
end
end
class InterpolatedMatchLastLineNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
first = parts.first
- first.newline!(lines) if first
+ first.newline_flag!(lines) if first
end
end
class InterpolatedRegularExpressionNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
first = parts.first
- first.newline!(lines) if first
+ first.newline_flag!(lines) if first
end
end
class InterpolatedStringNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
first = parts.first
- first.newline!(lines) if first
+ first.newline_flag!(lines) if first
end
end
class InterpolatedSymbolNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
first = parts.first
- first.newline!(lines) if first
+ first.newline_flag!(lines) if first
end
end
class InterpolatedXStringNode < Node
- def newline!(lines) # :nodoc:
+ def newline_flag!(lines) # :nodoc:
first = parts.first
- first.newline!(lines) if first
+ first.newline_flag!(lines) if first
end
end
end
diff --git a/prism/config.yml b/prism/config.yml
index 9001b388ee..52c3982261 100644
--- a/prism/config.yml
+++ b/prism/config.yml
@@ -858,10 +858,8 @@ nodes:
left and right
^^^^^^^^^^^^^^
- name: ArgumentsNode
+ flags: ArgumentsNodeFlags
fields:
- - name: flags
- type: flags
- kind: ArgumentsNodeFlags
- name: arguments
type: node[]
comment: |
@@ -870,10 +868,8 @@ nodes:
return foo, bar, baz
^^^^^^^^^^^^^
- name: ArrayNode
+ flags: ArrayNodeFlags
fields:
- - name: flags
- type: flags
- kind: ArrayNodeFlags
- name: elements
type: node[]
comment: Represent the list of zero or more [non-void expressions](https://github.com/ruby/prism/blob/main/docs/parsing_rules.md#non-void-expression) within the array.
@@ -1042,10 +1038,8 @@ nodes:
bar(&args)
^^^^^^^^^^
- name: BlockLocalVariableNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant
comment: |
@@ -1071,10 +1065,8 @@ nodes:
[1, 2, 3].each { |i| puts x }
^^^^^^^^^^^^^^
- name: BlockParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant?
- name: name_loc
@@ -1131,10 +1123,8 @@ nodes:
break foo
^^^^^^^^^
- name: CallAndWriteNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
- name: call_operator_loc
@@ -1155,10 +1145,8 @@ nodes:
foo.bar &&= value
^^^^^^^^^^^^^^^^^
- name: CallNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
comment: |
@@ -1208,10 +1196,8 @@ nodes:
foo&.bar
^^^^^^^^
- name: CallOperatorWriteNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
- name: call_operator_loc
@@ -1234,10 +1220,8 @@ nodes:
foo.bar += baz
^^^^^^^^^^^^^^
- name: CallOrWriteNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
- name: call_operator_loc
@@ -1258,10 +1242,8 @@ nodes:
foo.bar ||= value
^^^^^^^^^^^^^^^^^
- name: CallTargetNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node
- name: call_operator_loc
@@ -1856,10 +1838,8 @@ nodes:
foo in Foo(*bar, baz, *qux)
^^^^^^^^^^^^^^^^^^^^
- name: FlipFlopNode
+ flags: RangeFlags
fields:
- - name: flags
- type: flags
- kind: RangeFlags
- name: left
type: node?
- name: right
@@ -2278,10 +2258,8 @@ nodes:
case a; in b then c end
^^^^^^^^^^^
- name: IndexAndWriteNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
- name: call_operator_loc
@@ -2305,10 +2283,8 @@ nodes:
foo.bar[baz] &&= value
^^^^^^^^^^^^^^^^^^^^^^
- name: IndexOperatorWriteNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
- name: call_operator_loc
@@ -2334,10 +2310,8 @@ nodes:
foo.bar[baz] += value
^^^^^^^^^^^^^^^^^^^^^
- name: IndexOrWriteNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node?
- name: call_operator_loc
@@ -2361,10 +2335,8 @@ nodes:
foo.bar[baz] ||= value
^^^^^^^^^^^^^^^^^^^^^^
- name: IndexTargetNode
+ flags: CallNodeFlags
fields:
- - name: flags
- type: flags
- kind: CallNodeFlags
- name: receiver
type: node
- name: opening_loc
@@ -2500,10 +2472,8 @@ nodes:
@foo = 1
^^^^^^^^
- name: IntegerNode
+ flags: IntegerBaseFlags
fields:
- - name: flags
- type: flags
- kind: IntegerBaseFlags
- name: value
type: integer
comment: The value of the integer literal as a number.
@@ -2513,10 +2483,8 @@ nodes:
1
^
- name: InterpolatedMatchLastLineNode
+ flags: RegularExpressionFlags
fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- name: opening_loc
type: location
- name: parts
@@ -2534,10 +2502,8 @@ nodes:
if /foo #{bar} baz/ then end
^^^^^^^^^^^^^^^^
- name: InterpolatedRegularExpressionNode
+ flags: RegularExpressionFlags
fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- name: opening_loc
type: location
- name: parts
@@ -2555,10 +2521,8 @@ nodes:
/foo #{bar} baz/
^^^^^^^^^^^^^^^^
- name: InterpolatedStringNode
+ flags: InterpolatedStringNodeFlags
fields:
- - name: flags
- type: flags
- kind: InterpolatedStringNodeFlags
- name: opening_loc
type: location?
- name: parts
@@ -2625,10 +2589,8 @@ nodes:
-> { it + it }
^^^^^^^^^^^^^^
- name: KeywordHashNode
+ flags: KeywordHashNodeFlags
fields:
- - name: flags
- type: flags
- kind: KeywordHashNodeFlags
- name: elements
type: node[]
kind:
@@ -2640,10 +2602,8 @@ nodes:
foo(a: b)
^^^^
- name: KeywordRestParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant?
- name: name_loc
@@ -2823,10 +2783,8 @@ nodes:
foo = 1
^^^^^^^
- name: MatchLastLineNode
+ flags: RegularExpressionFlags
fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- name: opening_loc
type: location
- name: content_loc
@@ -3142,10 +3100,8 @@ nodes:
$1
^^
- name: OptionalKeywordParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant
- name: name_loc
@@ -3159,10 +3115,8 @@ nodes:
^^^^
end
- name: OptionalParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant
- name: name_loc
@@ -3337,10 +3291,8 @@ nodes:
kind: StatementsNode
comment: The top level node of any parse tree.
- name: RangeNode
+ flags: RangeFlags
fields:
- - name: flags
- type: flags
- kind: RangeFlags
- name: left
type: node?
comment: |
@@ -3375,10 +3327,8 @@ nodes:
c if a =~ /left/ ... b =~ /right/
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- name: RationalNode
+ flags: IntegerBaseFlags
fields:
- - name: flags
- type: flags
- kind: IntegerBaseFlags
- name: numerator
type: integer
comment: |
@@ -3403,10 +3353,8 @@ nodes:
redo
^^^^
- name: RegularExpressionNode
+ flags: RegularExpressionFlags
fields:
- - name: flags
- type: flags
- kind: RegularExpressionFlags
- name: opening_loc
type: location
- name: content_loc
@@ -3421,10 +3369,8 @@ nodes:
/foo/i
^^^^^^
- name: RequiredKeywordParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant
- name: name_loc
@@ -3436,10 +3382,8 @@ nodes:
^^
end
- name: RequiredParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant
comment: |
@@ -3489,10 +3433,8 @@ nodes:
`Foo, *splat, Bar` are in the `exceptions` field. `ex` is in the `exception` field.
- name: RestParameterNode
+ flags: ParameterFlags
fields:
- - name: flags
- type: flags
- kind: ParameterFlags
- name: name
type: constant?
- name: name_loc
@@ -3512,10 +3454,8 @@ nodes:
retry
^^^^^
- name: ReturnNode
+ flags: ReturnNodeFlags
fields:
- - name: flags
- type: flags
- kind: ReturnNodeFlags
- name: keyword_loc
type: location
- name: arguments
@@ -3533,10 +3473,8 @@ nodes:
self
^^^^
- name: ShareableConstantNode
+ flags: ShareableConstantNodeFlags
fields:
- - name: flags
- type: flags
- kind: ShareableConstantNodeFlags
- name: write
type: node
kind:
@@ -3581,10 +3519,8 @@ nodes:
__ENCODING__
^^^^^^^^^^^^
- name: SourceFileNode
+ flags: StringFlags
fields:
- - name: flags
- type: flags
- kind: StringFlags
- name: filepath
type: string
comment: Represents the file path being parsed. This corresponds directly to the `filepath` option given to the various `Prism::parse*` APIs.
@@ -3620,10 +3556,8 @@ nodes:
foo; bar; baz
^^^^^^^^^^^^^
- name: StringNode
+ flags: StringFlags
fields:
- - name: flags
- type: flags
- kind: StringFlags
- name: opening_loc
type: location?
- name: content_loc
@@ -3665,10 +3599,8 @@ nodes:
super foo, bar
^^^^^^^^^^^^^^
- name: SymbolNode
+ flags: SymbolFlags
fields:
- - name: flags
- type: flags
- kind: SymbolFlags
- name: opening_loc
type: location?
- name: value_loc
@@ -3768,10 +3700,8 @@ nodes:
unless foo then bar end
^^^^^^^^^^^^^^^^^^^^^^^
- name: UntilNode
+ flags: LoopFlags
fields:
- - name: flags
- type: flags
- kind: LoopFlags
- name: keyword_loc
type: location
- name: closing_loc
@@ -3809,10 +3739,8 @@ nodes:
^^^^^^^^^
end
- name: WhileNode
+ flags: LoopFlags
fields:
- - name: flags
- type: flags
- kind: LoopFlags
- name: keyword_loc
type: location
- name: closing_loc
@@ -3832,10 +3760,8 @@ nodes:
while foo do bar end
^^^^^^^^^^^^^^^^^^^^
- name: XStringNode
+ flags: EncodingFlags
fields:
- - name: flags
- type: flags
- kind: EncodingFlags
- name: opening_loc
type: location
- name: content_loc
diff --git a/prism/templates/ext/prism/api_node.c.erb b/prism/templates/ext/prism/api_node.c.erb
index 258c61f319..a5086d5bca 100644
--- a/prism/templates/ext/prism/api_node.c.erb
+++ b/prism/templates/ext/prism/api_node.c.erb
@@ -170,17 +170,20 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
<%- nodes.each do |node| -%>
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
case <%= node.type %>: {
- <%- if node.fields.any? { |field| ![Prism::Template::NodeField, Prism::Template::OptionalNodeField, Prism::Template::FlagsField].include?(field.class) } -%>
+ <%- if node.fields.any? { |field| ![Prism::Template::NodeField, Prism::Template::OptionalNodeField].include?(field.class) } -%>
pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
<%- end -%>
- VALUE argv[<%= node.fields.length + 2 %>];
+ VALUE argv[<%= node.fields.length + 3 %>];
// source
argv[0] = source;
// location
argv[1] = pm_location_new(parser, node->location.start, node->location.end);
- <%- node.fields.each.with_index(2) do |field, index| -%>
+
+ // flags
+ argv[2] = ULONG2NUM(node->flags);
+ <%- node.fields.each.with_index(3) do |field, index| -%>
// <%= field.name %>
<%- case field -%>
@@ -221,9 +224,6 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
<%- when Prism::Template::UInt32Field -%>
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
argv[<%= index %>] = ULONG2NUM(cast-><%= field.name %>);
- <%- when Prism::Template::FlagsField -%>
-#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
- argv[<%= index %>] = ULONG2NUM(node->flags & ~PM_NODE_FLAG_COMMON_MASK);
<%- when Prism::Template::IntegerField -%>
#line <%= __LINE__ + 1 %> "prism/templates/ext/prism/<%= File.basename(__FILE__) %>"
argv[<%= index %>] = pm_integer_new(&cast-><%= field.name %>);
@@ -235,7 +235,7 @@ pm_ast_new(const pm_parser_t *parser, const pm_node_t *node, rb_encoding *encodi
<%- end -%>
<%- end -%>
- rb_ary_push(value_stack, rb_class_new_instance(<%= node.fields.length + 2 %>, argv, rb_cPrism<%= node.name %>));
+ rb_ary_push(value_stack, rb_class_new_instance(<%= node.fields.length + 3 %>, argv, rb_cPrism<%= node.name %>));
break;
}
<%- end -%>
diff --git a/prism/templates/include/prism/ast.h.erb b/prism/templates/include/prism/ast.h.erb
index 0fe7905e40..585e3f4058 100644
--- a/prism/templates/include/prism/ast.h.erb
+++ b/prism/templates/include/prism/ast.h.erb
@@ -100,11 +100,8 @@ typedef uint16_t pm_node_flags_t;
* We store the flags enum in every node in the tree. Some flags are common to
* all nodes (the ones listed below). Others are specific to certain node types.
*/
-#define PM_NODE_FLAG_BITS (sizeof(pm_node_flags_t) * 8)
-
-static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = (1 << (PM_NODE_FLAG_BITS - 1));
-static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = (1 << (PM_NODE_FLAG_BITS - 2));
-static const pm_node_flags_t PM_NODE_FLAG_COMMON_MASK = (1 << (PM_NODE_FLAG_BITS - 1)) | (1 << (PM_NODE_FLAG_BITS - 2));
+static const pm_node_flags_t PM_NODE_FLAG_NEWLINE = 0x1;
+static const pm_node_flags_t PM_NODE_FLAG_STATIC_LITERAL = 0x2;
/**
* Cast the type to an enum to allow the compiler to provide exhaustiveness
@@ -151,11 +148,10 @@ typedef struct pm_node {
* <%= node.name %>
*
* Type: <%= node.type %>
-<%- if (node_flags = node.fields.find { |field| field.is_a? Prism::Template::FlagsField }) -%>
+<%- if (node_flags = node.flags) -%>
* Flags:
-<%- found = flags.find { |flag| flag.name == node_flags.kind }.tap { |found| raise "Expected to find #{field.kind}" unless found } -%>
-<%- found.values.each do |value| -%>
- * PM_<%= found.human.upcase %>_<%= value.name %>
+<%- node_flags.values.each do |value| -%>
+ * PM_<%= node_flags.human.upcase %>_<%= value.name %>
<%- end -%>
<%- end -%>
*
@@ -164,7 +160,7 @@ typedef struct pm_node {
typedef struct pm_<%= node.human %> {
/** The embedded base node. */
pm_node_t base;
-<%- node.fields.grep_v(Prism::Template::FlagsField).each do |field| -%>
+<%- node.fields.each do |field| -%>
/**
* <%= node.name %>#<%= field.name %>
@@ -201,7 +197,7 @@ typedef enum pm_<%= flag.human %> {
<%- flag.values.each_with_index do |value, index| -%>
<%= "\n" if index > 0 -%>
/** <%= value.comment %> */
- PM_<%= flag.human.upcase %>_<%= value.name %> = <%= 1 << index %>,
+ PM_<%= flag.human.upcase %>_<%= value.name %> = <%= 1 << (index + 2) %>,
<%- end -%>
} pm_<%= flag.human %>_t;
<%- end -%>
diff --git a/prism/templates/lib/prism/dot_visitor.rb.erb b/prism/templates/lib/prism/dot_visitor.rb.erb
index 93c94b19ee..e9c81e4545 100644
--- a/prism/templates/lib/prism/dot_visitor.rb.erb
+++ b/prism/templates/lib/prism/dot_visitor.rb.erb
@@ -109,6 +109,11 @@ module Prism
def visit_<%= node.human %>(node)
table = Table.new("<%= node.name %>")
id = node_id(node)
+ <%- if (node_flags = node.flags) -%>
+
+ # flags
+ table.field("flags", <%= node_flags.human %>_inspect(node))
+ <%- end -%>
<%- node.fields.each do |field| -%>
# <%= field.name %>
@@ -141,9 +146,6 @@ module Prism
unless (<%= field.name %> = node.<%= field.name %>).nil?
table.field("<%= field.name %>", location_inspect(<%= field.name %>))
end
- <%- when Prism::Template::FlagsField -%>
- <%- flag = flags.find { |flag| flag.name == field.kind }.tap { |flag| raise "Expected to find #{field.kind}" unless flag } -%>
- table.field("<%= field.name %>", <%= flag.human %>_inspect(node))
<%- else -%>
<%- raise -%>
<%- end -%>
diff --git a/prism/templates/lib/prism/dsl.rb.erb b/prism/templates/lib/prism/dsl.rb.erb
index 4f61d71a2a..ec899f0b74 100644
--- a/prism/templates/lib/prism/dsl.rb.erb
+++ b/prism/templates/lib/prism/dsl.rb.erb
@@ -65,7 +65,7 @@ module Prism
<%- nodes.each do |node| -%>
# Create a new <%= node.name %> node.
- def <%= node.human %>(<%= ["source: default_source", "location: default_location", *node.fields.map { |field|
+ def <%= node.human %>(<%= ["source: default_source", "location: default_location", "flags: 0", *node.fields.map { |field|
case field
when Prism::Template::NodeField, Prism::Template::ConstantField
"#{field.name}: default_node(source, location)"
@@ -77,13 +77,13 @@ module Prism
"#{field.name}: \"\""
when Prism::Template::LocationField
"#{field.name}: location"
- when Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::FlagsField, Prism::Template::IntegerField, Prism::Template::DoubleField
+ when Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::IntegerField, Prism::Template::DoubleField
"#{field.name}: 0"
else
raise
end
}].join(", ") %>)
- <%= node.name %>.new(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>)
+ <%= node.name %>.new(<%= ["source", "location", "flags", *node.fields.map(&:name)].join(", ") %>)
end
<%- end -%>
<%- flags.each do |flag| -%>
diff --git a/prism/templates/lib/prism/inspect_visitor.rb.erb b/prism/templates/lib/prism/inspect_visitor.rb.erb
index 9328da636b..8b35b079c9 100644
--- a/prism/templates/lib/prism/inspect_visitor.rb.erb
+++ b/prism/templates/lib/prism/inspect_visitor.rb.erb
@@ -69,10 +69,13 @@ module Prism
# Inspect a <%= node.name %> node.
def visit_<%= node.human %>(node)
commands << [inspect_node(<%= node.name.inspect %>, node), indent]
- <%- node.fields.each_with_index do |field, index| -%>
- <%- pointer = index == node.fields.length - 1 ? "└── " : "├── " -%>
- <%- preadd = index == node.fields.length - 1 ? " " : "│ " -%>
+ <%- (fields = [*node.flags, *node.fields]).each_with_index do |field, index| -%>
+ <%- pointer = index == fields.length - 1 ? "└── " : "├── " -%>
+ <%- preadd = index == fields.length - 1 ? " " : "│ " -%>
<%- case field -%>
+ <%- when Prism::Template::Flags -%>
+ flags = [<%= field.values.map { |value| "(\"#{value.name.downcase}\" if node.#{value.name.downcase}?)" }.join(", ") %>].compact
+ commands << ["<%= pointer %>flags: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
<%- when Prism::Template::NodeListField -%>
commands << ["<%= pointer %><%= field.name %>: (length: #{(<%= field.name %> = node.<%= field.name %>).length})\n", indent]
if <%= field.name %>.any?
@@ -101,10 +104,6 @@ module Prism
else
commands << ["<%= pointer %><%= field.name %>: #{<%= field.name %>.inspect}\n", indent]
end
- <%- when Prism::Template::FlagsField -%>
- <%- flag = flags.find { |flag| flag.name == field.kind }.tap { |flag| raise unless flag } -%>
- flags = [<%= flag.values.map { |value| "(\"#{value.name.downcase}\" if node.#{value.name.downcase}?)" }.join(", ") %>].compact
- commands << ["<%= pointer %><%= field.name %>: #{flags.empty? ? "∅" : flags.join(", ")}\n", indent]
<%- when Prism::Template::LocationField, Prism::Template::OptionalLocationField -%>
commands << ["<%= pointer %><%= field.name %>: #{inspect_location(node.<%= field.name %>)}\n", indent]
<%- end -%>
diff --git a/prism/templates/lib/prism/node.rb.erb b/prism/templates/lib/prism/node.rb.erb
index 945b62fadb..ce166dda65 100644
--- a/prism/templates/lib/prism/node.rb.erb
+++ b/prism/templates/lib/prism/node.rb.erb
@@ -49,6 +49,21 @@ module Prism
location.slice_lines
end
+ # An bitset of flags for this node. There are certain flags that are common
+ # for all nodes, and then some nodes have specific flags.
+ attr_reader :flags
+ protected :flags
+
+ # Returns true if the node has the newline flag set.
+ def newline?
+ flags.anybits?(NodeFlags::NEWLINE)
+ end
+
+ # Returns true if the node has the static literal flag set.
+ def static_literal?
+ flags.anybits?(NodeFlags::STATIC_LITERAL)
+ end
+
# Similar to inspect, but respects the current level of indentation given by
# the pretty print object.
def pretty_print(q)
@@ -167,9 +182,10 @@ module Prism
<%- end -%>
class <%= node.name -%> < Node
# Initialize a new <%= node.name %> node.
- def initialize(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>)
+ def initialize(<%= ["source", "location", "flags", *node.fields.map(&:name)].join(", ") %>)
@source = source
@location = location
+ @flags = flags
<%- node.fields.each do |field| -%>
<%- if Prism::Template::CHECK_FIELD_KIND && field.respond_to?(:check_field_kind) -%>
raise <%= field.name %>.inspect unless <%= field.check_field_kind %>
@@ -228,9 +244,9 @@ module Prism
}.compact.join(", ") %>] #: Array[Prism::node | Location]
end
- # def copy: (<%= (["?location: Location"] + node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" }).join(", ") %>) -> <%= node.name %>
- def copy(<%= (["location"] + node.fields.map(&:name)).map { |field| "#{field}: self.#{field}" }.join(", ") %>)
- <%= node.name %>.new(<%= ["source", "location", *node.fields.map(&:name)].join(", ") %>)
+ # def copy: (<%= (["?location: Location", "?flags: Integer"] + node.fields.map { |field| "?#{field.name}: #{field.rbs_class}" }).join(", ") %>) -> <%= node.name %>
+ def copy(<%= (["location", "flags"] + node.fields.map(&:name)).map { |field| "#{field}: self.#{field}" }.join(", ") %>)
+ <%= node.name %>.new(<%= ["source", "location", "flags", *node.fields.map(&:name)].join(", ") %>)
end
# def deconstruct: () -> Array[nil | Node]
@@ -240,10 +256,19 @@ module Prism
def deconstruct_keys(keys)
{ <%= (node.fields.map { |field| "#{field.name}: #{field.name}" } + ["location: location"]).join(", ") %> }
end
+ <%- if (node_flags = node.flags) -%>
+ <%- node_flags.values.each do |value| -%>
+
+ # def <%= value.name.downcase %>?: () -> bool
+ def <%= value.name.downcase %>?
+ flags.anybits?(<%= node_flags.name %>::<%= value.name %>)
+ end
+ <%- end -%>
+ <%- end -%>
<%- node.fields.each do |field| -%>
<%- if field.comment.nil? -%>
- # <%= "protected " if field.is_a?(Prism::Template::FlagsField) %>attr_reader <%= field.name %>: <%= field.rbs_class %>
+ # attr_reader <%= field.name %>: <%= field.rbs_class %>
<%- else -%>
<%- field.each_comment_line do |line| -%>
#<%= line %>
@@ -269,7 +294,7 @@ module Prism
end
end
<%- else -%>
- attr_reader :<%= field.name -%><%= "\n protected :#{field.name}" if field.is_a?(Prism::Template::FlagsField) %>
+ attr_reader :<%= field.name -%>
<%- end -%>
<%- end -%>
<%- node.fields.each do |field| -%>
@@ -290,14 +315,6 @@ module Prism
def <%= field.name.delete_suffix("_loc") %>
<%= field.name %>&.slice
end
- <%- when Prism::Template::FlagsField -%>
- <%- flags.find { |flag| flag.name == field.kind }.tap { |flag| raise "Expected to find #{field.kind}" unless flag }.values.each do |value| -%>
-
- # def <%= value.name.downcase %>?: () -> bool
- def <%= value.name.downcase %>?
- <%= field.name %>.anybits?(<%= field.kind %>::<%= value.name %>)
- end
- <%- end -%>
<%- end -%>
<%- end -%>
@@ -337,15 +354,17 @@ module Prism
# Implements case-equality for the node. This is effectively == but without
# comparing the value of locations. Locations are checked only for presence.
def ===(other)
- other.is_a?(<%= node.name %>)<%= " &&" if node.fields.any? %>
- <%- node.fields.each_with_index do |field, index| -%>
+ other.is_a?(<%= node.name %>)<%= " &&" if (fields = [*node.flags, *node.fields]).any? %>
+ <%- fields.each_with_index do |field, index| -%>
<%- if field.is_a?(Prism::Template::LocationField) || field.is_a?(Prism::Template::OptionalLocationField) -%>
- (<%= field.name %>.nil? == other.<%= field.name %>.nil?)<%= " &&" if index != node.fields.length - 1 %>
+ (<%= field.name %>.nil? == other.<%= field.name %>.nil?)<%= " &&" if index != fields.length - 1 %>
<%- elsif field.is_a?(Prism::Template::NodeListField) || field.is_a?(Prism::Template::ConstantListField) -%>
(<%= field.name %>.length == other.<%= field.name %>.length) &&
- <%= field.name %>.zip(other.<%= field.name %>).all? { |left, right| left === right }<%= " &&" if index != node.fields.length - 1 %>
+ <%= field.name %>.zip(other.<%= field.name %>).all? { |left, right| left === right }<%= " &&" if index != fields.length - 1 %>
+ <%- elsif field.is_a?(Prism::Template::Flags) -%>
+ (flags === other.flags)<%= " &&" if index != fields.length - 1 %>
<%- else -%>
- (<%= field.name %> === other.<%= field.name %>)<%= " &&" if index != node.fields.length - 1 %>
+ (<%= field.name %> === other.<%= field.name %>)<%= " &&" if index != fields.length - 1 %>
<%- end -%>
<%- end -%>
end
@@ -357,9 +376,20 @@ module Prism
module <%= flag.name %>
<%- flag.values.each_with_index do |value, index| -%>
# <%= value.comment %>
- <%= value.name %> = 1 << <%= index %>
+ <%= value.name %> = 1 << <%= (index + 2) %>
<%= "\n" if value != flag.values.last -%>
<%- end -%>
end
<%- end -%>
+
+ # The flags that are common to all nodes.
+ module NodeFlags
+ # A flag to indicate that the node is a candidate to emit a :line event
+ # through tracepoint when compiled.
+ NEWLINE = 1
+
+ # A flag to indicate that the value that the node represents is a value that
+ # can be determined at parse-time.
+ STATIC_LITERAL = 2
+ end
end
diff --git a/prism/templates/lib/prism/reflection.rb.erb b/prism/templates/lib/prism/reflection.rb.erb
index 3c1d61c6c1..6c8b2f4d25 100644
--- a/prism/templates/lib/prism/reflection.rb.erb
+++ b/prism/templates/lib/prism/reflection.rb.erb
@@ -97,7 +97,7 @@ module Prism
case node.type
<%- nodes.each do |node| -%>
when :<%= node.human %>
- [<%= node.fields.map { |field|
+ [<%= [*node.flags, *node.fields].map { |field|
case field
when Prism::Template::NodeField
"NodeField.new(:#{field.name})"
@@ -121,9 +121,8 @@ module Prism
"IntegerField.new(:#{field.name})"
when Prism::Template::DoubleField
"FloatField.new(:#{field.name})"
- when Prism::Template::FlagsField
- found = flags.find { |flag| flag.name == field.kind }.tap { |found| raise "Expected to find #{field.kind}" unless found }
- "FlagsField.new(:#{field.name}, [#{found.values.map { |value| ":#{value.name.downcase}?" }.join(", ")}])"
+ when Prism::Template::Flags
+ "FlagsField.new(:flags, [#{field.values.map { |value| ":#{value.name.downcase}?" }.join(", ")}])"
else
raise field.class.name
end
diff --git a/prism/templates/lib/prism/serialize.rb.erb b/prism/templates/lib/prism/serialize.rb.erb
index 5532a7fd6a..cc16c09fe7 100644
--- a/prism/templates/lib/prism/serialize.rb.erb
+++ b/prism/templates/lib/prism/serialize.rb.erb
@@ -330,7 +330,7 @@ module Prism
<%- if node.needs_serialized_length? -%>
load_uint32
<%- end -%>
- <%= node.name %>.new(<%= ["source", "location", *node.fields.map { |field|
+ <%= node.name %>.new(<%= ["source", "location", "load_varuint", *node.fields.map { |field|
case field
when Prism::Template::NodeField then "load_node"
when Prism::Template::OptionalNodeField then "load_optional_node"
@@ -342,7 +342,7 @@ module Prism
when Prism::Template::LocationField then "load_location"
when Prism::Template::OptionalLocationField then "load_optional_location"
when Prism::Template::UInt8Field then "io.getbyte"
- when Prism::Template::UInt32Field, Prism::Template::FlagsField then "load_varuint"
+ when Prism::Template::UInt32Field then "load_varuint"
when Prism::Template::IntegerField then "load_integer"
when Prism::Template::DoubleField then "load_double"
else raise
@@ -366,7 +366,7 @@ module Prism
<%- if node.needs_serialized_length? -%>
load_uint32
<%- end -%>
- <%= node.name %>.new(<%= ["source", "location", *node.fields.map { |field|
+ <%= node.name %>.new(<%= ["source", "location", "load_varuint", *node.fields.map { |field|
case field
when Prism::Template::NodeField then "load_node"
when Prism::Template::OptionalNodeField then "load_optional_node"
@@ -378,7 +378,7 @@ module Prism
when Prism::Template::LocationField then "load_location"
when Prism::Template::OptionalLocationField then "load_optional_location"
when Prism::Template::UInt8Field then "io.getbyte"
- when Prism::Template::UInt32Field, Prism::Template::FlagsField then "load_varuint"
+ when Prism::Template::UInt32Field then "load_varuint"
when Prism::Template::IntegerField then "load_integer"
when Prism::Template::DoubleField then "load_double"
else raise
diff --git a/prism/templates/src/node.c.erb b/prism/templates/src/node.c.erb
index da30a96ec4..2357e55200 100644
--- a/prism/templates/src/node.c.erb
+++ b/prism/templates/src/node.c.erb
@@ -108,12 +108,12 @@ pm_node_destroy(pm_parser_t *parser, pm_node_t *node) {
<%- nodes.each do |node| -%>
#line <%= __LINE__ + 1 %> "prism/templates/src/<%= File.basename(__FILE__) %>"
case <%= node.type %>: {
- <%- if node.fields.any? { |field| ![Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::FlagsField, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField].include?(field.class) } -%>
+ <%- if node.fields.any? { |field| ![Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField].include?(field.class) } -%>
pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
<%- end -%>
<%- node.fields.each do |field| -%>
<%- case field -%>
- <%- when Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::FlagsField, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField -%>
+ <%- when Prism::Template::LocationField, Prism::Template::OptionalLocationField, Prism::Template::UInt8Field, Prism::Template::UInt32Field, Prism::Template::ConstantField, Prism::Template::OptionalConstantField, Prism::Template::DoubleField -%>
<%- when Prism::Template::NodeField -%>
pm_node_destroy(parser, (pm_node_t *)cast-><%= field.name %>);
<%- when Prism::Template::OptionalNodeField -%>
@@ -244,7 +244,7 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
const pm_<%= node.human %>_t *cast = (const pm_<%= node.human %>_t *) node;
pm_dump_json_location(buffer, parser, &cast->base.location);
- <%- node.fields.each_with_index do |field, index| -%>
+ <%- [*node.flags, *node.fields].each_with_index do |field, index| -%>
// Dump the <%= field.name %> field
pm_buffer_append_byte(buffer, ',');
@@ -301,12 +301,11 @@ pm_dump_json(pm_buffer_t *buffer, const pm_parser_t *parser, const pm_node_t *no
pm_buffer_append_format(buffer, "%" PRIu8, cast-><%= field.name %>);
<%- when Prism::Template::UInt32Field -%>
pm_buffer_append_format(buffer, "%" PRIu32, cast-><%= field.name %>);
- <%- when Prism::Template::FlagsField -%>
+ <%- when Prism::Template::Flags -%>
size_t flags = 0;
pm_buffer_append_byte(buffer, '[');
- <%- found = flags.find { |flag| flag.name == field.kind }.tap { |found| raise "Expected to find #{field.kind}" unless found } -%>
- <%- found.values.each_with_index do |value, index| -%>
- if (PM_NODE_FLAG_P(cast, PM_<%= found.human.upcase %>_<%= value.name %>)) {
+ <%- node.flags.values.each_with_index do |value, index| -%>
+ if (PM_NODE_FLAG_P(cast, PM_<%= node.flags.human.upcase %>_<%= value.name %>)) {
if (flags != 0) pm_buffer_append_byte(buffer, ',');
pm_buffer_append_string(buffer, "\"<%= value.name %>\"", <%= value.name.bytesize + 2 %>);
flags++;
diff --git a/prism/templates/src/prettyprint.c.erb b/prism/templates/src/prettyprint.c.erb
index 27f44cd996..639c2fecf3 100644
--- a/prism/templates/src/prettyprint.c.erb
+++ b/prism/templates/src/prettyprint.c.erb
@@ -31,14 +31,14 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
return;
<%- nodes.each do |node| -%>
case <%= node.type %>: {
- <%- if node.fields.any? -%>
+ <%- if !node.flags.nil? || node.fields.any? -%>
pm_<%= node.human %>_t *cast = (pm_<%= node.human %>_t *) node;
<%- end -%>
pm_buffer_append_string(output_buffer, "@ <%= node.name %> (location: ", <%= node.name.length + 14 %>);
prettyprint_location(output_buffer, parser, &node->location);
pm_buffer_append_string(output_buffer, ")\n", 2);
- <%- node.fields.each_with_index do |field, index| -%>
- <%- preadd = index == node.fields.length - 1 ? " " : "| " -%>
+ <%- (fields = [*node.flags, *node.fields]).each_with_index do |field, index| -%>
+ <%- preadd = index == fields.length - 1 ? " " : "| " -%>
// <%= field.name %>
{
@@ -123,11 +123,10 @@ prettyprint_node(pm_buffer_t *output_buffer, const pm_parser_t *parser, const pm
pm_buffer_append_format(output_buffer, " %" PRIu8 "\n", cast-><%= field.name %>);
<%- when Prism::Template::UInt32Field -%>
pm_buffer_append_format(output_buffer, " %" PRIu32 "\n", cast-><%= field.name %>);
- <%- when Prism::Template::FlagsField -%>
+ <%- when Prism::Template::Flags -%>
bool found = false;
- <%- found = flags.find { |flag| flag.name == field.kind }.tap { |found| raise "Expected to find #{field.kind}" unless found } -%>
- <%- found.values.each do |value| -%>
- if (cast->base.<%= field.name %> & PM_<%= found.human.upcase %>_<%= value.name %>) {
+ <%- field.values.each do |value| -%>
+ if (cast->base.flags & PM_<%= field.human.upcase %>_<%= value.name %>) {
if (found) pm_buffer_append_byte(output_buffer, ',');
pm_buffer_append_string(output_buffer, " <%= value.name.downcase %>", <%= value.name.bytesize + 1 %>);
found = true;
diff --git a/prism/templates/src/serialize.c.erb b/prism/templates/src/serialize.c.erb
index dd4b3fa5f0..9c3ddecf25 100644
--- a/prism/templates/src/serialize.c.erb
+++ b/prism/templates/src/serialize.c.erb
@@ -89,6 +89,7 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
size_t length_offset = buffer->length;
pm_buffer_append_string(buffer, "\0\0\0\0", 4); /* consume 4 bytes, updated below */
<%- end -%>
+ pm_buffer_append_varuint(buffer, (uint32_t) node->flags);
<%- node.fields.each do |field| -%>
<%- case field -%>
<%- when Prism::Template::NodeField -%>
@@ -132,8 +133,6 @@ pm_serialize_node(pm_parser_t *parser, pm_node_t *node, pm_buffer_t *buffer) {
pm_buffer_append_byte(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
<%- when Prism::Template::UInt32Field -%>
pm_buffer_append_varuint(buffer, ((pm_<%= node.human %>_t *)node)-><%= field.name %>);
- <%- when Prism::Template::FlagsField -%>
- pm_buffer_append_varuint(buffer, (uint32_t)(node->flags & ~PM_NODE_FLAG_COMMON_MASK));
<%- when Prism::Template::IntegerField -%>
pm_serialize_integer(&((pm_<%= node.human %>_t *)node)-><%= field.name %>, buffer);
<%- when Prism::Template::DoubleField -%>
diff --git a/prism/templates/template.rb b/prism/templates/template.rb
index 7a330f5e27..ba8013c9a3 100755
--- a/prism/templates/template.rb
+++ b/prism/templates/template.rb
@@ -357,27 +357,6 @@ module Prism
end
end
- # This represents a set of flags. It is very similar to the UInt32Field, but
- # can be directly embedded into the flags field on the struct and provides
- # convenient methods for checking if a flag is set.
- class FlagsField < Field
- def rbs_class
- "Integer"
- end
-
- def rbi_class
- "Integer"
- end
-
- def java_type
- "short"
- end
-
- def kind
- options.fetch(:kind)
- end
- end
-
# This represents an arbitrarily-sized integer. When it gets to Ruby it will
# be an Integer.
class IntegerField < Field
@@ -414,9 +393,9 @@ module Prism
# in YAML format. It contains information about the name of the node and the
# various child nodes it contains.
class NodeType
- attr_reader :name, :type, :human, :fields, :newline, :comment
+ attr_reader :name, :type, :human, :flags, :fields, :newline, :comment
- def initialize(config)
+ def initialize(config, flags)
@name = config.fetch("name")
type = @name.gsub(/(?<=.)[A-Z]/, "_\\0")
@@ -430,13 +409,14 @@ module Prism
options = field.transform_keys(&:to_sym)
options.delete(:type)
- # If/when we have documentation on every field, this should be changed
- # to use fetch instead of delete.
+ # If/when we have documentation on every field, this should be
+ # changed to use fetch instead of delete.
comment = options.delete(:comment)
type.new(comment: comment, **options)
end
+ @flags = config.key?("flags") ? flags.fetch(config.fetch("flags")) : nil
@newline = config.fetch("newline", true)
@comment = config.fetch("comment")
end
@@ -474,7 +454,6 @@ module Prism
when "location?" then OptionalLocationField
when "uint8" then UInt8Field
when "uint32" then UInt32Field
- when "flags" then FlagsField
when "integer" then IntegerField
when "double" then DoubleField
else raise("Unknown field type: #{name.inspect}")
@@ -603,13 +582,14 @@ module Prism
@locals ||=
begin
config = YAML.load_file(File.expand_path("../config.yml", __dir__))
+ flags = config.fetch("flags").to_h { |flags| [flags["name"], Flags.new(flags)] }
{
errors: config.fetch("errors").map { |name| Error.new(name) },
warnings: config.fetch("warnings").map { |name| Warning.new(name) },
- nodes: config.fetch("nodes").map { |node| NodeType.new(node) }.sort_by(&:name),
+ nodes: config.fetch("nodes").map { |node| NodeType.new(node, flags) }.sort_by(&:name),
tokens: config.fetch("tokens").map { |token| Token.new(token) },
- flags: config.fetch("flags").map { |flags| Flags.new(flags) }
+ flags: flags.values
}
end
end
diff --git a/test/prism/newline_test.rb b/test/prism/newline_test.rb
index 03d7df4c97..a244b5428a 100644
--- a/test/prism/newline_test.rb
+++ b/test/prism/newline_test.rb
@@ -88,7 +88,7 @@ module Prism
while node = queue.shift
queue.concat(node.compact_child_nodes)
- newlines << result.source.line(node.location.start_offset) if node&.newline?
+ newlines << result.source.line(node.location.start_offset) if node&.newline_flag?
end
newlines.sort
diff --git a/test/prism/result/integer_base_flags_test.rb b/test/prism/result/integer_base_flags_test.rb
index ef15fb437c..e3ab8c6910 100644
--- a/test/prism/result/integer_base_flags_test.rb
+++ b/test/prism/result/integer_base_flags_test.rb
@@ -11,7 +11,7 @@ module Prism
#
# In C, this would look something like:
#
- # ((flags & ~DECIMAL) << 1) || 10
+ # ((flags & ~DECIMAL) >> 1) || 10
#
# We have to do some other work in Ruby because 0 is truthy and ~ on an
# integer doesn't have a fixed width.
@@ -26,7 +26,7 @@ module Prism
def base(source)
node = Prism.parse_statement(source)
- value = (node.send(:flags) & (0b1111 - IntegerBaseFlags::DECIMAL)) << 1
+ value = (node.send(:flags) & (0b111100 - IntegerBaseFlags::DECIMAL)) >> 1
value == 0 ? 10 : value
end
end
diff --git a/test/prism/snapshots/integer_operations.txt b/test/prism/snapshots/integer_operations.txt
index 4660928ad2..4dda43e38c 100644
--- a/test/prism/snapshots/integer_operations.txt
+++ b/test/prism/snapshots/integer_operations.txt
@@ -236,7 +236,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (25,0)-(25,5))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ IntegerNode (location: (25,0)-(25,1))
│ │ ├── flags: decimal
@@ -274,7 +274,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (29,0)-(29,6))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ IntegerNode (location: (29,0)-(29,1))
│ │ ├── flags: decimal
@@ -369,7 +369,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (39,0)-(39,5))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ IntegerNode (location: (39,0)-(39,1))
│ │ ├── flags: decimal
@@ -388,7 +388,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (41,0)-(41,6))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ IntegerNode (location: (41,0)-(41,1))
│ │ ├── flags: decimal
diff --git a/test/prism/snapshots/ranges.txt b/test/prism/snapshots/ranges.txt
index 2fffe80537..a9688baf30 100644
--- a/test/prism/snapshots/ranges.txt
+++ b/test/prism/snapshots/ranges.txt
@@ -346,7 +346,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (35,0)-(35,7))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ RangeNode (location: (35,0)-(35,3))
│ │ ├── flags: ∅
@@ -370,7 +370,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (37,0)-(37,7))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ RangeNode (location: (37,0)-(37,3))
│ │ ├── flags: ∅
@@ -394,7 +394,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (39,0)-(39,8))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ RangeNode (location: (39,0)-(39,3))
│ │ ├── flags: ∅
@@ -418,7 +418,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (41,0)-(41,8))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ RangeNode (location: (41,0)-(41,3))
│ │ ├── flags: ∅
diff --git a/test/prism/snapshots/seattlerb/call_gt.txt b/test/prism/snapshots/seattlerb/call_gt.txt
index a6f19e5adf..90f419a412 100644
--- a/test/prism/snapshots/seattlerb/call_gt.txt
+++ b/test/prism/snapshots/seattlerb/call_gt.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(1,5))
└── body: (length: 1)
└── @ CallNode (location: (1,0)-(1,5))
- ├── flags: ∅
+ ├── flags: ignore_visibility
├── receiver:
│ @ IntegerNode (location: (1,0)-(1,1))
│ ├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/call_lt.txt b/test/prism/snapshots/seattlerb/call_lt.txt
index 14f50585d9..0020494e57 100644
--- a/test/prism/snapshots/seattlerb/call_lt.txt
+++ b/test/prism/snapshots/seattlerb/call_lt.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(1,5))
└── body: (length: 1)
└── @ CallNode (location: (1,0)-(1,5))
- ├── flags: ∅
+ ├── flags: ignore_visibility
├── receiver:
│ @ IntegerNode (location: (1,0)-(1,1))
│ ├── flags: decimal
diff --git a/test/prism/snapshots/seattlerb/call_lte.txt b/test/prism/snapshots/seattlerb/call_lte.txt
index 665a99d60a..e6630a7f28 100644
--- a/test/prism/snapshots/seattlerb/call_lte.txt
+++ b/test/prism/snapshots/seattlerb/call_lte.txt
@@ -4,7 +4,7 @@
@ StatementsNode (location: (1,0)-(1,6))
└── body: (length: 1)
└── @ CallNode (location: (1,0)-(1,6))
- ├── flags: ∅
+ ├── flags: ignore_visibility
├── receiver:
│ @ IntegerNode (location: (1,0)-(1,1))
│ ├── flags: decimal
diff --git a/test/prism/snapshots/whitequark/send_binary_op.txt b/test/prism/snapshots/whitequark/send_binary_op.txt
index 540a7681dc..09991c5679 100644
--- a/test/prism/snapshots/whitequark/send_binary_op.txt
+++ b/test/prism/snapshots/whitequark/send_binary_op.txt
@@ -238,7 +238,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (19,0)-(19,7))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ CallNode (location: (19,0)-(19,3))
│ │ ├── flags: variable_call, ignore_visibility
@@ -290,7 +290,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (23,0)-(23,8))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ CallNode (location: (23,0)-(23,3))
│ │ ├── flags: variable_call, ignore_visibility
@@ -420,7 +420,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (33,0)-(33,7))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ CallNode (location: (33,0)-(33,3))
│ │ ├── flags: variable_call, ignore_visibility
@@ -446,7 +446,7 @@
│ ├── closing_loc: ∅
│ └── block: ∅
├── @ CallNode (location: (35,0)-(35,8))
- │ ├── flags: ∅
+ │ ├── flags: ignore_visibility
│ ├── receiver:
│ │ @ CallNode (location: (35,0)-(35,3))
│ │ ├── flags: variable_call, ignore_visibility