Skip to content

Commit 5c20ec0

Browse files
authored
Merge pull request #189 from rhiroe/add/the-unknown-type-option
Proposal: Added the `--unknown-type` option to generate type other than `untyped` for unknown types
2 parents 69ca6d6 + 9af1252 commit 5c20ec0

File tree

9 files changed

+204
-49
lines changed

9 files changed

+204
-49
lines changed

lib/rbs/inline/ast/declarations.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -189,7 +189,7 @@ def initialize(node, comments, assertion) #: void
189189

190190
# @rbs %a{pure}
191191
# @rbs return: Types::t
192-
def type
192+
def type(default_type)
193193
if assertion
194194
case assertion.type
195195
when MethodType, nil
@@ -203,7 +203,7 @@ def type
203203
return literal
204204
end
205205

206-
Types::Bases::Any.new(location: nil)
206+
default_type
207207
end
208208

209209
# @rbs %a{pure}

lib/rbs/inline/ast/members.rb

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -158,7 +158,8 @@ def overloading? #: bool
158158
end
159159
end
160160

161-
def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
161+
# @rbs (::RBS::Types::t default_type) -> Array[RBS::AST::Members::MethodDefinition::Overload]
162+
def method_overloads(default_type)
162163
case
163164
when method_types = annotated_method_types
164165
method_types.map do |method_type|
@@ -181,7 +182,7 @@ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
181182
when Prism::RequiredParameterNode
182183
required_positionals << Types::Function::Param.new(
183184
name: param.name,
184-
type: var_type_hash[param.name] || Types::Bases::Any.new(location: nil),
185+
type: var_type_hash[param.name] || default_type,
185186
location: nil
186187
)
187188
end
@@ -192,7 +193,7 @@ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
192193
when Prism::OptionalParameterNode
193194
optional_positionals << Types::Function::Param.new(
194195
name: param.name,
195-
type: var_type_hash[param.name] || Types::Bases::Any.new(location: nil),
196+
type: var_type_hash[param.name] || default_type,
196197
location: nil
197198
)
198199
end
@@ -207,7 +208,7 @@ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
207208

208209
rest_positionals = Types::Function::Param.new(
209210
name: rest.name,
210-
type: splat_type || Types::Bases::Any.new(location: nil),
211+
type: splat_type || default_type,
211212
location: nil
212213
)
213214
end
@@ -216,15 +217,15 @@ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
216217
if node.is_a?(Prism::RequiredKeywordParameterNode)
217218
required_keywords[node.name] = Types::Function::Param.new(
218219
name: nil,
219-
type: var_type_hash[node.name] || Types::Bases::Any.new(location: nil),
220+
type: var_type_hash[node.name] || default_type,
220221
location: nil
221222
)
222223
end
223224

224225
if node.is_a?(Prism::OptionalKeywordParameterNode)
225226
optional_keywords[node.name] = Types::Function::Param.new(
226227
name: nil,
227-
type: var_type_hash[node.name] || Types::Bases::Any.new(location: nil),
228+
type: var_type_hash[node.name] || default_type,
228229
location: nil
229230
)
230231
end
@@ -239,13 +240,13 @@ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
239240

240241
rest_keywords = Types::Function::Param.new(
241242
name: kw_rest.name,
242-
type: double_splat_type || Types::Bases::Any.new(location: nil),
243+
type: double_splat_type || default_type,
243244
location: nil)
244245
end
245246

246247
if node.parameters.block
247248
block = Types::Block.new(
248-
type: Types::UntypedFunction.new(return_type: Types::Bases::Any.new(location: nil)),
249+
type: Types::UntypedFunction.new(return_type: default_type),
249250
required: false,
250251
self_type: nil
251252
)
@@ -268,7 +269,7 @@ def method_overloads #: Array[RBS::AST::Members::MethodDefinition::Overload]
268269
required_keywords: required_keywords,
269270
optional_keywords: optional_keywords,
270271
rest_keywords: rest_keywords,
271-
return_type: return_type || Types::Bases::Any.new(location: nil)
272+
return_type: return_type || default_type
272273
),
273274
block: block,
274275
location: nil
@@ -429,7 +430,8 @@ def initialize(node, comments, assertion)
429430
end
430431

