[ruby/prism] wip: node unions

https://github.com/ruby/prism/commit/99a71675d4
This commit is contained in:
Gopal Patel 2023-12-20 20:41:52 -08:00 committed by git
parent 46fe3dc799
commit e03e9c3644
2 changed files with 59 additions and 7 deletions

View File

@ -692,6 +692,7 @@ nodes:
type: constant[] type: constant[]
- name: parameters - name: parameters
type: node? type: node?
kind: BlockParametersNode
- name: body - name: body
type: node? type: node?
- name: opening_loc - name: opening_loc
@ -727,6 +728,7 @@ nodes:
kind: ParametersNode kind: ParametersNode
- name: locals - name: locals
type: node[] type: node[]
kind: BlockLocalVariableNode
- name: opening_loc - name: opening_loc
type: location? type: location?
- name: closing_loc - name: closing_loc
@ -1134,6 +1136,9 @@ nodes:
type: node? type: node?
- name: child - name: child
type: node type: node
kind:
- ConstantReadNode
- MissingNode
- name: delimiter_loc - name: delimiter_loc
type: location type: location
comment: | comment: |
@ -1177,6 +1182,9 @@ nodes:
type: node? type: node?
- name: child - name: child
type: node type: node
kind:
- ConstantReadNode
- MissingNode
- name: delimiter_loc - name: delimiter_loc
type: location type: location
comment: | comment: |
@ -1617,6 +1625,10 @@ nodes:
fields: fields:
- name: numeric - name: numeric
type: node type: node
kind:
- FloatNode
- IntegerNode
- RationalNode
comment: | comment: |
Represents an imaginary number literal. Represents an imaginary number literal.
@ -2370,16 +2382,36 @@ nodes:
fields: fields:
- name: requireds - name: requireds
type: node[] type: node[]
kind:
- RequiredParameterNode
- MultiTargetNode
- name: optionals - name: optionals
type: node[] type: node[]
kind: OptionalParameterNode
- name: rest - name: rest
type: node? type: node?
kind:
- RestParameterNode
- ImplicitRestNode # Only in block parameters
- name: posts - name: posts
type: node[] type: node[]
kind:
- RequiredParameterNode
- MultiTargetNode
# On parsing error of `f(**kwargs, ...)` or `f(**nil, ...)`, the keyword_rest value is moved here:
- KeywordRestParameterNode
- NoKeywordsParameterNode
- name: keywords - name: keywords
type: node[] type: node[]
kind:
- RequiredKeywordParameterNode
- OptionalKeywordParameterNode
- name: keyword_rest - name: keyword_rest
type: node? type: node?
kind:
- KeywordRestParameterNode
- ForwardingParameterNode
- NoKeywordsParameterNode
- name: block - name: block
type: node? type: node?
kind: BlockParameterNode kind: BlockParameterNode

View File

@ -75,35 +75,49 @@ module Prism
# node and not just a generic node. # node and not just a generic node.
class NodeKindField < Field class NodeKindField < Field
def c_type def c_type
if options[:kind] if specific_kind
"pm_#{options[:kind].gsub(/(?<=.)[A-Z]/, "_\\0").downcase}" "pm_#{specific_kind.gsub(/(?<=.)[A-Z]/, "_\\0").downcase}"
else else
"pm_node" "pm_node"
end end
end end
def ruby_type def ruby_type
options[:kind] || "Node" specific_kind || "Node"
end end
def java_type def java_type
options[:kind] || "Node" specific_kind || "Node"
end end
def java_cast def java_cast
if options[:kind] if specific_kind
"(Nodes.#{options[:kind]}) " "(Nodes.#{options[:kind]}) "
else else
"" ""
end end
end end
def specific_kind
@options[:kind] unless @options[:kind].is_a?(Array)
end
def union_kind
options[:kind] if @options[:kind].is_a?(Array)
end
end end
# This represents a field on a node that is itself a node. We pass them as # This represents a field on a node that is itself a node. We pass them as
# references and store them as references. # references and store them as references.
class NodeField < NodeKindField class NodeField < NodeKindField
def rbs_class def rbs_class
options[:kind] || "Prism::node" if specific_kind
specific_kind
elsif union_kind
union_kind.join(" | ")
else
"Prism::node"
end
end end
def rbi_class def rbi_class
@ -115,7 +129,13 @@ module Prism
# optionally null. We pass them as references and store them as references. # optionally null. We pass them as references and store them as references.
class OptionalNodeField < NodeKindField class OptionalNodeField < NodeKindField
def rbs_class def rbs_class
"#{options[:kind] || "Prism::node"}?" if specific_kind
"#{specific_kind}?"
elsif union_kind
[union_kind, "nil"].join(" | ")
else
"Prism::node?"
end
end end
def rbi_class def rbi_class