rbs 3.0.4 → 3.1.0

Sign up to get free protection for your applications and to get access to all the features.
data/lib/rbs/errors.rb CHANGED
@@ -22,11 +22,16 @@ module RBS
22
22
 
23
23
  module DetailedMessageable
24
24
  def detailed_message(highlight: false, **)
25
+ msg = super
26
+
27
+ # Support only one line
28
+ return msg unless location.start_line == location.end_line
29
+
25
30
  indent = " " * location.start_column
26
31
  marker = "^" * (location.end_column - location.start_column)
27
32
 
28
33
  io = StringIO.new
29
- io.puts super
34
+ io.puts msg
30
35
  io.puts
31
36
  io.print "\e[1m" if highlight
32
37
  io.puts " #{location.buffer.lines[location.end_line - 1]}"
@@ -125,7 +130,9 @@ module RBS
125
130
  end
126
131
  end
127
132
 
128
- class NoTypeFoundError < BaseError
133
+ class NoTypeFoundError < DefinitionError
134
+ include DetailedMessageable
135
+
129
136
  attr_reader :type_name
130
137
  attr_reader :location
131
138
 
@@ -163,6 +170,8 @@ module RBS
163
170
  end
164
171
 
165
172
  class InheritModuleError < DefinitionError
173
+ include DetailedMessageable
174
+
166
175
  attr_reader :super_decl
167
176
 
168
177
  def initialize(super_decl)
@@ -171,6 +180,10 @@ module RBS
171
180
  super "#{Location.to_string(super_decl.location)}: Cannot inherit a module: #{super_decl.name}"
172
181
  end
173
182
 
183
+ def location
184
+ @super_decl.location
185
+ end
186
+
174
187
  def self.check!(super_decl, env:)
175
188
  return if env.class_decl?(super_decl.name) || env.class_alias?(super_decl.name)
176
189
 
@@ -179,6 +192,8 @@ module RBS
179
192
  end
180
193
 
181
194
  class NoSelfTypeFoundError < DefinitionError
195
+ include DetailedMessageable
196
+
182
197
  attr_reader :type_name
183
198
  attr_reader :location
184
199
 
@@ -197,6 +212,8 @@ module RBS
197
212
  end
198
213
 
199
214
  class NoMixinFoundError < DefinitionError
215
+ include DetailedMessageable
216
+
200
217
  attr_reader :type_name
201
218
  attr_reader :member
202
219
 
@@ -217,6 +234,8 @@ module RBS
217
234
  end
218
235
 
219
236
  class DuplicatedMethodDefinitionError < DefinitionError
237
+ include DetailedMessageable
238
+
220
239
  attr_reader :type
221
240
  attr_reader :method_name
222
241
  attr_reader :members
@@ -256,6 +275,8 @@ module RBS
256
275
  end
257
276
 
258
277
  class DuplicatedInterfaceMethodDefinitionError < DefinitionError
278
+ include DetailedMessageable
279
+
259
280
  attr_reader :type
260
281
  attr_reader :method_name
261
282
  attr_reader :member
@@ -268,6 +289,10 @@ module RBS
268
289
  super "#{member.location}: Duplicated method definition: #{qualified_method_name}"
269
290
  end
270
291
 
292
+ def location
293
+ member.location
294
+ end
295
+
271
296
  def qualified_method_name
272
297
  case type
273
298
  when Types::ClassSingleton
@@ -283,6 +308,8 @@ module RBS
283
308
  end
284
309
 
285
310
  class UnknownMethodAliasError < DefinitionError
311
+ include DetailedMessageable
312
+
286
313
  attr_reader :type_name
287
314
  attr_reader :original_name
288
315
  attr_reader :aliased_name
@@ -310,6 +337,8 @@ module RBS
310
337
  end
311
338
 
312
339
  class InvalidOverloadMethodError < DefinitionError
340
+ include DetailedMessageable
341
+
313
342
  attr_reader :type_name
314
343
  attr_reader :method_name
315
344
  attr_reader :kind
