rbs 1.5.1 → 1.7.0.beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (88) hide show
  1. checksums.yaml +4 -4
  2. data/.github/dependabot.yml +10 -0
  3. data/.github/workflows/ruby.yml +0 -4
  4. data/.gitignore +1 -0
  5. data/CHANGELOG.md +51 -0
  6. data/Gemfile +2 -0
  7. data/Rakefile +7 -22
  8. data/Steepfile +9 -1
  9. data/core/enumerator.rbs +1 -0
  10. data/core/io.rbs +3 -1
  11. data/core/kernel.rbs +4 -4
  12. data/core/trace_point.rbs +1 -1
  13. data/docs/collection.md +116 -0
  14. data/ext/rbs/extension/constants.c +140 -0
  15. data/ext/rbs/extension/constants.h +72 -0
  16. data/ext/rbs/extension/extconf.rb +3 -0
  17. data/ext/rbs/extension/lexer.c +1070 -0
  18. data/ext/rbs/extension/lexer.h +145 -0
  19. data/ext/rbs/extension/location.c +295 -0
  20. data/ext/rbs/extension/location.h +59 -0
  21. data/ext/rbs/extension/main.c +9 -0
  22. data/ext/rbs/extension/parser.c +2418 -0
  23. data/ext/rbs/extension/parser.h +23 -0
  24. data/ext/rbs/extension/parserstate.c +313 -0
  25. data/ext/rbs/extension/parserstate.h +141 -0
  26. data/ext/rbs/extension/rbs_extension.h +40 -0
  27. data/ext/rbs/extension/ruby_objs.c +585 -0
  28. data/ext/rbs/extension/ruby_objs.h +46 -0
  29. data/ext/rbs/extension/unescape.c +65 -0
  30. data/goodcheck.yml +1 -1
  31. data/lib/rbs/ast/comment.rb +0 -12
  32. data/lib/rbs/buffer.rb +4 -0
  33. data/lib/rbs/builtin_names.rb +1 -0
  34. data/lib/rbs/cli.rb +98 -10
  35. data/lib/rbs/collection/cleaner.rb +29 -0
  36. data/lib/rbs/collection/config/lockfile_generator.rb +95 -0
  37. data/lib/rbs/collection/config.rb +85 -0
  38. data/lib/rbs/collection/installer.rb +27 -0
  39. data/lib/rbs/collection/sources/git.rb +162 -0
  40. data/lib/rbs/collection/sources/rubygems.rb +40 -0
  41. data/lib/rbs/collection/sources/stdlib.rb +38 -0
  42. data/lib/rbs/collection/sources.rb +22 -0
  43. data/lib/rbs/collection.rb +13 -0
  44. data/lib/rbs/environment_loader.rb +12 -0
  45. data/lib/rbs/errors.rb +16 -1
  46. data/lib/rbs/location.rb +221 -217
  47. data/lib/rbs/location_aux.rb +108 -0
  48. data/lib/rbs/locator.rb +10 -7
  49. data/lib/rbs/parser_aux.rb +24 -0
  50. data/lib/rbs/repository.rb +13 -7
  51. data/lib/rbs/types.rb +2 -3
  52. data/lib/rbs/validator.rb +4 -1
  53. data/lib/rbs/version.rb +1 -1
  54. data/lib/rbs/writer.rb +4 -2
  55. data/lib/rbs.rb +4 -7
  56. data/rbs.gemspec +2 -1
  57. data/sig/ancestor_builder.rbs +2 -2
  58. data/sig/annotation.rbs +2 -2
  59. data/sig/builtin_names.rbs +1 -0
  60. data/sig/cli.rbs +5 -0
  61. data/sig/collection/cleaner.rbs +13 -0
  62. data/sig/collection/collections.rbs +112 -0
  63. data/sig/collection/config.rbs +69 -0
  64. data/sig/collection/installer.rbs +15 -0
  65. data/sig/collection.rbs +4 -0
  66. data/sig/comment.rbs +7 -7
  67. data/sig/constant_table.rbs +1 -1
  68. data/sig/declarations.rbs +9 -9
  69. data/sig/definition.rbs +1 -1
  70. data/sig/definition_builder.rbs +2 -2
  71. data/sig/environment_loader.rbs +3 -0
  72. data/sig/errors.rbs +30 -25
  73. data/sig/location.rbs +42 -79
  74. data/sig/locator.rbs +2 -2
  75. data/sig/members.rbs +7 -7
  76. data/sig/method_types.rbs +3 -3
  77. data/sig/parser.rbs +11 -21
  78. data/sig/polyfill.rbs +12 -3
  79. data/sig/repository.rbs +4 -0
  80. data/sig/types.rbs +45 -27
  81. data/sig/writer.rbs +1 -1
  82. data/stdlib/json/0/json.rbs +3 -3
  83. data/stdlib/objspace/0/objspace.rbs +406 -0
  84. data/stdlib/openssl/0/openssl.rbs +1 -1
  85. data/stdlib/tempfile/0/tempfile.rbs +270 -0
  86. data/steep/Gemfile.lock +10 -10
  87. metadata +43 -7
  88. data/lib/rbs/parser.rb +0 -3614
