Skip to content

Commit d71f85d

Browse files
committed
Update inline parser
1 parent b6be236 commit d71f85d

3 files changed

Lines changed: 221 additions & 49 deletions

File tree

lib/rbs/ast/ruby/members.rb

Lines changed: 68 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -27,29 +27,55 @@ class DocStyle
2727

2828
def initialize
2929
@return_type_annotation = nil
30-
@required_positionals = [] #: Array[Annotations::ParamTypeAnnotation?]
31-
@optional_positionals = [] #: Array[Annotations::ParamTypeAnnotation?]
32-
@rest_positionals = nil #: Annotations::ParamTypeAnnotation?
33-
@trailing_positionals = [] #: Array[Annotations::ParamTypeAnnotation?]
34-
@required_keywords = {} #: Hash[Symbol, Annotations::ParamTypeAnnotation]
35-
@optional_keywords = {} #: Hash[Symbol, Annotations::ParamTypeAnnotation]
36-
@rest_keywords = nil #: Annotations::ParamTypeAnnotation?
30+
@required_positionals = []
31+
@optional_positionals = []
32+
@rest_positionals = nil
33+
@trailing_positionals = []
34+
@required_keywords = {}
35+
@optional_keywords = {}
36+
@rest_keywords = nil
3737
end
3838

3939
def self.build(param_type_annotations, return_type_annotation, node)
4040
doc = DocStyle.new
4141
doc.return_type_annotation = return_type_annotation
4242

43-
unused = param_type_annotations.dup
43+
splat_annotation = nil #: Annotations::SplatParamTypeAnnotation?
44+
double_splat_annotation = nil #: Annotations::DoubleSplatParamTypeAnnotation?
45+
param_annotations = {} #: Hash[Symbol, Annotations::ParamTypeAnnotation]
46+
unused = [] #: Array[Annotations::ParamTypeAnnotation | Annotations::SplatParamTypeAnnotation | Annotations::DoubleSplatParamTypeAnnotation]
47+
48+
param_type_annotations.each do |annot|
49+
case annot
50+
when Annotations::SplatParamTypeAnnotation
51+
if splat_annotation
52+
unused << annot
53+
else
54+
splat_annotation = annot
55+
end
56+
when Annotations::DoubleSplatParamTypeAnnotation
57+
if double_splat_annotation
58+
unused << annot
59+
else
60+
double_splat_annotation = annot
61+
end
62+
when Annotations::ParamTypeAnnotation
63+
name = annot.name_location.source.to_sym
64+
if param_annotations.key?(name)
65+
unused << annot
66+
else
67+
param_annotations[name] = annot
68+
end
69+
end
70+
end
4471

4572
if node.parameters
4673
params = node.parameters #: Prism::ParametersNode
4774

4875
params.requireds.each do |param|
4976
if param.is_a?(Prism::RequiredParameterNode)
50-
annotation = unused.find { _1.name_location.source.to_sym == param.name }
77+
annotation = param_annotations.delete(param.name)
5178
if annotation
52-
unused.delete(annotation)
5379
doc.required_positionals << annotation
5480
else
5581
doc.required_positionals << param.name
@@ -59,31 +85,28 @@ def self.build(param_type_annotations, return_type_annotation, node)
5985

6086
params.optionals.each do |param|
6187
if param.is_a?(Prism::OptionalParameterNode)
62-
annotation = unused.find { _1.name_location.source.to_sym == param.name }
88+
annotation = param_annotations.delete(param.name)
6389
if annotation
64-
unused.delete(annotation)
6590
doc.optional_positionals << annotation
6691
else
6792
doc.optional_positionals << param.name
6893
end
6994
end
7095
end
7196

72-
if (rest = params.rest) && rest.is_a?(Prism::RestParameterNode) && rest.name
73-
annotation = unused.find { _1.name_location.source.to_sym == rest.name }
74-
if annotation
75-
unused.delete(annotation)
76-
doc.rest_positionals = annotation
97+
if (rest = params.rest) && rest.is_a?(Prism::RestParameterNode)
98+
if splat_annotation && (splat_annotation.name_location.nil? || rest.name.nil? || splat_annotation.name_location.source.to_sym == rest.name)
99+
doc.rest_positionals = splat_annotation
100+
splat_annotation = nil
77101
else
78-
doc.rest_positionals = rest.name
102+
doc.rest_positionals = rest.name || true
79103
end
80104
end
81105