@@ -330,6 +359,10 @@ module RBS
330
359
 
331
360
  super "#{Location.to_string members[0].location}: Invalid method overloading: #{type_name}#{delimiter}#{method_name}"
332
361
  end
362
+
363
+ def location
364
+ members[0].location
365
+ end
333
366
  end
334
367
 
335
368
  class GenericParameterMismatchError < LoadingError
@@ -357,6 +390,8 @@ module RBS
357
390
  end
358
391
 
359
392
  class InvalidVarianceAnnotationError < DefinitionError
393
+ include DetailedMessageable
394
+
360
395
  attr_reader :type_name
361
396
  attr_reader :param
362
397
  attr_reader :location
@@ -371,6 +406,8 @@ module RBS
371
406
  end
372
407
 
373
408
  class RecursiveAliasDefinitionError < DefinitionError
409
+ include DetailedMessageable
410
+
374
411
  attr_reader :type
375
412
  attr_reader :defs
376
413
 
@@ -389,6 +426,8 @@ module RBS
389
426
  end
390
427
 
391
428
  class MixinClassError < DefinitionError
429
+ include DetailedMessageable
430
+
392
431
  attr_reader :type_name
393
432
  attr_reader :member
394
433
 
@@ -426,6 +465,8 @@ module RBS
426
465
  end
427
466
 
428
467
  class RecursiveTypeAliasError < BaseError
468
+ include DetailedMessageable
469
+
429
470
  attr_reader :alias_names
430
471
  attr_reader :location
431
472
 
@@ -442,6 +483,8 @@ module RBS
442
483
  end
443
484
 
444
485
  class NonregularTypeAliasError < BaseError
486
+ include DetailedMessageable
487
+
445
488
  attr_reader :diagnostic
446
489
  attr_reader :location
447
490
 
@@ -454,6 +497,8 @@ module RBS
454
497
  end
455
498
 
456
499
  class CyclicTypeParameterBound < BaseError
500
+ include DetailedMessageable
501
+
457
502
  attr_reader :params, :type_name, :method_name, :location
458
503
 
459
504
  def initialize(type_name:, method_name:, params:, location:)
@@ -467,6 +512,8 @@ module RBS
467
512
  end
468
513
 
469
514
  class InconsistentClassModuleAliasError < BaseError
515
+ include DetailedMessageable
516
+
470
517
  attr_reader :alias_entry
471
518
 
472
519
  def initialize(entry)
@@ -482,9 +529,15 @@ module RBS
482
529
 
483
530
  super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{expected_kind} `#{entry.decl.new_name}` cannot be an alias of a #{actual_kind} `#{entry.decl.old_name}`"
484
531
  end
532
+
533
+ def location
534
+ @alias_entry.decl.location
535
+ end
485
536
  end
486
537
 
487
538
  class CyclicClassAliasDefinitionError < BaseError
539
+ include DetailedMessageable
540
+
488
541
  attr_reader :alias_entry
489
542
 
490
543
  def initialize(entry)
@@ -492,5 +545,9 @@ module RBS
492
545
 
493
546
  super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{alias_entry.decl.new_name} is a cyclic definition"
494
547
  end
548
+
549
+ def location
550
+ @alias_entry.decl.location
551
+ end
495
552
  end
496
553
  end
@@ -0,0 +1,31 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ module FileFinder
5
+ module_function
6
+
7
+ def self.each_file(path, immediate:, skip_hidden:, &block)
8
+ return enum_for(__method__, path, immediate: immediate, skip_hidden: skip_hidden) unless block
9
+
10
+ case
11
+ when path.file?
12
+ if path.extname == ".rbs" || immediate
13
+ yield path
14
+ end
15
+
16
+ when path.directory?
17
+ if path.basename.to_s.start_with?("_")
18
+ if skip_hidden
19
+ unless immediate
20
+ return
21
+ end
22
+ end
23
+ end
24
+
25
+ path.children.sort.each do |child|
26
+ each_file(child, immediate: false, skip_hidden: skip_hidden, &block)
27
+ end
28
+ end
29
+ end
30
+ end
31
+ end
@@ -2,14 +2,14 @@
2
2
 