data/lib/rbs/locator.rb CHANGED
@@ -172,16 +172,19 @@ module RBS
172
172
 
173
173
  def find_in_loc(pos, location:, array:)
174
174
  if test_loc(pos, location: location)
175
- if location.is_a?(Location::WithChildren)
176
- location.optional_children.each do |key, range|
177
- if range === pos
178
- array.unshift(key)
179
- return true
175
+ if location.is_a?(Location)
176
+ location.each_optional_key do |key|
177
+ if loc = location[key]
178
+ if loc.range === pos
179
+ array.unshift(key)
180
+ return true
181
+ end
180
182
  end
181
183
  end
182
184
 
183
- location.required_children.each do |key, range|
184
- if range === pos
185
+ location.each_required_key do |key|
186
+ loc = location[key] or raise
187
+ if loc.range === pos
185
188
  array.unshift(key)
186
189
  return true
187
190
  end
@@ -0,0 +1,24 @@
1
+ module RBS
2
+ class Parser
3
+ def self.parse_type(source, line: 1, column: 0, variables: [])
4
+ _parse_type(buffer(source), line, column, variables)
5
+ end
6
+
7
+ def self.parse_method_type(source, line: 1, column: 0, variables: [])
8
+ _parse_method_type(buffer(source), line, column, variables)
9
+ end
10
+
11
+ def self.parse_signature(source, line: 1, column: 0)
12
+ _parse_signature(buffer(source), line, column)
13
+ end
14
+
15
+ def self.buffer(source)
16
+ case source
17
+ when String
18
+ Buffer.new(content: source, name: "a.rbs")
19
+ when Buffer
20
+ source
21
+ end
22
+ end
23
+ end
24
+ end
@@ -55,13 +55,8 @@ module RBS
55
55
  end
56
56
 
57
57
  def find_best_version(version)
58
- return latest_version unless version
59
-
60
- if v = version_names.reverse.bsearch {|v| v <= version ? true : false }
61
- versions[v]
62
- else
63
- oldest_version
64
- end
58
+ best_version = Repository.find_best_version(version, version_names)
59
+ versions[best_version]
65
60
  end
66
61
 
67
62
  def empty?
@@ -89,6 +84,17 @@ module RBS
89
84
  end
90
85
  end
91
86
 
87
+ def self.find_best_version(version, candidates)
88
+ candidates = candidates.sort
89
+ return candidates.last || raise unless version
90
+
91
+ if v = candidates.reverse.bsearch {|v| v <= version ? true : false }
92
+ v
93
+ else
94
+ candidates.first or raise
95
+ end
96
+ end
97
+
92
98
  def add(dir)
93
99
  dirs << dir
94
100
 
data/lib/rbs/types.rb CHANGED
@@ -1,4 +1,3 @@
1
-
2
1
  module RBS
3
2
  module Types
4
3
  module NoFreeVariables
@@ -434,7 +433,7 @@ module RBS
434
433
  return "{ }" if self.fields.empty?
435
434
 
436
435
  fields = self.fields.map do |key, type|
437
- if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/) && !key.match?(Parser::KEYWORDS_RE)
436
+ if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/) && !Parser::KEYWORDS.key?(key)
438
437
  "#{key}: #{type}"
439
438
  else
440
439
  "#{key.inspect} => #{type}"
@@ -691,7 +690,7 @@ module RBS
691
690
 
692
691
  def to_s
