rbs 3.0.0.dev.1 → 3.0.0.dev.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (75) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby.yml +0 -3
  3. data/CHANGELOG.md +28 -0
  4. data/Gemfile.lock +2 -2
  5. data/README.md +1 -0
  6. data/Rakefile +75 -1
  7. data/core/array.rbs +1 -1
  8. data/core/builtin.rbs +1 -1
  9. data/core/hash.rbs +1 -1
  10. data/core/module.rbs +1 -1
  11. data/ext/rbs_extension/constants.c +16 -2
  12. data/ext/rbs_extension/constants.h +8 -1
  13. data/ext/rbs_extension/extconf.rb +1 -1
  14. data/ext/rbs_extension/lexer.c +834 -777
  15. data/ext/rbs_extension/lexer.h +3 -1
  16. data/ext/rbs_extension/lexer.re +3 -1
  17. data/ext/rbs_extension/lexstate.c +4 -2
  18. data/ext/rbs_extension/parser.c +264 -44
  19. data/ext/rbs_extension/ruby_objs.c +56 -2
  20. data/ext/rbs_extension/ruby_objs.h +7 -1
  21. data/lib/rbs/annotate/rdoc_annotator.rb +1 -1
  22. data/lib/rbs/ast/declarations.rb +49 -2
  23. data/lib/rbs/ast/directives.rb +39 -0
  24. data/lib/rbs/cli.rb +32 -18
  25. data/lib/rbs/collection/config/lockfile_generator.rb +25 -20
  26. data/lib/rbs/collection/config.rb +2 -2
  27. data/lib/rbs/collection/sources/git.rb +1 -1
  28. data/lib/rbs/definition_builder/ancestor_builder.rb +24 -8
  29. data/lib/rbs/definition_builder.rb +8 -8
  30. data/lib/rbs/environment/use_map.rb +77 -0
  31. data/lib/rbs/environment.rb +352 -83
  32. data/lib/rbs/environment_loader.rb +9 -7
  33. data/lib/rbs/environment_walker.rb +1 -1
  34. data/lib/rbs/errors.rb +34 -37
  35. data/lib/rbs/locator.rb +1 -1
  36. data/lib/rbs/parser_aux.rb +8 -6
  37. data/lib/rbs/resolver/constant_resolver.rb +23 -7
  38. data/lib/rbs/resolver/type_name_resolver.rb +2 -1
  39. data/lib/rbs/sorter.rb +3 -3
  40. data/lib/rbs/test/setup.rb +1 -1
  41. data/lib/rbs/type_alias_dependency.rb +1 -1
  42. data/lib/rbs/type_alias_regularity.rb +3 -3
  43. data/lib/rbs/validator.rb +23 -2
  44. data/lib/rbs/variance_calculator.rb +2 -2
  45. data/lib/rbs/version.rb +1 -1
  46. data/lib/rbs/writer.rb +28 -2
  47. data/lib/rbs.rb +2 -2
  48. data/lib/rdoc_plugin/parser.rb +2 -2
  49. data/rbs.gemspec +1 -1
  50. data/sig/ancestor_graph.rbs +22 -2
  51. data/sig/collection/config/lockfile_generator.rbs +8 -10
  52. data/sig/collection/config.rbs +1 -1
  53. data/sig/collection/sources.rbs +12 -6
  54. data/sig/constant.rbs +1 -1
  55. data/sig/declarations.rbs +36 -3
  56. data/sig/definition.rbs +1 -1
  57. data/sig/definition_builder.rbs +0 -1
  58. data/sig/directives.rbs +61 -0
  59. data/sig/environment.rbs +150 -28
  60. data/sig/environment_loader.rbs +1 -1
  61. data/sig/errors.rbs +22 -1
  62. data/sig/parser.rbs +8 -15
  63. data/sig/resolver/constant_resolver.rbs +1 -2
  64. data/sig/shims/bundler.rbs +18 -0
  65. data/sig/shims/rubygems.rbs +6 -0
  66. data/sig/use_map.rbs +35 -0
  67. data/sig/validator.rbs +12 -5
  68. data/sig/writer.rbs +4 -2
  69. metadata +7 -9
  70. data/lib/rbs/constant_table.rb +0 -167
  71. data/lib/rbs/type_name_resolver.rb +0 -67
  72. data/sig/constant_table.rbs +0 -30
  73. data/sig/type_name_resolver.rbs +0 -26
  74. data/steep/Gemfile +0 -3
  75. data/steep/Gemfile.lock +0 -61
