@@ -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
0 commit comments