693
692
  if name
694
- if /\A#{Parser::KEYWORDS_RE}\z/.match?(name)
693
+ if Parser::KEYWORDS.key?(name)
695
694
  "#{type} `#{name}`"
696
695
  else
697
696
  "#{type} #{name}"
data/lib/rbs/validator.rb CHANGED
@@ -56,7 +56,10 @@ module RBS
56
56
 
57
57
  def validate_type_alias(entry:)
58
58
  @type_alias_dependency ||= TypeAliasDependency.new(env: env)
59
- raise RecursiveTypeAliasError.new(alias_names: [entry.decl.name], location: entry.decl.location) if @type_alias_dependency.circular_definition?(entry.decl.name)
59
+ if @type_alias_dependency.circular_definition?(entry.decl.name)
60
+ location = entry.decl.location or raise
61
+ raise RecursiveTypeAliasError.new(alias_names: [entry.decl.name], location: location)
62
+ end
60
63
  end
61
64
  end
62
65
  end
data/lib/rbs/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module RBS
2
- VERSION = "1.5.1"
2
+ VERSION = "1.7.0.beta.1"
3
3
  end
data/lib/rbs/writer.rb CHANGED
@@ -232,8 +232,10 @@ module RBS
232
232
  def method_name(name)
233
233
  s = name.to_s
234
234
 