@@ -95,9 +95,11 @@ module RBS
95
95
  # @type var loaded: Array[[AST::Declarations::t, Pathname, source]]
96
96
  loaded = []
97
97
 
98
- each_decl do |decl, buf, source, path|
99
- env << decl
100
- loaded << [decl, path, source]
98
+ each_signature do |source, path, buffer, decls, dirs|
99
+ decls.each do |decl|
100
+ loaded << [decl, path, source]
101
+ end
102
+ env.add_signature(buffer: buffer, directives: dirs, decls: decls)
101
103
  end
102
104
 
103
105
  loaded
@@ -148,7 +150,7 @@ module RBS
148
150
  end
149
151
  end
150
152
 
151
- def each_decl
153
+ def each_signature
152
154
  files = Set[]
153
155
 
154
156
  each_dir do |source, dir|
@@ -160,9 +162,9 @@ module RBS
160
162
  files << path
161
163
  buffer = Buffer.new(name: path.to_s, content: path.read(encoding: "UTF-8"))
162
164
 
163
- Parser.parse_signature(buffer).each do |decl|
164
- yield decl, buffer, source, path
165
- end
165
+ _, dirs, decls = Parser.parse_signature(buffer)
166
+
167
+ yield source, path, buffer, decls, dirs
166
168
  end
167
169
  end
168
170
  end
@@ -36,7 +36,7 @@ module RBS
36
36
  env.interface_decls.each_key do |type_name|
37
37
  yield TypeNameNode.new(type_name: type_name)
38
38
  end
39
- env.alias_decls.each_key do |type_name|
39
+ env.type_alias_decls.each_key do |type_name|
40
40
  yield TypeNameNode.new(type_name: type_name)
41
41
  end
42
42
  end
data/lib/rbs/errors.rb CHANGED
@@ -119,19 +119,7 @@ module RBS
119
119
  end
120
120
 
121
121
  def self.check!(type_name, env:, location:)
122
- dic = case
123
- when type_name.class?
124
- env.class_decls
125
- when type_name.alias?
126
- env.alias_decls
127
- when type_name.interface?
128
- env.interface_decls
129
- else
130
- raise
131
- end
132
-
133
- dic.key?(type_name) or raise new(type_name: type_name, location: location)
134
-
122
+ env.type_name?(type_name) or raise new(type_name: type_name, location: location)
135
123
  type_name
136
124
  end
137
125
  end
@@ -148,7 +136,7 @@ module RBS
148
136
  end
149
137
 
150
138
  def self.check!(type_name, env:, location:)
151
- if decl = env.class_decls[type_name]
139
+ if env.module_name?(type_name)
152
140
  return
153
141
  end
154
142
 
@@ -166,7 +154,7 @@ module RBS
166
154
  end
167
155
 
168
156
  def self.check!(super_decl, env:)
169
- return if env.class_decls[super_decl.name].is_a?(Environment::ClassEntry)
157
+ return if env.class_decl?(super_decl.name) || env.class_alias?(super_decl.name)
170
158
 
171
159
  raise new(super_decl)
172
160
  end
@@ -186,16 +174,7 @@ module RBS
186
174
  def self.check!(self_type, env:)
187
175
  type_name = self_type.name
188
176
 
189
- dic = case
190
- when type_name.class?
191
- env.class_decls
192
- when type_name.interface?
193
- env.interface_decls
194
- else
195
- raise
196
- end
197
-
198
- dic.key?(type_name) or raise new(type_name: type_name, location: self_type.location)
177
+ (env.module_name?(type_name) || env.interface_name?(type_name)) or raise new(type_name: type_name, location: self_type.location)
199
178
  end