82106
params.posts.each do |param|
83107
if param.is_a?(Prism::RequiredParameterNode)
84-
annotation = unused.find { _1.name_location.source.to_sym == param.name }
108+
annotation = param_annotations.delete(param.name)
85109
if annotation
86-
unused.delete(annotation)
87110
doc.trailing_positionals << annotation
88111
else
89112
doc.trailing_positionals << param.name
@@ -94,41 +117,42 @@ def self.build(param_type_annotations, return_type_annotation, node)
94117
params.keywords.each do |param|
95118
case param
96119
when Prism::RequiredKeywordParameterNode
97-
annotation = unused.find { _1.name_location.source.to_sym == param.name }
120+
annotation = param_annotations.delete(param.name)
98121
if annotation
99-
unused.delete(annotation)
100122
doc.required_keywords[param.name] = annotation
101123
else
102124
doc.required_keywords[param.name] = param.name
103125
end
104126
when Prism::OptionalKeywordParameterNode
105-
annotation = unused.find { _1.name_location.source.to_sym == param.name }
127+
annotation = param_annotations.delete(param.name)
106128
if annotation
107-
unused.delete(annotation)
108129
doc.optional_keywords[param.name] = annotation
109130
else
110131
doc.optional_keywords[param.name] = param.name
111132
end
112133
end
113134
end
114135

115-
if (kw_rest = params.keyword_rest) && kw_rest.is_a?(Prism::KeywordRestParameterNode) && kw_rest.name
116-
annotation = unused.find { _1.name_location.source.to_sym == kw_rest.name }
117-
if annotation
118-
unused.delete(annotation)
119-
doc.rest_keywords = annotation
136+
if (kw_rest = params.keyword_rest) && kw_rest.is_a?(Prism::KeywordRestParameterNode)
137+
if double_splat_annotation && (double_splat_annotation.name_location.nil? || kw_rest.name.nil? || double_splat_annotation.name_location.source.to_sym == kw_rest.name)
138+
doc.rest_keywords = double_splat_annotation
139+
double_splat_annotation = nil
120140
else
121-
doc.rest_keywords = kw_rest.name
141+
doc.rest_keywords = kw_rest.name || true
122142
end
123143
end
124144
end
125145

146+
unused.concat(param_annotations.values)
147+
unused << splat_annotation if splat_annotation
148+
unused << double_splat_annotation if double_splat_annotation
149+
126150
[doc, unused]
127151
end
128152

129153
def all_param_annotations
130-
annotations = [] #: Array[param_type_annotation | Symbol | nil]
131-
#
154+
annotations = [] #: Array[param_type_annotation | Symbol | true | nil]
155+
132156
required_positionals.each { |a| annotations << a }
133157
optional_positionals.each { |a| annotations << a }
134158
annotations << rest_positionals
@@ -165,7 +189,7 @@ def map_type_name(&block)
165189
)
166190
new.rest_positionals =
167191
case rest_positionals
168-
when Annotations::ParamTypeAnnotation
192+
when Annotations::SplatParamTypeAnnotation
169193
rest_positionals.map_type_name(&block)
170194
else
171195
rest_positionals
@@ -202,7 +226,7 @@ def map_type_name(&block)
202226
)
203227
new.rest_keywords =
204228
case rest_keywords
205-
when Annotations::ParamTypeAnnotation
229+
when Annotations::DoubleSplatParamTypeAnnotation
206230
rest_keywords.map_type_name(&block)
207231
else
208232
rest_keywords
@@ -255,10 +279,12 @@ def method_type
255279
end
256280
rest_pos =
257281
case rest_positionals
258-
when Annotations::ParamTypeAnnotation
259-
Types::Function::Param.new(type: rest_positionals.param_type, name: rest_positionals.name_location.source.to_sym)
282+
when Annotations::SplatParamTypeAnnotation
283+
Types::Function::Param.new(type: rest_positionals.param_type, name: rest_positionals.name_location&.source&.to_sym)
260284
when Symbol
261285
Types::Function::Param.new(type: any.call, name: rest_positionals)
286+
when true
287+
Types::Function::Param.new(type: any.call, name: nil)
262288
else
263289
nil
264290
end
@@ -290,9 +316,11 @@ def method_type
290316