235
- if [:tOPERATOR, :kAMP, :kHAT, :kSTAR, :kLT, :kEXCLAMATION, :kSTAR2, :kBAR].include?(Parser::PUNCTS[s]) ||
236
- (/\A[a-zA-Z_]\w*[?!=]?\z/.match?(s) && !/\Aself\??\z/.match?(s))
235
+ case s
236
+ when /\A(_?)[A-Za-z_]\w*(\?|!|=)?\Z/
237
+ s
238
+ when *%w(| ^ & <=> == === =~ > >= < <= << >> + - * / % ** ~ +@ -@ [] []= ` ! != !~)
237
239
  s
238
240
  else
239
241
  "`#{s}`"
data/lib/rbs.rb CHANGED
@@ -12,7 +12,6 @@ require "strscan"
12
12
  require "rbs/char_scanner"
13
13
  require "rbs/errors"
14
14
  require "rbs/buffer"
15
- require "rbs/location"
16
15
  require "rbs/namespace"
17
16
  require "rbs/type_name"
18
17
  require "rbs/types"
@@ -45,13 +44,11 @@ require "rbs/repository"
45
44
  require "rbs/ancestor_graph"
46
45
  require "rbs/locator"
47
46
  require "rbs/type_alias_dependency"
47
+ require "rbs/collection"
48
48
 
49
- begin
50
- require "rbs/parser"
51
- rescue LoadError
52
- STDERR.puts "Missing parser Ruby code? Running `rake parser` may solve the issue"
53
- raise
54
- end
49
+ require "rbs/extension"
50
+ require "rbs/parser_aux"
51
+ require "rbs/location_aux"
55
52
 
56
53
  module RBS
57
54
  class <<self
data/rbs.gemspec CHANGED
@@ -30,7 +30,8 @@ Gem::Specification.new do |spec|
30
30
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
31
31
  `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features|bin)/}) }
32
32
  end
33
- spec.files << "lib/rbs/parser.rb"
33
+ spec.extensions = %w{ext/rbs/extension/extconf.rb}
34
+
34
35
  spec.bindir = "exe"
35
36
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
36
37
  spec.require_paths = ["lib"]
@@ -82,7 +82,7 @@ module RBS
82
82
  def mixin_ancestors: (Environment::ClassEntry | Environment::ModuleEntry,
83
83
  TypeName,
84
84
  included_modules: Array[Definition::Ancestor::Instance]?,
85
- included_interfaces:Array[Definition::Ancestor::Instance]?,
85
+ included_interfaces: Array[Definition::Ancestor::Instance]?,
86
86
  prepended_modules: Array[Definition::Ancestor::Instance]?,
87
87
  extended_modules: Array[Definition::Ancestor::Instance]?,
88
88
  extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void
@@ -91,7 +91,7 @@ module RBS
91
91
  TypeName,
92
92
  align_params: Substitution?,
93
93
  included_modules: Array[Definition::Ancestor::Instance]?,
94
- included_interfaces:Array[Definition::Ancestor::Instance]?,
94
+ included_interfaces: Array[Definition::Ancestor::Instance]?,
95
95
  prepended_modules: Array[Definition::Ancestor::Instance]?,
96
96
  extended_modules: Array[Definition::Ancestor::Instance]?,
97
97
  extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void
data/sig/annotation.rbs CHANGED
@@ -10,9 +10,9 @@ module RBS
10
10
  #
11
11
  class Annotation
12
12
  attr_reader string: String
13
- attr_reader location: Location?
13
+ attr_reader location: Location[untyped, untyped]?
14
14
 
15
- def initialize: (string: String, location: Location?) -> void
15
+ def initialize: (string: String, location: Location[untyped, untyped]?) -> void
16
16
 
17
17
  def ==: (untyped other) -> bool
18
18
 
@@ -37,5 +37,6 @@ module RBS
37
37
  Regexp: Name
38
38
  TrueClass: Name
39
39
  FalseClass: Name
40
+ Numeric: Name
40
41
  end
41
42
  end
data/sig/cli.rbs CHANGED
@@ -2,6 +2,7 @@ module RBS
2
2
  class CLI
3
3
  class LibraryOptions
4
4
  attr_accessor core_root: Pathname?
5
+ attr_accessor config_path: Pathname?
5
6
 
6
7
  attr_reader libs: Array[String]
7
8
  attr_reader dirs: Array[String]
@@ -63,6 +64,10 @@ module RBS
63
64
 
64
65
  def run_test: (Array[String], LibraryOptions) -> void
65
66
 
67
+ def run_collection: (Array[String], LibraryOptions) -> void
68
+
66
69
  def test_opt: (LibraryOptions) -> String?
70
+
71
+ def collection_options: (Array[String]) -> OptionParser
67
72
  end
68
73
  end
@@ -0,0 +1,13 @@
1
+ module RBS
2
+ module Collection
3
+ class Cleaner
4
+ attr_reader lock: Config
5
+
6
+ def initialize: (lockfile_path: Pathname) -> void
7
+
8
+ def clean: () -> void
9
+
10
+ def needed?: (String gem_name, String version) -> bool
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,112 @@
1
+ module RBS
2
+ module Collection
3
+ module Sources
4
+ def self.from_config_entry: (source_entry) -> _Source
5
+
6
+ interface _Source
7
+ def has?: (Config::gem_entry) -> boolish
8
+ def versions: (Config::gem_entry) -> Array[String]
9
+ def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
10
+ def to_lockfile: () -> source_entry
11
+ end
12
+
13
+ type source_entry = Git::source_entry
14
+ | Stdlib::source_entry
15
+ | Rubygems::source_entry
16
+
17
+ class Git
18
+ METADATA_FILENAME: String
19
+
20
+ type source_entry = {
21
+ 'type' => 'git',
22
+ 'name' => String,
23
+ 'remote' => String,
24
+ 'revision' => String,
25
+ 'repo_dir' => String?,
26
+ }
27
+
28
+ class CommandError < StandardError
29
+ end
30
+
31
+ attr_reader name: String
32
+ attr_reader remote: String
33
+ attr_reader repo_dir: String
34
+
35
+ def initialize: (name: String, revision: String, remote: String, repo_dir: String?) -> untyped
36
+
37
+ def has?: (Config::gem_entry) -> bool
38
+
39
+ def versions: (Config::gem_entry) -> Array[String]
40
+
41
+ def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
42
+
43
+ def to_lockfile: () -> source_entry
44
+
45
+ private
46
+
47
+ def _install: (dest: Pathname , config_entry: Config::gem_entry) -> void
48
+
49
+ def setup!: (revision: String) -> void
50
+
51
+ def need_to_fetch?: (String revision ) -> bool
52
+
53
+ def git_dir: () -> Pathname
54
+
55
+ def gem_repo_dir: () -> Pathname
56
+
57
+ def with_revision: [T] () { () -> T } -> T
58
+
59
+ def resolved_revision: () -> String
60
+
61
+ def resolve_revision: () -> String
62
+
63
+ def git: (*String cmd) -> String
64
+
65
+ def sh!: (*String cmd) -> String
66
+
67
+ def format_config_entry: (Config::gem_entry) -> String
68
+ end
69
+
70
+ # signatures that are bundled in rbs gem under the stdlib/ directory
71
+ class Stdlib
72
+ type source_entry = {
73
+ 'type' => 'stdlib',
74
+ }
75
+
76
+ # polyfill of singleton module
77
+ def self.instance: () -> instance
78
+
79
+ def has?: (Config::gem_entry) -> bool
80
+
81
+ def versions: (Config::gem_entry) -> Array[String]
82
+
83
+ def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
84
+
85
+ def to_lockfile: () -> source_entry
86
+
87
+ private
88
+
89
+ def gem_dir: (Config::gem_entry) -> Pathname
90
+ end
91
+
92
+ # sig/ directory
93
+ class Rubygems
94
+ type source_entry = {
95
+ 'type' => 'rubygems',
96
+ }
97
+
98
+ # polyfill of singleton module
99
+ def self.instance: () -> instance
100
+
101
+ def has?: (Config::gem_entry) -> boolish
102
+ def versions: (Config::gem_entry) -> Array[String]
103
+ def install: (dest: Pathname, config_entry: Config::gem_entry, stdout: CLI::_IO) -> void
104
+ def to_lockfile: () -> source_entry
105
+
106
+ private
107
+
108
+ def gem_sig_path: (Config::gem_entry) -> [Gem::Specification, Pathname]?
109
+ end
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,69 @@
1
+ module RBS
2
+ module Collection
3
+ # This class represent the configration file.
4
+ class Config
5
+ class LockfileGenerator
6
+ attr_reader config: Config
7
+ attr_reader lock: Config?
8
+ attr_reader lock_path: Pathname
9
+ attr_reader gemfile_lock: Bundler::LockfileParser
10
+
11
+ def self.generate: (config_path: Pathname, gemfile_lock_path: Pathname, ?with_lockfile: boolish) -> Config
12
+
13
+ def initialize: (config_path: Pathname, gemfile_lock_path: Pathname, with_lockfile: boolish) -> void
14
+
15
+ def generate: () -> Config
16
+
17
+ private
18
+
19
+ def assign_gem: (gem_name: String, version: String?) -> void
20
+
21
+ def upsert_gem: (gem_entry? old, gem_entry new) -> void
22
+
23
+ def gemfile_lock_gems: () { (untyped) -> void } -> void
24
+
25
+ def remove_ignored_gems!: () -> void
26
+
27
+ def find_source: (gem_name: String) -> untyped
28
+
29
+ def find_best_version: (version: String?, versions: Array[String]) -> Gem::Version
30
+ end
31
+
32
+ PATH: Pathname
33
+
34
+ type gem_entry = {
35
+ 'name' => String,
36
+ 'version' => String?,
37
+ 'ignore' => boolish,
38
+ 'source' => Sources::source_entry?
39
+ }
40
+
41
+ @config_path: Pathname
42
+
43
+ def self.generate_lockfile: (config_path: Pathname, gemfile_lock_path: Pathname, ?with_lockfile: boolish) -> Config
44
+
45
+ def self.from_path: (Pathname path) -> Config
46
+
47
+ def self.lockfile_of: (Pathname config_path) -> Config?
48
+
49
+ def self.to_lockfile_path: (Pathname config_path) -> Pathname
50
+
51
+ # config_path is necessary to resolve relative repo_path
52
+ def initialize: (untyped data, config_path: Pathname) -> void
53
+
54
+ def add_gem: (untyped gem) -> untyped
55
+
56
+ def gem: (String gem_name) -> untyped
57
+
58
+ def repo_path: () -> Pathname
59
+
60
+ def sources: () -> Array[Sources::_Source]
61
+
62
+ def dump_to: (Pathname) -> void
63
+
64
+ def gems: () -> Array[untyped]
65
+
66
+ def check_rbs_availability!: () -> void
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,15 @@
1
+ module RBS
2
+ module Collection
3
+ class Installer
4
+ attr_reader lockfile: Config
5
+ attr_reader stdout: CLI::_IO
6
+
7
+ def initialize: (lockfile_path: Pathname, ?stdout: CLI::_IO) -> void
8
+ def install_from_lockfile: () -> void
9
+
10
+ private
11
+
12
+ def source_for: (Config::gem_entry) -> Sources::_Source
13
+ end
14
+ end
15
+ end