200
179
  end
201
180
 
@@ -215,16 +194,7 @@ module RBS
215
194
  end
216
195
 
217
196
  def self.check!(type_name, env:, member:)
218
- dic = case
219
- when type_name.class?
220
- env.class_decls
221
- when type_name.interface?
222
- env.interface_decls
223
- else
224
- raise
225
- end
226
-
227
- dic.key?(type_name) or raise new(type_name: type_name, member: member)
197
+ (env.module_name?(type_name) || env.interface_name?(type_name)) or raise new(type_name: type_name, member: member)
228
198
  end
229
199
  end
230
200
 
@@ -416,8 +386,7 @@ module RBS
416
386
  end
417
387
 
418
388
  def self.check!(type_name:, env:, member:)
419
- case env.class_decls[member.name]
420
- when Environment::ClassEntry
389
+ if env.class_decl?(member.name)
421
390
  raise new(type_name: type_name, member: member)
422
391
  end
423
392
  end
@@ -478,4 +447,32 @@ module RBS
478
447
  super "#{Location.to_string(location)}: Cyclic type parameter bound is prohibited"
479
448
  end
480
449
  end
450
+
451
+ class InconsistentClassModuleAliasError < BaseError
452
+ attr_reader :alias_entry
453
+
454
+ def initialize(entry)
455
+ @alias_entry = entry
456
+
457
+ expected_kind, actual_kind =
458
+ case entry
459
+ when Environment::ModuleAliasEntry
460
+ ["module", "class"]
461
+ when Environment::ClassAliasEntry
462
+ ["class", "module"]
463
+ end
464
+
465
+ 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}`"
466
+ end
467
+ end
468
+
469
+ class CyclicClassAliasDefinitionError < BaseError
470
+ attr_reader :alias_entry
471
+
472
+ def initialize(entry)
473
+ @alias_entry = entry
474
+
475
+ super "#{Location.to_string(entry.decl.location&.[](:old_name))}: A #{alias_entry.decl.new_name} is a cyclic definition"
476
+ end
477
+ end
481
478
  end
data/lib/rbs/locator.rb CHANGED
@@ -95,7 +95,7 @@ module RBS
95
95
  when AST::Declarations::Constant, AST::Declarations::Global
96
96
  find_in_type(pos, array: array, type: decl.type) and return true
97
97
 
98
- when AST::Declarations::Alias
98
+ when AST::Declarations::TypeAlias
99
99
  find_in_type(pos, array: array, type: decl.type) and return true
100
100
  end
101
101
 
@@ -2,19 +2,21 @@
2
2
 
3
3
  module RBS
4
4
  class Parser
5
- def self.parse_type(source, line: nil, column: nil, range: nil, variables: [])
5
+ def self.parse_type(source, range: 0..., variables: [])
6
6
  buf = buffer(source)
7
- _parse_type(buf, range&.begin || 0, range&.end || buf.last_position, variables, range.nil?)
7
+ _parse_type(buf, range.begin || 0, range.end || buf.last_position, variables)
8
8
  end
9
9
 
10
- def self.parse_method_type(source, line: nil, column: nil, range: nil, variables: [])
10
+ def self.parse_method_type(source, range: 0..., variables: [])
11
11
  buf = buffer(source)
12
- _parse_method_type(buf, range&.begin || 0, range&.end || buf.last_position, variables, range.nil?)
12
+ _parse_method_type(buf, range.begin || 0, range.end || buf.last_position, variables)
13
13
  end
14
14
 
15
- def self.parse_signature(source, line: nil, column: nil)
15
+ def self.parse_signature(source)
16
16
  buf = buffer(source)
17
- _parse_signature(buf, buf.last_position)
17
+ dirs, decls = _parse_signature(buf, buf.last_position)
18
+
19
+ [buf, dirs, decls]
18
20
  end
19
21
 
20
22
  def self.buffer(source)
@@ -18,20 +18,33 @@ module RBS
18
18
  end
19
19
 
20
20
  environment.class_decls.each do |name, entry|
21
+ constant = constant_of_module(name, entry)
22
+
21
23
  unless name.namespace.empty?
22
24
  parent = name.namespace.to_type_name
23
-
24
25
  table = children_table[parent] or raise
25
- constant = constant_of_module(name, entry)
26
26
  else
27
27
  table = toplevel
28
- constant = constant_of_module(name, entry)
29
28
  end
30
29
 
31
30
  table[name.name] = constant
32
31
  constants_table[name] = constant
33
32
  end
34
33
 
34
+ environment.class_alias_decls.each do |name, entry|
35
+ normalized_entry = environment.normalized_module_class_entry(name) or next
36
+ constant = constant_of_module(name, normalized_entry)
37
+
38
+ # Insert class/module aliases into `children_table` and `toplevel` table
39
+ unless name.namespace.empty?
40
+ normalized_parent = environment.normalize_module_name?(name.namespace.to_type_name) or raise
41
+ table = children_table[normalized_parent] or raise
42
+ table[name.name] = constant
43
+ else
44
+ toplevel[name.name] = constant
45
+ end
46
+ end
47
+
35
48
  environment.constant_decls.each do |name, entry|
36
49
  unless name.namespace.empty?
37
50
  parent = name.namespace.to_type_name
@@ -97,6 +110,8 @@ module RBS
97
110
  end
98
111
 
99
112
  def children(module_name)
113
+ module_name = builder.env.normalize_module_name(module_name)
114
+
100
115
  unless child_constants_cache.key?(module_name)
101
116
  load_child_constants(module_name)
102
117
  end
@@ -113,6 +128,7 @@ module RBS
113
128
  else
114
129
  constants_from_ancestors(BuiltinNames::Object.name, constants: consts)
115
130
  end
131
+
116
132
  constants_from_context(context, constants: consts) or return
117
133
  constants_itself(context, constants: consts)
118
134
 
@@ -151,7 +167,7 @@ module RBS
151
167
  constants_from_context(parent, constants: constants) or return false
152
168
 
153
169
  if last
154
- consts = table.children(last) or return false
170
+ consts = table.children(builder.env.normalize_module_name(last)) or return false
155
171
  constants.merge!(consts)
156
172
  end
157
173
  end
@@ -160,14 +176,14 @@ module RBS
160
176
  end
161
177
 
162
178
  def constants_from_ancestors(module_name, constants:)
163
- entry = builder.env.class_decls[module_name]
179
+ entry = builder.env.normalized_module_class_entry(module_name) or raise
164
180
 
165
- if entry.is_a?(Environment::ModuleEntry)
181
+ if entry.is_a?(Environment::ClassEntry) || entry.is_a?(Environment::ModuleEntry)
166
182
  constants.merge!(table.children(BuiltinNames::Object.name) || raise)
167
183
  constants.merge!(table.toplevel)
168
184
  end
169
185
 
170
- builder.ancestor_builder.instance_ancestors(module_name).ancestors.reverse_each do |ancestor|
186
+ builder.ancestor_builder.instance_ancestors(entry.name).ancestors.reverse_each do |ancestor|
171
187
  if ancestor.is_a?(Definition::Ancestor::Instance)
172
188
  case ancestor.source
173
189
  when AST::Members::Include, :super, nil
@@ -12,7 +12,8 @@ module RBS
12
12
 
13
13
  all_names.merge(env.class_decls.keys)
14
14
  all_names.merge(env.interface_decls.keys)
15
- all_names.merge(env.alias_decls.keys)
15
+ all_names.merge(env.type_alias_decls.keys)
16
+ all_names.merge(env.class_alias_decls.keys)
16
17
  end
17
18
 
18
19
  def try_cache(query)
data/lib/rbs/sorter.rb CHANGED
@@ -15,7 +15,7 @@ module RBS
15
15
  stdout.puts "Opening #{path}..."
16
16
 
17
17
  buffer = Buffer.new(name: path, content: path.read)
18
- sigs = Parser.parse_signature(buffer)
18
+ _, _, sigs = Parser.parse_signature(buffer)
19
19
 
20
20
  sigs.each do |m|
21
21
  sort_decl! m
@@ -30,7 +30,7 @@ module RBS
30
30
 
31
31
  def group(member)
32
32
  case member
33
- when Declarations::Alias
33
+ when Declarations::TypeAlias
34
34
  -3
35
35
  when Declarations::Constant
36
36
  -2
@@ -100,7 +100,7 @@ module RBS
100
100
  member.new_name.to_s
101
101
  when Declarations::Constant
102
102
  member.name.to_s
103
- when Declarations::Alias
103
+ when Declarations::TypeAlias
104
104
  member.name.to_s
105
105
  when Declarations::Class, Declarations::Module
106
106
  member.name.to_s
@@ -67,7 +67,7 @@ TracePoint.trace :end do |tp|
67
67
 
68
68
  if class_name
69
69
  if filter.any? {|f| match(to_absolute_typename(f).to_s, class_name.to_s) } && skips.none? {|f| match(f, class_name.to_s) }
70
- if env.class_decls.key?(class_name)
70
+ if env.module_name?(class_name)
71
71
  logger.info "Setting up hooks for #{class_name}"
72
72
  tester.install!(tp.self, sample_size: sample_size, unchecked_classes: unchecked_classes)
73
73
  end
@@ -32,7 +32,7 @@ module RBS
32
32
  # Initialize dependencies as an empty hash
33
33
  @dependencies = {}
34
34
  # Iterate over alias declarations inserted into environment
35
- env.alias_decls.each do |name, entry|
35
+ env.type_alias_decls.each do |name, entry|
36
36
  # Construct a directed graph by recursively extracting type aliases
37
37
  @direct_dependencies[name] = direct_dependency(entry.decl.type)
38
38
  # Initialize dependencies with an empty hash
@@ -57,7 +57,7 @@ module RBS
57
57
  end
58
58
 
59
59
  def build_alias_type(name)
60
- entry = env.alias_decls[name] or return
60
+ entry = env.type_alias_decls[name] or return
61
61
  unless entry.decl.type_params.empty?
62
62
  as = entry.decl.type_params.each.map {|param| Types::Variable.new(name: param.name, location: nil) }
63
63
  Types::Alias.new(name: name, args: as, location: nil)
@@ -81,13 +81,13 @@ module RBS
81
81
  def each_mutual_alias_defs(&block)
82
82
  # @type var each_node: TSort::_EachNode[TypeName]
83
83
  each_node = __skip__ = -> (&block) do
84
- env.alias_decls.each_value do |decl|
84
+ env.type_alias_decls.each_value do |decl|
85
85
  block[decl.name]
86
86
  end
87
87
  end
88
88
  # @type var each_child: TSort::_EachChild[TypeName]
89
89
  each_child = __skip__ = -> (name, &block) do
90
- if env.alias_decls.key?(name)
90
+ if env.type_alias_decls.key?(name)
91
91
  type = builder.expand_alias1(name)
92
92
  each_alias_type(type) do |ty|
93
93
  block[ty.name]
data/lib/rbs/validator.rb CHANGED
@@ -33,11 +33,12 @@ module RBS
33
33
 
34
34
  type_params = case type
35
35
  when Types::ClassInstance
36
- env.class_decls[type.name].type_params
36
+ entry = env.normalized_module_class_entry(type.name) or raise
37
+ entry.type_params
37
38
  when Types::Interface
38
39
  env.interface_decls[type.name].decl.type_params
39
40
  when Types::Alias
40
- env.alias_decls[type.name].decl.type_params
41
+ env.type_alias_decls[type.name].decl.type_params
41
42
  end
42
43
 
43
44
  InvalidTypeApplicationError.check!(
@@ -147,6 +148,26 @@ module RBS
147
148
  end
148
149
  end
149
150
 
151
+ def validate_class_alias(entry:)
152
+ case env.normalize_module_name?(entry.decl.new_name)
153
+ when nil
154
+ raise NoTypeFoundError.new(type_name: entry.decl.old_name, location: entry.decl.location&.[](:old_name))
155
+ when false
156
+ raise CyclicClassAliasDefinitionError.new(entry)
157
+ end
158
+
159
+ case entry
160
+ when Environment::ClassAliasEntry
161
+ unless env.class_entry(entry.decl.old_name)
162
+ raise InconsistentClassModuleAliasError.new(entry)
163
+ end
164
+ when Environment::ModuleAliasEntry
165
+ unless env.module_entry(entry.decl.old_name)
166
+ raise InconsistentClassModuleAliasError.new(entry)
167
+ end
168
+ end
169
+ end
170
+
150
171
  def type_alias_dependency
151
172
  @type_alias_dependency ||= TypeAliasDependency.new(env: env)
152
173
  end
@@ -108,7 +108,7 @@ module RBS
108
108
  end
109
109
 
110
110
  def in_type_alias(name:)
111
- decl = env.alias_decls[name].decl or raise
111
+ decl = env.type_alias_decls[name].decl or raise
112
112
  variables = decl.type_params.each.map(&:name)
113
113
  Result.new(variables: variables).tap do |result|
114
114
  type(decl.type, result: result, context: :covariant)
@@ -139,7 +139,7 @@ module RBS
139
139
  when Types::Interface
140
140
  env.interface_decls[type.name].decl.type_params
141
141
  when Types::Alias
142
- env.alias_decls[type.name].decl.type_params
142
+ env.type_alias_decls[type.name].decl.type_params
143
143
  end
144
144
 
145
145
  type.args.each.with_index do |ty, i|
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.0.dev.1"
4
+ VERSION = "3.0.0.dev.2"
5
5
  end
data/lib/rbs/writer.rb CHANGED
@@ -76,7 +76,16 @@ module RBS
76
76
  end
77
77
  end
78
78
 
79
- def write(decls)
79
+ def write(contents)
80
+ dirs = contents.select {|c| c.is_a?(AST::Directives::Base) } #: Array[AST::Directives::t]
81
+ decls = contents.select {|c| c.is_a?(AST::Declarations::Base) } #: Array[AST::Declarations::t]
82
+
83
+ dirs.each do |dir|
84
+ write_directive(dir)
85
+ end
86
+
87
+ puts unless dirs.empty?
88
+
80
89
  [nil, *decls].each_cons(2) do |prev, decl|
81
90
  raise unless decl
82
91
 
@@ -85,6 +94,23 @@ module RBS
85
94
  end
86
95
  end
87
96
 
97
+ def write_directive(dir)
98
+ clauses = dir.clauses.map do |clause|
99
+ case clause
100
+ when AST::Directives::Use::SingleClause
101
+ if clause.new_name
102
+ "#{clause.type_name} as #{clause.new_name}"
103
+ else
104
+ "#{clause.type_name}"
105
+ end
106
+ when AST::Directives::Use::WildcardClause
107
+ "#{clause.namespace}*"
108
+ end
109
+ end
110
+
111
+ puts "use #{clauses.join(", ")}"
112
+ end
113
+
88
114
  def write_decl(decl)
89
115
  case decl
90
116
  when AST::Declarations::Class
@@ -134,7 +160,7 @@ module RBS
134
160
  write_comment decl.comment
135
161
  puts "#{decl.name}: #{decl.type}"
136
162
 
137
- when AST::Declarations::Alias
163
+ when AST::Declarations::TypeAlias
138
164
  write_comment decl.comment
139
165
  write_annotation decl.annotations
140
166
  write_loc_source(decl) {
data/lib/rbs.rb CHANGED
@@ -17,10 +17,12 @@ require "rbs/type_name"
17
17
  require "rbs/types"
18
18
  require "rbs/method_type"
19
19
  require "rbs/ast/type_param"
20
+ require "rbs/ast/directives"
20
21
  require "rbs/ast/declarations"
21
22
  require "rbs/ast/members"
22
23
  require "rbs/ast/annotation"
23
24
  require "rbs/environment"
25
+ require "rbs/environment/use_map"
24
26
  require "rbs/environment_loader"
25
27
  require "rbs/builtin_names"
26
28
  require "rbs/definition"
@@ -32,7 +34,6 @@ require "rbs/substitution"
32
34
  require "rbs/constant"
33
35
  require "rbs/resolver/constant_resolver"
34
36
  require "rbs/resolver/type_name_resolver"
35
- require "rbs/constant_table"
36
37
  require "rbs/ast/comment"
37
38
  require "rbs/writer"
38
39
  require "rbs/prototype/helpers"
@@ -40,7 +41,6 @@ require "rbs/prototype/rbi"
40
41
  require "rbs/prototype/rb"
41
42
  require "rbs/prototype/runtime"
42
43
  require "rbs/prototype/node_usage"
43
- require "rbs/type_name_resolver"
44
44
  require "rbs/environment_walker"
45
45
  require "rbs/vendorer"
46
46
  require "rbs/validator"
@@ -14,8 +14,8 @@ module RBS
14
14
  end
15
15
 
16
16
  def scan
17
- ast = ::RBS::Parser.parse_signature(@content)
18
- ast.each do |decl|
17
+ _, _, decls = ::RBS::Parser.parse_signature(@content)
18
+ decls.each do |decl|
19
19
  parse_member(decl: decl, context: @top_level)
20
20
  end
21
21
  @top_level
data/rbs.gemspec CHANGED
@@ -28,7 +28,7 @@ Gem::Specification.new do |spec|
28
28
  # Specify which files should be added to the gem when it is released.
29
29
  # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
30
30
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin)/}) }
31
+ `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin|steep)/}) }
32
32
  end