431432
# @rbs return Array[RBS::AST::Members::AttrReader | RBS::AST::Members::AttrWriter | RBS::AST::Members::AttrAccessor]?
432-
def rbs
433+
# @rbs default_type: RBS::Types::t
434+
def rbs(default_type)
433435
if comments
434436
comment = RBS::AST::Comment.new(string: comments.content(trim: true), location: nil)
435437
end
@@ -460,7 +462,7 @@ def rbs
460462
args.map do |arg|
461463
klass.new(
462464
name: arg,
463-
type: attribute_type,
465+
type: attribute_type || default_type,
464466
ivar_name: nil,
465467
kind: :instance,
466468
annotations: [],
@@ -474,13 +476,11 @@ def rbs
474476

475477
# Returns the type of the attribute
476478
#
477-
# Returns `untyped` when not annotated.
478-
#
479-
def attribute_type #: Types::t
479+
def attribute_type #: Types::t?
480480
type = assertion&.type
481481
raise if type.is_a?(MethodType)
482482

483-
type || Types::Bases::Any.new(location: nil)
483+
type
484484
end
485485
end
486486

lib/rbs/inline/cli.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,7 @@ def run(args)
7373
base_paths = [Pathname("lib"), Pathname("app")]
7474
output_path = nil #: Pathname?
7575
opt_in = true
76+
unknown_type = nil #: String?
7677

7778
OptionParser.new do |opts|
7879
opts.on("--base=BASE", "The path to calculate relative path of files (defaults to #{base_paths.join(File::PATH_SEPARATOR)})") do |str|
@@ -96,6 +97,10 @@ def run(args)
9697
opt_in = true
9798
end
9899

100+
opts.on("--unknown-type=TYPE", "Use given type instead of untyped for unknown types (default: untyped)") do
101+
unknown_type = _1
102+
end
103+
99104
opts.on("--verbose") do
100105
logger.level = :DEBUG
101106
end
@@ -141,6 +146,12 @@ def run(args)
141146

142147
if (uses, decls, rbs_decls = Parser.parse(Prism.parse_file(target.to_s), opt_in: opt_in))
143148
writer = Writer.new()
149+
150+
if unknown_type
151+
type = RBS::Parser.parse_type(unknown_type, require_eof: true)
152+
type && writer.default_type = type
153+
end
154+
144155
writer.header("Generated from #{target.relative? ? target : target.relative_path_from(Pathname.pwd)} with RBS::Inline")
145156
writer.write(uses, decls, rbs_decls)
146157

lib/rbs/inline/writer.rb

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -15,17 +15,22 @@ class Writer
1515
attr_reader :output #: String
1616
attr_reader :writer #: RBS::Writer
1717

18+
attr_accessor :default_type #: Types::t
19+
1820
# @rbs buffer: String
1921
def initialize(buffer = +"") #: void
2022
@output = buffer
2123
@writer = RBS::Writer.new(out: StringIO.new(buffer))
24+
@default_type = Types::Bases::Any.new(location: nil)
2225
end
2326

2427
# @rbs uses: Array[AST::Annotations::Use]
2528
# @rbs decls: Array[AST::Declarations::t]
2629
# @rbs rbs_decls: Array[RBS::AST::Declarations::t]
27-
def self.write(uses, decls, rbs_decls) #: void
30+
# @rbs &: ? (Writer) -> void
31+
def self.write(uses, decls, rbs_decls, &) #: void
2832
writer = Writer.new()
33+
yield writer if block_given?
2934
writer.write(uses, decls, rbs_decls)
3035
writer.output
3136
end
@@ -200,7 +205,7 @@ def translate_data_assign_decl(decl, rbs) #: void
200205
attributes = decl.each_attribute.map do |name, type|
201206
RBS::AST::Members::AttrReader.new(
202207
name: name,
203-
type: type&.type || Types::Bases::Any.new(location: nil),
208+
type: type&.type || default_type,
204209
ivar_name: false,
205210
comment: nil,
206211
kind: :instance,
@@ -220,7 +225,7 @@ def translate_data_assign_decl(decl, rbs) #: void
220225
type: Types::Function.empty(Types::Bases::Instance.new(location: nil)).update(
221226
required_positionals: decl.each_attribute.map do |name, attr|
222227
RBS::Types::Function::Param.new(
223-
type: attr&.type || Types::Bases::Any.new(location: nil),
228+
type: attr&.type || default_type,
224229
name: name,
225230
location: nil
226231
)
@@ -239,7 +244,7 @@ def translate_data_assign_decl(decl, rbs) #: void
239244
[
240245
name,
241246
RBS::Types::Function::Param.new(
242-
type: attr&.type || Types::Bases::Any.new(location: nil),
247+
type: attr&.type || default_type,
243248
name: nil,
244249
location: nil
245250
)
@@ -317,7 +322,7 @@ def translate_struct_assign_decl(decl, rbs) #: void
317322
if decl.readonly_attributes?
318323
RBS::AST::Members::AttrReader.new(
319324
name: name,
320-
type: type&.type || Types::Bases::Any.new(location: nil),
325+
type: type&.type || default_type,
321326
ivar_name: false,
322327
comment: nil,
323328
kind: :instance,
@@ -328,7 +333,7 @@ def translate_struct_assign_decl(decl, rbs) #: void
328333
else
329334
RBS::AST::Members::AttrAccessor.new(
330335
name: name,
331-
type: type&.type || Types::Bases::Any.new(location: nil),
336+
type: type&.type || default_type,
332337
ivar_name: false,
333338
comment: nil,
334339
kind: :instance,
@@ -353,7 +358,7 @@ def translate_struct_assign_decl(decl, rbs) #: void
353358
if decl.positional_init?
354359
attr_params = decl.each_attribute.map do |name, attr|
355360
RBS::Types::Function::Param.new(
356-
type: attr&.type || Types::Bases::Any.new(location: nil),
361+
type: attr&.type || default_type,
357362
name: name,
358363
location: nil
359364
)
@@ -378,7 +383,7 @@ def translate_struct_assign_decl(decl, rbs) #: void
378383
[
379384
name,
380385
RBS::Types::Function::Param.new(
381-
type: attr&.type || Types::Bases::Any.new(location: nil),
386+
type: attr&.type || default_type,
382387
name: nil,
383388
location: nil
384389
)
@@ -407,7 +412,7 @@ def translate_struct_assign_decl(decl, rbs) #: void
407412
t.update(required_positionals: [
408413
RBS::Types::Function::Param.new(
409414
type: RBS::Types::Record.new(all_fields: decl.each_attribute.map do |name, attr|
410-
[name, attr&.type || Types::Bases::Any.new(location: nil)]
415+
[name, attr&.type || default_type]
411416
end.to_h, location: nil),
412417
name: nil,
413418
location: nil
@@ -430,7 +435,7 @@ def translate_struct_assign_decl(decl, rbs) #: void
430435
name: RBS::TypeName.new(name: :Struct, namespace: RBS::Namespace.empty),
431436
args: [
432437
RBS::Types::Union.new(
433-
types: decl.each_attribute.map { |_, attr| attr&.type || RBS::Types::Bases::Any.new(location: nil) }.uniq,
438+
types: decl.each_attribute.map { |_, attr| attr&.type || default_type }.uniq,
434439
location: nil
435440
)
436441
],
@@ -485,7 +490,7 @@ def translate_member(member, decl, rbs)
485490
rbs << RBS::AST::Members::MethodDefinition.new(
486491
name: member.method_name,
487492
kind: kind,
488-
overloads: member.method_overloads,
493+
overloads: member.method_overloads(default_type),
489494
annotations: member.method_annotations,
490495
location: nil,
491496
comment: comment,
@@ -510,7 +515,7 @@ def translate_member(member, decl, rbs)
510515
rbs << m
511516
end
512517
when AST::Members::RubyAttr
513-
if m = member.rbs
518+
if m = member.rbs(default_type)
514519
rbs.concat m
515520
end
516521
when AST::Members::RubyPrivate
@@ -620,24 +625,19 @@ def translate_class_block_decl(block, rbs)
620625
# @rbs decl: AST::Declarations::ConstantDecl
621626
# @rbs return: RBS::Types::t
622627
def constant_decl_to_type(decl)
623-
type = decl.type
628+
type = decl.type(default_type)
624629
return type unless type.is_a?(RBS::Types::ClassInstance)
625630
return type if type.args.any?
626631

627632
case decl.node.value
628633
when Prism::ArrayNode
629-
RBS::BuiltinNames::Array.instance_type(untyped)
634+
RBS::BuiltinNames::Array.instance_type(default_type)
630635
when Prism::HashNode
631-
RBS::BuiltinNames::Hash.instance_type(untyped, untyped)
636+
RBS::BuiltinNames::Hash.instance_type(default_type, default_type)
632637
else
633638
type
634639
end
635640
end
636-
637-
# @rbs return: RBS::Types::Bases::Any
638-
def untyped
639-
@untyped ||= RBS::Types::Bases::Any.new(location: nil)
640-
end
641641
end
642642
end
643643
end

sig/generated/rbs/inline/ast/declarations.rbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ module RBS
9999
# @rbs %a{pure}
100100
# @rbs return: Types::t
101101
%a{pure}
102-
def type: () -> Types::t
102+
def type: (untyped default_type) -> Types::t
103103

104104
# @rbs %a{pure}
105105
# @rbs return Types::t?

sig/generated/rbs/inline/ast/members.rbs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,8 @@ module RBS
6868

6969
def overloading?: () -> bool
7070

71-
def method_overloads: () -> Array[RBS::AST::Members::MethodDefinition::Overload]
71+
# @rbs (::RBS::Types::t default_type) -> Array[RBS::AST::Members::MethodDefinition::Overload]
72+
def method_overloads: (::RBS::Types::t default_type) -> Array[RBS::AST::Members::MethodDefinition::Overload]
7273

7374
def method_annotations: () -> Array[RBS::AST::Annotation]
7475

@@ -133,12 +134,11 @@ module RBS
133134
def initialize: (Prism::CallNode node, AnnotationParser::ParsingResult? comments, Annotations::TypeAssertion? assertion) -> void
134135

135136
# @rbs return Array[RBS::AST::Members::AttrReader | RBS::AST::Members::AttrWriter | RBS::AST::Members::AttrAccessor]?
136-
def rbs: () -> Array[RBS::AST::Members::AttrReader | RBS::AST::Members::AttrWriter | RBS::AST::Members::AttrAccessor]?
137+
# @rbs default_type: RBS::Types::t
138+
def rbs: (RBS::Types::t default_type) -> Array[RBS::AST::Members::AttrReader | RBS::AST::Members::AttrWriter | RBS::AST::Members::AttrAccessor]?
137139

138140
# Returns the type of the attribute
139-
#
140-
# Returns `untyped` when not annotated.
141-
def attribute_type: () -> Types::t
141+
def attribute_type: () -> Types::t?
142142
end
143143

144144
# `private` call without arguments

sig/generated/rbs/inline/writer.rbs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,16 @@ module RBS
1313

1414
attr_reader writer: RBS::Writer
1515

16+
attr_accessor default_type: Types::t
17+
1618
# @rbs buffer: String
1719
def initialize: (?String buffer) -> void
1820

1921
# @rbs uses: Array[AST::Annotations::Use]
2022
# @rbs decls: Array[AST::Declarations::t]
2123
# @rbs rbs_decls: Array[RBS::AST::Declarations::t]
22-
def self.write: (Array[AST::Annotations::Use] uses, Array[AST::Declarations::t] decls, Array[RBS::AST::Declarations::t] rbs_decls) -> void
24+
# @rbs &: ? (Writer) -> void
25+
def self.write: (Array[AST::Annotations::Use] uses, Array[AST::Declarations::t] decls, Array[RBS::AST::Declarations::t] rbs_decls) ?{ (Writer) -> void } -> void
2326

2427
# @rbs *lines: String
2528
# @rbs return: void
@@ -111,9 +114,6 @@ module RBS
111114
# @rbs decl: AST::Declarations::ConstantDecl
112115
# @rbs return: RBS::Types::t
113116
def constant_decl_to_type: (AST::Declarations::ConstantDecl decl) -> RBS::Types::t
114-
115-
# @rbs return: RBS::Types::Bases::Any
116-
def untyped: () -> RBS::Types::Bases::Any
117117
end
118118
end
119119
end

0 commit comments

Comments
 (0)