diff --git a/config.yml b/config.yml index af4bc42fb61..9a959c9cb88 100644 --- a/config.yml +++ b/config.yml @@ -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 diff --git a/templates/template.rb b/templates/template.rb index 35133169fee..18806901e1a 100755 --- a/templates/template.rb +++ b/templates/template.rb @@ -75,35 +75,49 @@ def should_be_serialized? # 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 @@ def rbi_class # 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