33
33
  spec.extensions = %w{ext/rbs_extension/extconf.rb}
34
34
 
@@ -1,4 +1,22 @@
1
1
  module RBS
2
+ # AncestorGraph is a utility class that helps iterating through ancestors and decendants of a class/module
3
+ #
4
+ # ```ruby
5
+ # graph = AncestorGraph.new(env: env, ancestor_builder: ancestor_builder)
6
+ #
7
+ # graph.each_parent(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
8
+ # graph.each_ancestor(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
9
+ #
10
+ # graph.each_child(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
11
+ # graph.each_descendant(AncestorGraph::InstanceNode.new(type_name: TypeName("::Object")))
12
+ # ```
13
+ #
14
+ # Note that the class works for class/module declarations.
15
+ # All of the *alias* classes/modules are ignored.
16
+ #
17
+ # * Alias classes/modules doesn't count as a parent nor child
18
+ # * Passing alias classes/modules to the method doesn't yield anything
19
+ #
2
20
  class AncestorGraph
3
21
  class InstanceNode
4
22
  attr_reader type_name: TypeName
@@ -19,8 +37,6 @@ module RBS
19
37
 
20
38
  def initialize: (env: Environment, ?ancestor_builder: DefinitionBuilder::AncestorBuilder) -> void
21
39
 