3
3
  module RBS
4
4
  class Parser
5
- def self.parse_type(source, range: 0..., variables: [])
5
+ def self.parse_type(source, range: 0..., variables: [], require_eof: false)
6
6
  buf = buffer(source)
7
- _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables)
7
+ _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
8
8
  end
9
9
 
10
- def self.parse_method_type(source, range: 0..., variables: [])
10
+ def self.parse_method_type(source, range: 0..., variables: [], require_eof: false)
11
11
  buf = buffer(source)
12
- _parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables)
12
+ _parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables, require_eof)
13
13
  end
14
14
 
15
15
  def self.parse_signature(source)
@@ -215,7 +215,8 @@ module RBS
215
215
  when :include
216
216
  args.each do |arg|
217
217
  if (name = const_to_name(arg, context: context))
218
- decls << AST::Members::Include.new(
218
+ klass = context.singleton ? AST::Members::Extend : AST::Members::Include
219
+ decls << klass.new(
219
220
  name: name,
220
221
  args: [],
221
222
  annotations: [],
@@ -0,0 +1,184 @@
1
+ # frozen_string_literal: true
2
+
3
+ module RBS
4
+ class Subtractor
5
+ def initialize(minuend, subtrahend)
6
+ @minuend = minuend
7
+ @subtrahend = subtrahend
8
+ end
9
+
10
+ def call(minuend = @minuend, context: nil)
11
+ minuend.map do |decl|
12
+ case decl
13
+ when AST::Declarations::Constant
14
+ name = absolute_typename(decl.name, context: context)
15
+ decl unless @subtrahend.constant_name?(name)
16
+ when AST::Declarations::Interface
17
+ name = absolute_typename(decl.name, context: context)
18
+ decl unless @subtrahend.interface_name?(name)
19
+ when AST::Declarations::Class, AST::Declarations::Module
20
+ name = absolute_typename(decl.name, context: context)
21
+ case
22
+ when @subtrahend.class_decl?(name) && decl.is_a?(AST::Declarations::Class)
23
+ filter_members(decl, context: context)
24
+ when @subtrahend.module_decl?(name) && decl.is_a?(AST::Declarations::Module)
25
+ filter_members(decl, context: context)
26
+ when @subtrahend.constant_name?(name)
27
+ nil
28
+ else
29
+ decl
30
+ end
31
+ when AST::Declarations::Global
32
+ decl unless @subtrahend.global_decls[decl.name]
33
+ when AST::Declarations::TypeAlias
34
+ name = absolute_typename(decl.name, context: context)
35
+ decl unless @subtrahend.type_alias_decls[name]
36
+ when AST::Declarations::ClassAlias
37
+ name = absolute_typename(decl.new_name, context: context)
38
+ decl unless @subtrahend.class_alias?(name) || @subtrahend.class_decl?(name)
39
+ when AST::Declarations::ModuleAlias
40
+ name = absolute_typename(decl.new_name, context: context)
41
+ decl unless @subtrahend.module_alias?(name) || @subtrahend.module_decl?(name)
42
+ else
43
+ raise "unknwon decl: #{(_ = decl).class}"
44
+ end
45
+ end.compact
46
+ end
47
+
48
+ private def filter_members(decl, context:)
49
+ owner = absolute_typename(decl.name, context: context)
50
+
51
+ context = _ = [context, decl.name]
52
+ children = call(decl.each_decl.to_a, context: context) +
53
+ decl.each_member.reject { |m| member_exist?(owner, m, context: context) }
54
+ return nil if children.empty?
55
+
56
+ update_decl(decl, members: children)
57
+ end
58
+
59
+ private def member_exist?(owner, member, context:)
60
+ case member
61
+ when AST::Members::MethodDefinition
62
+ method_exist?(owner, member.name, member.kind)
63
+ when AST::Members::Alias
64
+ method_exist?(owner, member.new_name, member.kind)
65
+ when AST::Members::AttrReader
66
+ method_exist?(owner, member.name, member.kind)
67
+ when AST::Members::AttrWriter
68
+ method_exist?(owner, :"#{member.name}=", member.kind)
69
+ when AST::Members::AttrAccessor
70
+ # TODO: It unexpectedly removes attr_accessor even if either reader or writer does not exist in the subtrahend.
71
+ method_exist?(owner, member.name, member.kind) || method_exist?(owner, :"#{member.name}=", member.kind)
72
+ when AST::Members::InstanceVariable
73
+ ivar_exist?(owner, member.name, :instance)
74
+ when AST::Members::ClassInstanceVariable
75
+ ivar_exist?(owner, member.name, :singleton)
76
+ when AST::Members::ClassVariable
77
+ cvar_exist?(owner, member.name)
78
+ when AST::Members::Include, AST::Members::Extend, AST::Members::Prepend
79
+ mixin_exist?(owner, member, context: context)
80
+ when AST::Members::Public, AST::Members::Private
81
+ # They should not be removed even if the subtrahend has them.
82
+ false
83
+ else
84
+ raise "unknown member: #{(_ = member).class}"
85
+ end
86
+ end
87
+
88
+ private def method_exist?(owner, method_name, kind)
89
+ each_member(owner).any? do |m|
90
+ case m
91
+ when AST::Members::MethodDefinition
92
+ m.name == method_name && m.kind == kind
93
+ when AST::Members::Alias
94
+ m.new_name == method_name && m.kind == kind
95
+ when AST::Members::AttrReader
96
+ m.name == method_name && m.kind == kind
97
+ when AST::Members::AttrWriter
98
+ :"#{m.name}=" == method_name && m.kind == kind
99
+ when AST::Members::AttrAccessor
100
+ (m.name == method_name || :"#{m.name}=" == method_name) && m.kind == kind
101
+ end
102
+ end
103
+ end
104
+
105
+ private def ivar_exist?(owner, name, kind)
106
+ each_member(owner).any? do |m|
107
+ case m
108
+ when AST::Members::InstanceVariable
109
+ m.name == name
110
+ when AST::Members::Attribute
111
+ ivar_name = m.ivar_name == false ? nil : m.ivar_name || :"@#{m.name}"
112
+ ivar_name == name && m.kind == kind
113
+ end
114
+ end
115
+ end
116
+
117
+ private def cvar_exist?(owner, name)
118
+ each_member(owner).any? do |m|
119
+ case m
120
+ when AST::Members::ClassVariable
121
+ m.name == name
122
+ end
123
+ end
124
+ end
125
+
126
+ private def each_member(owner, &block)
127
+ return enum_for((__method__ or raise), owner) unless block
128
+
129
+ entry = @subtrahend.class_decls[owner]
130
+ return unless entry
131
+ decls = entry.decls.map { |d| d.decl }
132
+
133
+ decls.each { |d| d.members.each { |m| block.call(m) } }
134
+ end
135
+
136
+ private def mixin_exist?(owner, mixin, context:)
137
+ candidates = typename_candidates(mixin.name, context: context)
138
+ each_member(owner).any? do |m|
139
+ case m
140
+ when mixin.class
141
+ # @type var m: AST::Members::Include | AST::Members::Extend | AST::Members::Prepend
142
+ candidates.include?(m.name)
143
+ end
144
+ end
145
+ end
146
+
147
+ private def update_decl(decl, members:)
148
+ case decl
149
+ when AST::Declarations::Class
150
+ decl.class.new(name: decl.name, type_params: decl.type_params, super_class: decl.super_class,
151
+ annotations: decl.annotations, location: decl.location, comment: decl.comment,
152
+ members: members)
153
+ when AST::Declarations::Module
154
+ decl.class.new(name: decl.name, type_params: decl.type_params, self_types: decl.self_types,
155
+ annotations: decl.annotations, location: decl.location, comment: decl.comment,
156
+ members: members)
157
+ end
158
+ end
159
+
160
+ private def absolute_typename(name, context:)
161
+ while context
162
+ ns = context[1] or raise
163
+ name = name.with_prefix(ns.to_namespace)
164
+ context = _ = context[0]
165
+ end
166
+ name.absolute!
167
+ end
168
+
169
+ private def typename_candidates(name, context:)
170
+ ret = [name.absolute!, name.relative!]
171
+ return ret if name.absolute?
172
+
173
+ while context
174
+ ns = context[1] or raise
175
+ name = name.with_prefix(ns.to_namespace)
176
+ ret.concat [name.absolute!, name.relative!]
177
+
178
+ context = _ = context[0]
179
+ end
180
+
181
+ ret
182
+ end
183
+ end
184
+ end
data/lib/rbs/vendorer.rb CHANGED
@@ -31,7 +31,7 @@ module RBS
31
31
 
32
32
  if core_root = loader.core_root
33
33
  RBS.logger.info "Vendoring core RBSs in #{vendor_dir + "core"}..."
34
- loader.each_file(core_root, immediate: false, skip_hidden: true) do |file_path|
34
+ FileFinder.each_file(core_root, immediate: false, skip_hidden: true) do |file_path|
35
35
  paths << [file_path, Pathname("core") + file_path.relative_path_from(core_root)]
36
36
  end
37
37
  end
@@ -43,7 +43,7 @@ module RBS
43
43
 
44
44
  RBS.logger.info "Vendoring #{lib.name}(#{spec.version}) RBSs in #{vendor_dir + dest_dir}..."
45
45
 
46
- loader.each_file(path, skip_hidden: true, immediate: false) do |file_path|
46
+ FileFinder.each_file(path, skip_hidden: true, immediate: false) do |file_path|
47
47
  paths << [file_path, dest_dir + file_path.relative_path_from(path)]
48
48
  end
49
49
 
@@ -52,7 +52,7 @@ module RBS
52
52
 
53
53
  RBS.logger.info "Vendoring #{lib.name}(#{path.version}) RBSs in #{vendor_dir + dest_dir}..."
54
54
 
55
- loader.each_file(path.path, skip_hidden: true, immediate: false) do |file_path|
55
+ FileFinder.each_file(path.path, skip_hidden: true, immediate: false) do |file_path|
56
56
  paths << [file_path, dest_dir + file_path.relative_path_from(path.path)]
57
57
  end
58
58
  else
data/lib/rbs/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module RBS
4
- VERSION = "3.0.4"
4
+ VERSION = "3.1.0"
5
5
  end
data/lib/rbs/writer.rb CHANGED
@@ -167,6 +167,18 @@ module RBS
167
167
  puts "type #{name_and_params(decl.name, decl.type_params)} = #{decl.type}"
168
168
  }
169
169
 
170
+ when AST::Declarations::ClassAlias
171
+ write_comment decl.comment
172
+ write_loc_source(decl) {
173
+ puts "class #{decl.new_name} = #{decl.old_name}"
174
+ }
175
+
176
+ when AST::Declarations::ModuleAlias
177
+ write_comment decl.comment
178
+ write_loc_source(decl) {
179
+ puts "module #{decl.new_name} = #{decl.old_name}"
180
+ }
181
+
170
182
  when AST::Declarations::Interface
171
183
  write_comment decl.comment
172
184
  write_annotation decl.annotations
data/lib/rbs.rb CHANGED
@@ -16,6 +16,7 @@ require "rbs/namespace"
16
16
  require "rbs/type_name"
17
17
  require "rbs/types"
18
18
  require "rbs/method_type"
19
+ require "rbs/file_finder"
19
20
  require "rbs/ast/type_param"
20
21
  require "rbs/ast/directives"
21
22
  require "rbs/ast/declarations"
@@ -46,6 +47,7 @@ require "rbs/vendorer"
46
47
  require "rbs/validator"
47
48
  require "rbs/factory"
48
49
  require "rbs/repository"
50
+ require "rbs/subtractor"
49
51
  require "rbs/ancestor_graph"
50
52
  require "rbs/locator"
51
53
  require "rbs/type_alias_dependency"
data/sig/cli.rbs CHANGED
@@ -76,6 +76,8 @@ module RBS
76
76
 
77
77
  def run_annotate: (Array[String], top) -> void
78
78
 
79
+ def run_subtract: (Array[String], top) -> void
80
+
79
81
  def test_opt: (LibraryOptions) -> String?
80
82
 
81
83
  def collection_options: (Array[String]) -> OptionParser
@@ -36,7 +36,9 @@ module RBS
36
36
 
37
37
  # Inserts a entry to lockfile of a gem and its dependencies, if not included in `ignored_gems:`
38
38
  #
39
- def assign_gem: (name: String, version: String?, src_data: Sources::source_entry?, ignored_gems: Set[String]) -> void
39
+ # * If `skip:` is true, it skips adding the gem, but adds it's dependencies.
40
+ #
41
+ def assign_gem: (name: String, version: String?, src_data: Sources::source_entry?, ignored_gems: Set[String], ?skip: bool) -> void
40
42
 
41
43
  def assign_stdlib: (name: String, from_gem: String?) -> void
42
44
 
@@ -3,23 +3,25 @@ module RBS
3
3
  #
4
4
  # Set up your configuration through repository and `#add` method.
5
5
  #
6
- # # Set up the repository to load library RBSs from.
7
- # repo = RBS::Repository.default
8
- # repo.add(Pathname("vendor/rbs/gem-rbs"))
9
- # repo.add(Pathname("vendor/rbs/internal-rbs"))
6
+ # ```ruby
7
+ # # Set up the repository to load library RBSs from.
8
+ # repo = RBS::Repository.default
9
+ # repo.add(Pathname("vendor/rbs/gem-rbs"))
10
+ # repo.add(Pathname("vendor/rbs/internal-rbs"))
10
11
  #
11
- # loader = RBS::EnvironmentLoader.new(repository: repo)
12
+ # loader = RBS::EnvironmentLoader.new(repository: repo)
12
13
  #
13
- # # Add libraries to load RBS files.
14
- # loader.add(library: "minitest")
15
- # loader.add(library: "rbs", version: "1.0.0")
14
+ # # Add libraries to load RBS files.
15
+ # loader.add(library: "minitest")
16
+ # loader.add(library: "rbs", version: "1.0.0")
16
17
  #
17
- # # Add dirs to load RBS files from.
18
- # loader.add(path: Pathname("sig"))
18
+ # # Add dirs to load RBS files from.
19
+ # loader.add(path: Pathname("sig"))
19
20
  #
20
- # # Load RBSs into an environment.
21
- # environment = RBS::Environment.new()
22
- # loader.load(env: environment)
21
+ # # Load RBSs into an environment.
22
+ # environment = RBS::Environment.new()
23
+ # loader.load(env: environment)
24
+ # ```
23
25
  #
24
26
  class EnvironmentLoader
25
27
  class UnknownLibraryError < StandardError
@@ -35,6 +37,8 @@ module RBS
35
37
  def initialize: (name: String, version: String?) -> void
36
38
  end
37
39
 
40
+ include FileFinder
41
+
38
42
  DEFAULT_CORE_ROOT: Pathname
39
43
 
40
44
  attr_reader core_root: Pathname?
@@ -103,7 +107,5 @@ module RBS
103
107
  def each_signature: () { (source, Pathname, Buffer, Array[AST::Declarations::t], Array[AST::Directives::t]) -> void } -> void
104
108
 
105
109
  def each_dir: { (source, Pathname) -> void } -> void
106
-
107
- def each_file: (Pathname path, immediate: boolish, skip_hidden: boolish) { (Pathname) -> void } -> void
108
110
  end
109
111
  end
@@ -0,0 +1,6 @@
1
+ module RBS
2
+ module FileFinder
3
+ def self?.each_file: (Pathname path, immediate: boolish, skip_hidden: boolish) { (Pathname) -> void } -> void
4
+ | (Pathname path, immediate: boolish, skip_hidden: boolish) -> Enumerator[Pathname, void]
5
+ end
6
+ end
data/sig/manifest.yaml CHANGED
@@ -5,3 +5,4 @@ dependencies:
5
5
  - name: optparse
6
6
  - name: tsort
7
7
  - name: rdoc
8
+ - name: abbrev
data/sig/parser.rbs CHANGED
@@ -2,8 +2,7 @@ module RBS
2
2
  class Parser
3
3
  # Parse a method type and return it
4
4
  #
5
- # When `pos` keyword is specified, skips the first `pos` characters from the input.
6
- # If no token is left in the input, it returns `nil`.
5
+ # When `range` keyword is specified, it starts parsing from the `begin` to the `endo` the range.
7
6
  #
8
7
  # ```ruby
9
8
  # RBS::Parser.parse_method_type("() -> void") # => `() -> void`
@@ -12,12 +11,21 @@ module RBS
12
11
  # RBS::Parser.parse_method_type("() -> void () -> String", range: 23...) # => nil
13
12
  # ```
14
13
  #
15
- def self.parse_method_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol]) -> MethodType?
14
+ # When `require_eof` is `true`, an error is raised if more tokens are left in the input.
15
+ # (Defaults to `false`.)
16
+ #
17
+ # ```ruby
18
+ # RBS::Parser.parse_method_type("() -> void () -> String", require_eof: false) # => `() -> void`
19
+ # RBS::Parser.parse_method_type("() -> void () -> String", require_eof: true) # => Raises an error
20
+ #
21
+ # RBS::Parser.parse_method_type("", require_eof: true) # => nil
22
+ # ```
23
+ #
24
+ def self.parse_method_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool) -> MethodType?
16
25
 
