[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[]
- name: parameters
type: node?
kind: BlockParametersNode
- name: body
type: node?
- name: opening_loc
@ -727,6 +728,7 @@ nodes:
kind: ParametersNode
- name: locals
type: node[]
kind: BlockLocalVariableNode
- name: opening_loc
type: location?
- name: closing_loc
@ -1134,6 +1136,9 @@ nodes:
type: node?
- name: child
type: node
kind:
- ConstantReadNode
- MissingNode
- name: delimiter_loc
type: location
comment: |
@ -1177,6 +1182,9 @@ nodes:
type: node?
- name: child
type: node
kind:
- ConstantReadNode
- MissingNode
- name: delimiter_loc
type: location
comment: |
@ -1617,6 +1625,10 @@ nodes:
fields:
- name: numeric
type: node
kind:
- FloatNode
- IntegerNode
- RationalNode
comment: |
Represents an imaginary number literal.
@ -2370,16 +2382,36 @@ nodes:
fields:
- name: requireds
type: node[]
kind:
- RequiredParameterNode
- MultiTargetNode
- name: optionals
type: node[]
kind: OptionalParameterNode
- name: rest
type: node?
kind:
- RestParameterNode
- ImplicitRestNode # Only in block parameters
- name: posts
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
type: node[]
kind:
- RequiredKeywordParameterNode
- OptionalKeywordParameterNode
- name: keyword_rest
type: node?
kind:
- KeywordRestParameterNode
- ForwardingParameterNode
- NoKeywordsParameterNode
- name: block
type: node?
kind: BlockParameterNode

View File

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