22
- def build: () -> void
23
-
24
40
  def each_parent: (node) { (node) -> void } -> void
25
41
  | (node) -> Enumerator[node, void]
26
42
 
@@ -33,6 +49,10 @@ module RBS
33
49
  def each_descendant: (node, ?yielded: Set[node]) { (node) -> void } -> void
34
50
  | (node) -> Enumerator[node, void]
35
51
 
52
+ private
53
+
54
+ def build: () -> void
55
+
36
56
  def build_ancestors: (node, DefinitionBuilder::AncestorBuilder::OneAncestors) -> void
37
57
 
38
58
  def register: (parent: node, child: node) -> void
@@ -13,18 +13,18 @@ module RBS
13
13
  end
14
14
 
15
15
  attr_reader config: Config
16
- attr_reader gemfile_lock: Bundler::LockfileParser
17
16
 
18
17
  attr_reader lockfile: Lockfile
19
18
  attr_reader existing_lockfile: Lockfile?
20
19
 
21
- type gem_queue_entry = { name: String, version: String? }
20
+ attr_reader definition: Bundler::Definition
22
21
 
23
- @gem_queue: Array[gem_queue_entry]
22
+ # A hash table to look up a spec from name of the gem
23
+ attr_reader gem_hash: Hash[String, Bundler::LazySpecification]
24
24
 