291317
rest_kw =
292318
case rest_keywords
293-
when Annotations::ParamTypeAnnotation
294-
Types::Function::Param.new(type: rest_keywords.param_type, name: nil)
319+
when Annotations::DoubleSplatParamTypeAnnotation
320+
Types::Function::Param.new(type: rest_keywords.param_type, name: rest_keywords.name_location&.source&.to_sym)
295321
when Symbol
322+
Types::Function::Param.new(type: any.call, name: rest_keywords)
323+
when true
296324
Types::Function::Param.new(type: any.call, name: nil)
297325
else
298326
nil
@@ -343,7 +371,7 @@ def self.build(leading_block, trailing_block, variables, node)
343371

344372
type_annotations = nil #: type_annotations
345373
return_annotation = nil #: Annotations::ReturnTypeAnnotation | Annotations::NodeTypeAssertion | nil
346-
param_annotations = [] #: Array[Annotations::ParamTypeAnnotation]
374+
param_annotations = [] #: Array[Annotations::ParamTypeAnnotation | Annotations::SplatParamTypeAnnotation | Annotations::DoubleSplatParamTypeAnnotation]
347375

348376
if trailing_block
349377
case annotation = trailing_block.trailing_annotation(variables)
@@ -377,7 +405,7 @@ def self.build(leading_block, trailing_block, variables, node)
377405
next
378406
end
379407
end
380-
when Annotations::ParamTypeAnnotation
408+
when Annotations::ParamTypeAnnotation, Annotations::SplatParamTypeAnnotation, Annotations::DoubleSplatParamTypeAnnotation
381409
unless type_annotations
382410
param_annotations << paragraph
383411
next

sig/ast/ruby/members.rbs

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -20,22 +20,24 @@ module RBS
2020
class MethodTypeAnnotation
2121
class DocStyle
2222
type param_type_annotation = Annotations::ParamTypeAnnotation
23+
| Annotations::SplatParamTypeAnnotation
24+
| Annotations::DoubleSplatParamTypeAnnotation
2325

2426
attr_accessor return_type_annotation: Annotations::ReturnTypeAnnotation | Annotations::NodeTypeAssertion | nil
2527

26-
attr_reader required_positionals: Array[param_type_annotation | Symbol]
27-
attr_reader optional_positionals: Array[param_type_annotation | Symbol]
28-
attr_accessor rest_positionals: param_type_annotation | Symbol | nil
29-
attr_reader trailing_positionals: Array[param_type_annotation | Symbol]
30-
attr_reader required_keywords: Hash[Symbol, param_type_annotation | Symbol]
31-
attr_reader optional_keywords: Hash[Symbol, param_type_annotation | Symbol]
32-
attr_accessor rest_keywords: param_type_annotation | Symbol | nil
28+
attr_reader required_positionals: Array[Annotations::ParamTypeAnnotation | Symbol]
29+
attr_reader optional_positionals: Array[Annotations::ParamTypeAnnotation | Symbol]
30+
attr_accessor rest_positionals: Annotations::SplatParamTypeAnnotation | Symbol | true | nil
31+
attr_reader trailing_positionals: Array[Annotations::ParamTypeAnnotation | Symbol]
32+
attr_reader required_keywords: Hash[Symbol, Annotations::ParamTypeAnnotation | Symbol]
33+
attr_reader optional_keywords: Hash[Symbol, Annotations::ParamTypeAnnotation | Symbol]
34+
attr_accessor rest_keywords: Annotations::DoubleSplatParamTypeAnnotation | Symbol | true | nil
3335

3436
def initialize: () -> void
3537

3638
def self.build: (Array[param_type_annotation], Annotations::ReturnTypeAnnotation | Annotations::NodeTypeAssertion | nil, Prism::DefNode) -> [DocStyle, Array[param_type_annotation]]
3739

38-
def all_param_annotations: () -> Array[param_type_annotation | Symbol | nil]
40+
def all_param_annotations: () -> Array[param_type_annotation | Symbol | true | nil]
3941

4042
def map_type_name: () { (TypeName) -> TypeName } -> self
4143

0 commit comments

Comments
 (0)