steep 0.7.1 → 0.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -0
- data/Gemfile +3 -0
- data/README.md +30 -1
- data/exe/steep +1 -1
- data/lib/steep/cli.rb +197 -61
- data/lib/steep/drivers/annotations.rb +2 -0
- data/lib/steep/drivers/check.rb +14 -3
- data/lib/steep/drivers/print_interface.rb +3 -0
- data/lib/steep/drivers/scaffold.rb +1 -0
- data/lib/steep/drivers/validate.rb +1 -1
- data/lib/steep/version.rb +1 -1
- data/smoke/regexp/a.rb +147 -0
- data/smoke/regexp/b.rb +105 -0
- data/stdlib/builtin.rbi +56 -1
- metadata +4 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d90e7067b0b17caaae304fa3de1e80e73a5a3cc8081270c338c291ec572a08d6
|
4
|
+
data.tar.gz: 15ab7f0d9168a6be10c0688fd8af60b4d85786a41f4648206287e04d737e690b
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5a0c188bee7427b97ef8a57b88dd0ab6f5b77cade4287951010bf0318e97b33bcb642530763faf2494666261fceac63f72113cad9a38b7ecaa2f8c3f984e8a72
|
7
|
+
data.tar.gz: aae9a7653b739e11a9ebec676698b0a1dc4af22ab67a9701e6c4615ffe0466da7907bd0a5980c6f4285c25d63aa12b0ff02185425a03087ecdb0f45e6da3bf64
|
data/CHANGELOG.md
CHANGED
@@ -2,6 +2,13 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
+
## 0.8.0 (2018-10-29)
|
6
|
+
|
7
|
+
* Load types from gems (#64, #66)
|
8
|
+
* Fix exit status (#65)
|
9
|
+
* Fix `--version` handling (#57 @ybiquitous, #58)
|
10
|
+
* Add `Regexp` and `MatchData` (#58 @ybiquitous)
|
11
|
+
|
5
12
|
## 0.7.1 (2018-10-22)
|
6
13
|
|
7
14
|
* Rename *hash type* to *record type* (#60)
|
data/Gemfile
CHANGED
data/README.md
CHANGED
@@ -208,10 +208,39 @@ Use `--dump-all-types` for that.
|
|
208
208
|
|
209
209
|
$ steep check --dump-all-types test.rb
|
210
210
|
|
211
|
-
### Verbose
|
211
|
+
### Verbose Option
|
212
212
|
|
213
213
|
Try `-v` option to report more information about type checking.
|
214
214
|
|
215
|
+
### Loading Type definitions from Gems
|
216
|
+
|
217
|
+
You can pass `-G` option to specify name of gems to load type definitions.
|
218
|
+
|
219
|
+
```
|
220
|
+
$ steep check -G strong_json lib
|
221
|
+
```
|
222
|
+
|
223
|
+
When you are using bundler, Steep load type definitions from bundled gems automatically.
|
224
|
+
|
225
|
+
```
|
226
|
+
$ bundle exec steep check lib
|
227
|
+
```
|
228
|
+
|
229
|
+
To disable automatic gem detection from bundler, you can specify `--no-bundler` option.
|
230
|
+
|
231
|
+
```
|
232
|
+
$ bundle exec steep check --no-bundler -G strong_json lib
|
233
|
+
```
|
234
|
+
|
235
|
+
## Making a Gem with Type Definition
|
236
|
+
|
237
|
+
Put your type definition file in a directory, ship that in your gem, and let `metadata` of the gemspec to contain `"steep_types" => dir_name`.
|
238
|
+
|
239
|
+
```rb
|
240
|
+
spec.metadata = { "steep_types" => "sig" }
|
241
|
+
```
|
242
|
+
|
243
|
+
We recommend using `sig` as a name of the directory for type definitions, but you can use any directory.
|
215
244
|
|
216
245
|
## Examples
|
217
246
|
|
data/exe/steep
CHANGED
@@ -8,7 +8,7 @@ require 'steep'
|
|
8
8
|
require 'steep/cli'
|
9
9
|
|
10
10
|
begin
|
11
|
-
Steep::CLI.new(argv: ARGV.dup, stdout: STDOUT, stderr: STDERR, stdin: STDIN).run
|
11
|
+
exit Steep::CLI.new(argv: ARGV.dup, stdout: STDOUT, stderr: STDERR, stdin: STDIN).run
|
12
12
|
rescue => exn
|
13
13
|
STDERR.puts exn.inspect
|
14
14
|
exn.backtrace.each do |t|
|
data/lib/steep/cli.rb
CHANGED
@@ -2,6 +2,122 @@ require 'optparse'
|
|
2
2
|
|
3
3
|
module Steep
|
4
4
|
class CLI
|
5
|
+
BUILTIN_PATH = Pathname(__dir__).join("../../stdlib").realpath
|
6
|
+
|
7
|
+
class SignatureOptions
|
8
|
+
class MissingGemError < StandardError
|
9
|
+
attr_reader :name
|
10
|
+
attr_reader :version
|
11
|
+
|
12
|
+
def initialize(name:, version:)
|
13
|
+
@name = name
|
14
|
+
@version = version
|
15
|
+
super "Requested gem not found: name=#{name}, version=#{version}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
class NoTypeDefinitionFromGemError < StandardError
|
20
|
+
attr_reader :gemspec
|
21
|
+
|
22
|
+
def initialize(gemspec:)
|
23
|
+
@gemspec = gemspec
|
24
|
+
super "Gem does not provide Steep type: gem=#{gemspec.name}"
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
attr_reader :no_builtin
|
29
|
+
attr_reader :no_bundler
|
30
|
+
|
31
|
+
def initialize
|
32
|
+
@options = []
|
33
|
+
end
|
34
|
+
|
35
|
+
def no_builtin!
|
36
|
+
@no_builtin = true
|
37
|
+
end
|
38
|
+
|
39
|
+
def no_bundler!
|
40
|
+
@no_bundler = true
|
41
|
+
end
|
42
|
+
|
43
|
+
def <<(option)
|
44
|
+
@options << option
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_gem_dir(gem)
|
48
|
+
name, version = gem.split(/:/)
|
49
|
+
spec =
|
50
|
+
begin
|
51
|
+
Gem::Specification.find_by_name(name, version)
|
52
|
+
rescue Gem::MissingSpecError
|
53
|
+
raise MissingGemError.new(name: name, version: version)
|
54
|
+
end
|
55
|
+
|
56
|
+
dirs_from_spec(spec).tap do |dirs|
|
57
|
+
if dirs.empty?
|
58
|
+
raise NoTypeDefinitionFromGemError.new(gemspec: spec)
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
63
|
+
def dirs_from_spec(spec)
|
64
|
+
type_dirs = spec.metadata["steep_types"].yield_self do |types|
|
65
|
+
case types
|
66
|
+
when nil
|
67
|
+
[]
|
68
|
+
when String
|
69
|
+
types.split(/:/).map do |type|
|
70
|
+
Pathname(type)
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
base_dir = Pathname(spec.gem_dir)
|
76
|
+
type_dirs.map do |dir|
|
77
|
+
base_dir + dir
|
78
|
+
end.select(&:directory?)
|
79
|
+
end
|
80
|
+
|
81
|
+
def add_bundler_gems(options)
|
82
|
+
if defined?(Bundler)
|
83
|
+
Steep.logger.info "Bundler detected!"
|
84
|
+
Bundler.load.gems.each do |spec|
|
85
|
+
dirs = dirs_from_spec(spec)
|
86
|
+
options.unshift *dirs
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def paths
|
92
|
+
options = if @options.none? {|option| option.is_a?(Pathname) }
|
93
|
+
@options + [Pathname("sig")]
|
94
|
+
else
|
95
|
+
@options
|
96
|
+
end
|
97
|
+
|
98
|
+
unless no_bundler
|
99
|
+
add_bundler_gems(options)
|
100
|
+
end
|
101
|
+
|
102
|
+
paths = options.flat_map do |option|
|
103
|
+
case option
|
104
|
+
when Pathname
|
105
|
+
# Dir
|
106
|
+
[option]
|
107
|
+
when String
|
108
|
+
# gem name
|
109
|
+
find_gem_dir(option)
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
unless no_builtin
|
114
|
+
paths.unshift BUILTIN_PATH
|
115
|
+
end
|
116
|
+
|
117
|
+
paths
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
5
121
|
attr_reader :argv
|
6
122
|
attr_reader :stdout
|
7
123
|
attr_reader :stdin
|
@@ -16,10 +132,17 @@ module Steep
|
|
16
132
|
end
|
17
133
|
|
18
134
|
def self.available_commands
|
19
|
-
[:check, :validate, :annotations, :scaffold, :interface, :version]
|
135
|
+
[:check, :validate, :annotations, :scaffold, :interface, :version, :paths]
|
20
136
|
end
|
21
137
|
|
22
|
-
def
|
138
|
+
def process_global_options
|
139
|
+
OptionParser.new do |opts|
|
140
|
+
opts.on("--version") do
|
141
|
+
process_version
|
142
|
+
exit 0
|
143
|
+
end
|
144
|
+
end.order!
|
145
|
+
|
23
146
|
true
|
24
147
|
end
|
25
148
|
|
@@ -35,101 +158,114 @@ module Steep
|
|
35
158
|
end
|
36
159
|
|
37
160
|
def run
|
38
|
-
|
161
|
+
process_global_options or return 1
|
39
162
|
setup_command or return 1
|
40
163
|
|
41
164
|
__send__(:"process_#{command}")
|
42
165
|
end
|
43
166
|
|
167
|
+
def handle_dir_options(opts, options)
|
168
|
+
opts.on("-I [PATH]") {|path| options << Pathname(path) }
|
169
|
+
opts.on("-G [GEM]") {|gem| options << gem }
|
170
|
+
opts.on("--no-builtin") { options.no_builtin! }
|
171
|
+
opts.on("--no-bundler") { options.no_bundler! }
|
172
|
+
end
|
173
|
+
|
174
|
+
def with_signature_options
|
175
|
+
yield SignatureOptions.new
|
176
|
+
rescue SignatureOptions::MissingGemError => exn
|
177
|
+
stderr.puts Rainbow("Gem not found: name=#{exn.name}, version=#{exn.version}").red
|
178
|
+
1
|
179
|
+
rescue SignatureOptions::NoTypeDefinitionFromGemError => exn
|
180
|
+
stderr.puts Rainbow("Type definition directory not found: #{exn.gemspec.name} (#{exn.gemspec.version})").red
|
181
|
+
1
|
182
|
+
end
|
183
|
+
|
44
184
|
def process_check
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
strict = false
|
185
|
+
with_signature_options do |signature_options|
|
186
|
+
verbose = false
|
187
|
+
dump_all_types = false
|
188
|
+
fallback_any_is_error = false
|
189
|
+
strict = false
|
51
190
|
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
end.parse!(argv)
|
60
|
-
|
61
|
-
if signature_dirs.empty?
|
62
|
-
signature_dirs << Pathname("sig")
|
63
|
-
end
|
191
|
+
OptionParser.new do |opts|
|
192
|
+
handle_dir_options opts, signature_options
|
193
|
+
opts.on("--verbose") { verbose = true }
|
194
|
+
opts.on("--dump-all-types") { dump_all_types = true }
|
195
|
+
opts.on("--strict") { strict = true }
|
196
|
+
opts.on("--fallback-any-is-error") { fallback_any_is_error = true }
|
197
|
+
end.parse!(argv)
|
64
198
|
|
65
|
-
|
66
|
-
|
67
|
-
|
199
|
+
source_paths = argv.map {|path| Pathname(path) }
|
200
|
+
if source_paths.empty?
|
201
|
+
source_paths << Pathname(".")
|
202
|
+
end
|
68
203
|
|
69
|
-
|
70
|
-
|
71
|
-
|
204
|
+
Drivers::Check.new(source_paths: source_paths, signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).tap do |check|
|
205
|
+
check.verbose = verbose
|
206
|
+
check.dump_all_types = dump_all_types
|
207
|
+
check.fallback_any_is_error = fallback_any_is_error || strict
|
208
|
+
check.allow_missing_definitions = false if strict
|
209
|
+
end.run
|
72
210
|
end
|
73
|
-
|
74
|
-
Drivers::Check.new(source_paths: source_paths, signature_dirs: signature_dirs, stdout: stdout, stderr: stderr).tap do |check|
|
75
|
-
check.verbose = verbose
|
76
|
-
check.dump_all_types = dump_all_types
|
77
|
-
check.fallback_any_is_error = fallback_any_is_error || strict
|
78
|
-
check.allow_missing_definitions = false if strict
|
79
|
-
end.run
|
80
211
|
end
|
81
212
|
|
82
213
|
def process_validate
|
83
|
-
|
84
|
-
|
214
|
+
with_signature_options do |signature_options|
|
215
|
+
verbose = false
|
85
216
|
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
217
|
+
OptionParser.new do |opts|
|
218
|
+
handle_dir_options opts, signature_options
|
219
|
+
opts.on("--verbose") { verbose = true }
|
220
|
+
end.parse!(argv)
|
90
221
|
|
91
|
-
|
92
|
-
|
93
|
-
|
222
|
+
Drivers::Validate.new(signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).tap do |validate|
|
223
|
+
validate.verbose = verbose
|
224
|
+
end.run
|
94
225
|
end
|
95
|
-
|
96
|
-
unless no_builtin
|
97
|
-
signature_dirs.unshift Pathname(__dir__).join("../../stdlib").realpath
|
98
|
-
end
|
99
|
-
|
100
|
-
Drivers::Validate.new(signature_dirs: signature_dirs, stdout: stdout, stderr: stderr).tap do |validate|
|
101
|
-
validate.verbose = verbose
|
102
|
-
end.run
|
103
226
|
end
|
104
227
|
|
105
228
|
def process_annotations
|
106
229
|
source_paths = argv.map {|file| Pathname(file) }
|
107
230
|
Drivers::Annotations.new(source_paths: source_paths, stdout: stdout, stderr: stderr).run
|
231
|
+
0
|
108
232
|
end
|
109
233
|
|
110
234
|
def process_scaffold
|
111
235
|
source_paths = argv.map {|file| Pathname(file) }
|
112
236
|
Drivers::Scaffold.new(source_paths: source_paths, stdout: stdout, stderr: stderr).run
|
237
|
+
0
|
113
238
|
end
|
114
239
|
|
115
240
|
def process_interface
|
116
|
-
|
117
|
-
|
241
|
+
with_signature_options do |signature_options|
|
242
|
+
OptionParser.new do |opts|
|
243
|
+
handle_dir_options opts, signature_options
|
244
|
+
end.parse!(argv)
|
118
245
|
|
119
|
-
|
120
|
-
opts.on("-I [PATH]") {|path| signature_dirs << Pathname(path) }
|
121
|
-
opts.on("--no-builtin") { no_builtin = true }
|
122
|
-
end.parse!(argv)
|
246
|
+
Drivers::PrintInterface.new(type_name: argv.first, signature_dirs: signature_options.paths, stdout: stdout, stderr: stderr).run
|
123
247
|
|
124
|
-
|
125
|
-
signature_dirs.unshift Pathname(__dir__).join("../../stdlib").realpath
|
248
|
+
0
|
126
249
|
end
|
127
|
-
|
128
|
-
Drivers::PrintInterface.new(type_name: argv.first, signature_dirs: signature_dirs, stdout: stdout, stderr: stderr).run
|
129
250
|
end
|
130
251
|
|
131
252
|
def process_version
|
132
253
|
stdout.puts Steep::VERSION
|
254
|
+
0
|
255
|
+
end
|
256
|
+
|
257
|
+
def process_paths
|
258
|
+
with_signature_options do |signature_options|
|
259
|
+
OptionParser.new do |opts|
|
260
|
+
handle_dir_options opts, signature_options
|
261
|
+
end.parse!(argv)
|
262
|
+
|
263
|
+
signature_options.paths.each do |path|
|
264
|
+
stdout.puts path
|
265
|
+
end
|
266
|
+
|
267
|
+
0
|
268
|
+
end
|
133
269
|
end
|
134
270
|
end
|
135
271
|
end
|
data/lib/steep/drivers/check.rb
CHANGED
@@ -111,11 +111,22 @@ module Steep
|
|
111
111
|
end
|
112
112
|
end
|
113
113
|
|
114
|
-
typing.errors.
|
115
|
-
|
116
|
-
|
114
|
+
errors = typing.errors.select do |error|
|
115
|
+
case
|
116
|
+
when error.is_a?(Errors::FallbackAny) && !fallback_any_is_error
|
117
|
+
false
|
118
|
+
when error.is_a?(Errors::MethodDefinitionMissing) && allow_missing_definitions
|
119
|
+
false
|
120
|
+
else
|
121
|
+
true
|
122
|
+
end
|
123
|
+
end
|
124
|
+
|
125
|
+
errors.each do |error|
|
117
126
|
error.print_to stdout
|
118
127
|
end
|
128
|
+
|
129
|
+
errors.empty? ? 0 : 1
|
119
130
|
end
|
120
131
|
end
|
121
132
|
end
|
@@ -48,11 +48,14 @@ module Steep
|
|
48
48
|
puts " - #{Rainbow(method_type.to_s).red} (#{loc})"
|
49
49
|
end
|
50
50
|
end
|
51
|
+
0
|
51
52
|
rescue Steep::Subtyping::Check::CannotResolveError
|
52
53
|
stderr.puts "🤔 #{Rainbow(type.to_s).red} cannot be resolved to interface"
|
54
|
+
1
|
53
55
|
end
|
54
56
|
else
|
55
57
|
stderr.puts "Pass a type name to command line"
|
58
|
+
1
|
56
59
|
end
|
57
60
|
end
|
58
61
|
end
|
data/lib/steep/version.rb
CHANGED
data/smoke/regexp/a.rb
ADDED
@@ -0,0 +1,147 @@
|
|
1
|
+
# ALLOW FAILURE
|
2
|
+
|
3
|
+
new_1 = Regexp.new("a")
|
4
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
5
|
+
new_1.foo
|
6
|
+
|
7
|
+
new_2 = Regexp.new("a", true)
|
8
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
9
|
+
new_2.foo
|
10
|
+
|
11
|
+
new_3 = Regexp.new("a", Regexp::EXTENDED | Regexp::IGNORECASE)
|
12
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
13
|
+
new_3.foo
|
14
|
+
|
15
|
+
new_4 = Regexp.new(/a/)
|
16
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
17
|
+
new_4.foo
|
18
|
+
|
19
|
+
compile_1 = Regexp.compile("a")
|
20
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
21
|
+
compile_1.foo
|
22
|
+
|
23
|
+
compile_2 = Regexp.compile("a", true)
|
24
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
25
|
+
compile_2.foo
|
26
|
+
|
27
|
+
compile_3 = Regexp.compile("a", Regexp::EXTENDED | Regexp::IGNORECASE)
|
28
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
29
|
+
compile_3.foo
|
30
|
+
|
31
|
+
compile_4 = Regexp.compile(/a/)
|
32
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
33
|
+
compile_4.foo
|
34
|
+
|
35
|
+
escape_1 = Regexp.escape("a")
|
36
|
+
# !expects NoMethodError: type=::String, method=foo
|
37
|
+
escape_1.foo
|
38
|
+
|
39
|
+
last_match_1 = Regexp.last_match
|
40
|
+
# !expects NoMethodError: type=(::MatchData | nil), method=foo
|
41
|
+
last_match_1.foo
|
42
|
+
|
43
|
+
last_match_2 = Regexp.last_match(1)
|
44
|
+
# !expects NoMethodError: type=(::String | nil), method=foo
|
45
|
+
last_match_2.foo
|
46
|
+
|
47
|
+
quote_1 = Regexp.quote("a")
|
48
|
+
# !expects NoMethodError: type=::String, method=foo
|
49
|
+
quote_1.foo
|
50
|
+
|
51
|
+
try_convert_1 = Regexp.try_convert(Object.new)
|
52
|
+
# !expects NoMethodError: type=(::Regexp | nil), method=foo
|
53
|
+
try_convert_1.foo
|
54
|
+
|
55
|
+
union_1 = Regexp.union
|
56
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
57
|
+
union_1.foo
|
58
|
+
|
59
|
+
union_2 = Regexp.union("a")
|
60
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
61
|
+
union_2.foo
|
62
|
+
|
63
|
+
union_3 = Regexp.union("a", "b")
|
64
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
65
|
+
union_3.foo
|
66
|
+
|
67
|
+
union_4 = Regexp.union(["a", "b"])
|
68
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
69
|
+
union_4.foo
|
70
|
+
|
71
|
+
union_5 = Regexp.union(/a/)
|
72
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
73
|
+
union_5.foo
|
74
|
+
|
75
|
+
union_6 = Regexp.union(/a/, /b/)
|
76
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
77
|
+
union_6.foo
|
78
|
+
|
79
|
+
union_7 = Regexp.union([/a/, /b/])
|
80
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
81
|
+
union_7.foo
|
82
|
+
|
83
|
+
op_eqeqeq_1 = /a/ === "a"
|
84
|
+
# !expects NoMethodError: type=bool, method=foo
|
85
|
+
op_eqeqeq_1.foo
|
86
|
+
|
87
|
+
op_match_1 = /a/ =~ "a"
|
88
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
89
|
+
op_match_1.foo
|
90
|
+
|
91
|
+
casefold_1 = /a/.casefold?
|
92
|
+
# !expects NoMethodError: type=bool, method=foo
|
93
|
+
casefold_1.foo
|
94
|
+
|
95
|
+
encoding_1 = /a/.encoding
|
96
|
+
# !expects NoMethodError: type=::Encoding, method=foo
|
97
|
+
encoding_1.foo
|
98
|
+
|
99
|
+
fixed_encoding_1 = /a/.fixed_encoding?
|
100
|
+
# !expects NoMethodError: type=bool, method=foo
|
101
|
+
fixed_encoding_1.foo
|
102
|
+
|
103
|
+
match_1 = /a/.match("a")
|
104
|
+
# !expects NoMethodError: type=(::MatchData | nil), method=foo
|
105
|
+
match_1.foo
|
106
|
+
|
107
|
+
match_2 = /a/.match("a", 0)
|
108
|
+
# !expects NoMethodError: type=(::MatchData | nil), method=foo
|
109
|
+
match_2.foo
|
110
|
+
|
111
|
+
/a/.match("a") do |m|
|
112
|
+
# !expects NoMethodError: type=::MatchData, method=foo
|
113
|
+
m.foo
|
114
|
+
end
|
115
|
+
|
116
|
+
/a/.match("a", 0) do |m|
|
117
|
+
# !expects NoMethodError: type=::MatchData, method=foo
|
118
|
+
m.foo
|
119
|
+
end
|
120
|
+
|
121
|
+
match_q_1 = /a/.match?("a")
|
122
|
+
# !expects NoMethodError: type=bool, method=foo
|
123
|
+
match_q_1.foo
|
124
|
+
|
125
|
+
match_q_2 = /a/.match?("a", 0)
|
126
|
+
# !expects NoMethodError: type=bool, method=foo
|
127
|
+
match_q_2.foo
|
128
|
+
|
129
|
+
named_captures_1 = /(?<foo>.)/.named_captures
|
130
|
+
# !expects NoMethodError: type=::Hash<::String, ::Array<::Integer>>, method=foo
|
131
|
+
named_captures_1.foo
|
132
|
+
|
133
|
+
names_1 = /(?<foo>.)/.names
|
134
|
+
# !expects NoMethodError: type=::Array<::String>, method=foo
|
135
|
+
names_1.foo
|
136
|
+
|
137
|
+
options_1 = /a/ix.options
|
138
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
139
|
+
options_1.foo
|
140
|
+
|
141
|
+
source_1 = /a/ix.source
|
142
|
+
# !expects NoMethodError: type=::String, method=foo
|
143
|
+
source_1.foo
|
144
|
+
|
145
|
+
op_unary_match_1 = ~ /a/
|
146
|
+
# !expects NoMethodError: type=(::Integer | nil), method=foo
|
147
|
+
op_unary_match_1.foo
|
data/smoke/regexp/b.rb
ADDED
@@ -0,0 +1,105 @@
|
|
1
|
+
/(?<foo>a)/.match("a") do |match|
|
2
|
+
match_ref_1 = match[0]
|
3
|
+
# !expects NoMethodError: type=(::String | nil), method=foo
|
4
|
+
match_ref_1.foo
|
5
|
+
|
6
|
+
match_ref_2 = match["foo"]
|
7
|
+
# !expects NoMethodError: type=(::String | nil), method=foo
|
8
|
+
match_ref_2.foo
|
9
|
+
|
10
|
+
match_ref_3 = match[:foo]
|
11
|
+
# !expects NoMethodError: type=(::String | nil), method=foo
|
12
|
+
match_ref_3.foo
|
13
|
+
|
14
|
+
match_ref_4 = match[0, 1]
|
15
|
+
# !expects NoMethodError: type=::Array<::String>, method=foo
|
16
|
+
match_ref_4.foo
|
17
|
+
|
18
|
+
match_ref_5 = match[0..1]
|
19
|
+
# !expects NoMethodError: type=::Array<::String>, method=foo
|
20
|
+
match_ref_5.foo
|
21
|
+
|
22
|
+
begin_1 = match.begin(0)
|
23
|
+
# !expects NoMethodError: type=(::Integer | nil), method=foo
|
24
|
+
begin_1.foo
|
25
|
+
|
26
|
+
begin_2 = match.begin("foo")
|
27
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
28
|
+
begin_2.foo
|
29
|
+
|
30
|
+
begin_3 = match.begin(:foo)
|
31
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
32
|
+
begin_3.foo
|
33
|
+
|
34
|
+
captures_1 = match.captures
|
35
|
+
# !expects NoMethodError: type=::Array<::String>, method=foo
|
36
|
+
captures_1.foo
|
37
|
+
|
38
|
+
end_1 = match.end(0)
|
39
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
40
|
+
end_1.foo
|
41
|
+
|
42
|
+
end_2 = match.end("foo")
|
43
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
44
|
+
end_2.foo
|
45
|
+
|
46
|
+
end_3 = match.end(:foo)
|
47
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
48
|
+
end_3.foo
|
49
|
+
|
50
|
+
length_1 = match.length
|
51
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
52
|
+
length_1.foo
|
53
|
+
|
54
|
+
named_captures_1 = match.named_captures
|
55
|
+
# !expects NoMethodError: type=::Hash<::String, (::String | nil)>, method=foo
|
56
|
+
named_captures_1.foo
|
57
|
+
|
58
|
+
names_1 = match.names
|
59
|
+
# !expects NoMethodError: type=::Array<::String>, method=foo
|
60
|
+
names_1.foo
|
61
|
+
|
62
|
+
offset_1 = match.offset(0)
|
63
|
+
# !expects NoMethodError: type=[::Integer, ::Integer], method=foo
|
64
|
+
offset_1.foo
|
65
|
+
|
66
|
+
offset_2 = match.offset("foo")
|
67
|
+
# !expects NoMethodError: type=[::Integer, ::Integer], method=foo
|
68
|
+
offset_2.foo
|
69
|
+
|
70
|
+
offset_3 = match.offset(:foo)
|
71
|
+
# !expects NoMethodError: type=[::Integer, ::Integer], method=foo
|
72
|
+
offset_3.foo
|
73
|
+
|
74
|
+
post_match_1 = match.post_match
|
75
|
+
# !expects NoMethodError: type=::String, method=foo
|
76
|
+
post_match_1.foo
|
77
|
+
|
78
|
+
pre_match_1 = match.pre_match
|
79
|
+
# !expects NoMethodError: type=::String, method=foo
|
80
|
+
pre_match_1.foo
|
81
|
+
|
82
|
+
regexp_1 = match.regexp
|
83
|
+
# !expects NoMethodError: type=::Regexp, method=foo
|
84
|
+
regexp_1.foo
|
85
|
+
|
86
|
+
size_1 = match.size
|
87
|
+
# !expects NoMethodError: type=::Integer, method=foo
|
88
|
+
size_1.foo
|
89
|
+
|
90
|
+
string_1 = match.string
|
91
|
+
# !expects NoMethodError: type=::String, method=foo
|
92
|
+
string_1.foo
|
93
|
+
|
94
|
+
to_a_1 = match.to_a
|
95
|
+
# !expects NoMethodError: type=::Array<::String>, method=foo
|
96
|
+
to_a_1.foo
|
97
|
+
|
98
|
+
values_at_1 = match.values_at
|
99
|
+
# !expects NoMethodError: type=::Array<(::String | nil)>, method=foo
|
100
|
+
values_at_1.foo
|
101
|
+
|
102
|
+
values_at_2 = match.values_at(0, "foo", :foo)
|
103
|
+
# !expects NoMethodError: type=::Array<(::String | nil)>, method=foo
|
104
|
+
values_at_2.foo
|
105
|
+
end
|
data/stdlib/builtin.rbi
CHANGED
@@ -560,10 +560,65 @@ class Enumerator<'a, 'b>
|
|
560
560
|
| -> Enumerator<['a, Integer], 'b>
|
561
561
|
end
|
562
562
|
|
563
|
+
class Encoding
|
564
|
+
end
|
565
|
+
|
563
566
|
class Regexp
|
564
|
-
def self.compile: (String
|
567
|
+
def self.compile: (String) -> Regexp
|
568
|
+
| (String, Integer) -> Regexp
|
569
|
+
| (String, bool) -> Regexp
|
570
|
+
| (Regexp) -> Regexp
|
565
571
|
def self.escape: (String) -> String
|
572
|
+
def self.last_match: -> MatchData?
|
573
|
+
| (Integer) -> String?
|
574
|
+
def self.quote: (String) -> String
|
575
|
+
def self.try_convert: (any) -> Regexp?
|
576
|
+
def self.union: (*String) -> Regexp
|
577
|
+
| (Array<String>) -> Regexp
|
578
|
+
| (*Regexp) -> Regexp
|
579
|
+
| (Array<Regexp>) -> Regexp
|
580
|
+
|
581
|
+
def initialize: (String) -> any
|
582
|
+
| (String, Integer) -> any
|
583
|
+
| (String, bool) -> any
|
584
|
+
| (Regexp) -> any
|
585
|
+
def ===: (String) -> bool
|
586
|
+
def =~: (String) -> Integer?
|
587
|
+
def casefold?: -> bool
|
588
|
+
def encoding: -> Encoding
|
589
|
+
def fixed_encoding?: -> bool
|
590
|
+
def match: (String) -> MatchData?
|
591
|
+
| (String, Integer) -> MatchData?
|
592
|
+
| <'a> (String) { (MatchData) -> 'a } -> ('a | nil)
|
593
|
+
| <'a> (String, Integer) { (MatchData) -> 'a } -> ('a | nil)
|
594
|
+
def match?: (String) -> bool
|
595
|
+
| (String, Integer) -> bool
|
596
|
+
def named_captures: -> Hash<String, Array<Integer>>
|
597
|
+
def names: -> Array<String>
|
598
|
+
def options: -> Integer
|
566
599
|
def source: -> String
|
600
|
+
def ~: -> Integer?
|
601
|
+
end
|
602
|
+
|
603
|
+
class MatchData
|
604
|
+
def []: (Integer | String | Symbol) -> String?
|
605
|
+
| (Integer, Integer) -> Array<String>
|
606
|
+
| (Range<Integer>) -> Array<String>
|
607
|
+
def begin: (Integer) -> Integer?
|
608
|
+
| (String | Symbol) -> Integer
|
609
|
+
def captures: -> Array<String>
|
610
|
+
def end: (Integer | String | Symbol) -> Integer
|
611
|
+
def length: -> Integer
|
612
|
+
def named_captures: -> Hash<String, String?>
|
613
|
+
def names: -> Array<String>
|
614
|
+
def offset: (Integer | String | Symbol) -> [Integer, Integer]
|
615
|
+
def post_match: -> String
|
616
|
+
def pre_match: -> String
|
617
|
+
def regexp: -> Regexp
|
618
|
+
def size: -> Integer
|
619
|
+
def string: -> String
|
620
|
+
def to_a: -> Array<String>
|
621
|
+
def values_at: (*(Integer | String | Symbol)) -> Array<String?>
|
567
622
|
end
|
568
623
|
|
569
624
|
class IO
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: steep
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Soutaro Matsumoto
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-10-
|
11
|
+
date: 2018-10-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -292,6 +292,8 @@ files:
|
|
292
292
|
- smoke/module/d.rb
|
293
293
|
- smoke/module/e.rb
|
294
294
|
- smoke/module/f.rb
|
295
|
+
- smoke/regexp/a.rb
|
296
|
+
- smoke/regexp/b.rb
|
295
297
|
- smoke/regression/array.rb
|
296
298
|
- smoke/regression/hash.rb
|
297
299
|
- smoke/regression/set_divide.rb
|