25
- def self.generate: (config: Config, gemfile_lock_path: Pathname, ?with_lockfile: boolish) -> Lockfile
25
+ def self.generate: (config: Config, definition: Bundler::Definition, ?with_lockfile: boolish) -> Lockfile
26
26
 
27
- def initialize: (config: Config, gemfile_lock_path: Pathname, with_lockfile: boolish) -> void
27
+ def initialize: (config: Config, definition: Bundler::Definition, with_lockfile: boolish) -> void
28
28
 
29
29
  def generate: () -> void
30
30
 
@@ -34,14 +34,12 @@ module RBS
34
34
  #
35
35
  def validate_gemfile_lock_path!: (lock: Lockfile?, gemfile_lock_path: Pathname) -> void
36
36
 
37
- def assign_gem: (name: String, version: String?, ignored_gems: Set[String], src_data: Sources::source_entry?) -> void
37
+ # Inserts a entry to lockfile of a gem and its dependencies, if not included in `ignored_gems:`
38
+ #
39
+ def assign_gem: (name: String, version: String?, src_data: Sources::source_entry?, ignored_gems: Set[String]) -> void
38
40
 
39
41
  def assign_stdlib: (name: String, from_gem: String?) -> void
40
42
 
41
- def gemfile_lock_gems: () { (untyped) -> void } -> void
42
-
43
- def remove_ignored_gems!: () -> void
44
-
45
43
  # Find a source of a gem from ones registered in `config.sources`