17
26
  # Parse a type and return it
18
27
  #
19
- # When `pos` keyword is specified, skips the first `pos` characters from the input.
20
- # If no token is left in the input, it returns `nil`.
28
+ # When `range` keyword is specified, it starts parsing from the `begin` to the `endo` the range.
21
29
  #
22
30
  # ```ruby
23
31
  # RBS::Parser.parse_type("String") # => `String`
@@ -26,7 +34,17 @@ module RBS
26
34
  # RBS::Parser.parse_type("String Integer", pos: 14...) # => nil
27
35
  # ```
28
36
  #
29
- def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol]) -> Types::t?
37
+ # When `require_eof` is `true`, an error is raised if more tokens are left in the input.
38
+ # (Defaults to `false`.)
39
+ #
40
+ # ```ruby
41
+ # RBS::Parser.parse_type("String untyped", require_eof: false) # => `String`
42
+ # RBS::Parser.parse_type("String untyped", require_eof: true) # => Raises an error
43
+ #
44
+ # RBS::Parser.parse_type("", require_eof: true) # => nil
45
+ # ```
46
+ #
47
+ def self.parse_type: (Buffer | String, ?range: Range[Integer?], ?variables: Array[Symbol], ?require_eof: bool) -> Types::t?
30
48
 
31
49
  # Parse whole RBS file and return an array of declarations
32
50
  #
@@ -38,9 +56,9 @@ module RBS
38
56
 
39
57
  def self.buffer: (String | Buffer source) -> Buffer
40
58
 
41
- def self._parse_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables) -> Types::t?
59
+ def self._parse_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof) -> Types::t?
42
60
 
43
- def self._parse_method_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables) -> MethodType?
61
+ def self._parse_method_type: (Buffer, Integer start_pos, Integer end_pos, Array[Symbol] variables, bool require_eof) -> MethodType?
44
62
 
45
63
  def self._parse_signature: (Buffer, Integer end_pos) -> [Array[AST::Directives::t], Array[AST::Declarations::t]]
46
64