46
44
  #
47
45
  # Returns `nil` if no source contains the definition of the gem.
@@ -23,7 +23,7 @@ module RBS
23
23
 
24
24
  def self.find_config_path: () -> Pathname?
25
25
 
26
- def self.generate_lockfile: (config_path: Pathname, gemfile_lock_path: Pathname, ?with_lockfile: boolish) -> [Config, Lockfile]
26
+ def self.generate_lockfile: (config_path: Pathname, definition: Bundler::Definition, ?with_lockfile: boolish) -> [Config, Lockfile]
27
27
 
28
28
  def self.from_path: (Pathname path) -> Config
29
29
 
@@ -78,28 +78,34 @@ module RBS
78
78
 
79
79
  def cp_r: (Pathname, Pathname) -> void
80
80
 
81
- # Ensure the git repository status is expected one
81
+ # Ensure the git repository exists, and
82
82
  #
83
- # * It exists, and
84
- # * The `HEAD` is the `revision`
83
+ # * When `revision` is a commit hash, the commit exists in the local repository, or
84
+ # * When `revision` is a branch name, the latest version is fetched from `origin`
85
+ #
86
+ # It may require a network connection to fetch or clone the repository from remote.
87
+ #
88
+ # * If `revision` is a commit hash and the commit doesn't exists in the local repository, it runs `git fetch`
89
+ # * If `revision` is a branch name, it runs `git fetch` once per instance
85
90
  #
86
91
  def setup!: [T] () { () -> T } -> T
87
92
  | () -> void
88
93
 
89
94
  def need_to_fetch?: (String revision) -> bool
90
95
 
96
+ # The full path of local git repository
91
97
  def git_dir: () -> Pathname
92
98
 
99
+ # The full path of `repo_dir` in the local git repository
93
100
  def gem_repo_dir: () -> Pathname
94
101
 
95
- def with_revision: [T] () { () -> T } -> T
96
-
97
102
  # Returns `true` if `revision` looks like a commit hash
98
- #
99
103
  def commit_hash?: () -> bool
100
104
 
105
+ # Executes a git command, raises an error if failed
101
106
  def git: (*String cmd, **untyped opt) -> String
102
107
 
108
+ # Executes a git command, returns `nil` if failed
103
109
  def git?: (*String cmd, **untyped opt) -> String?
104
110
 
105
111
  def sh!: (*String cmd, **untyped opt) -> String