rbs 3.0.0.dev.2 → 3.0.0.dev.3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/comments.yml +2 -1
- data/.github/workflows/ruby.yml +4 -0
- data/Gemfile.lock +11 -11
- data/Rakefile +2 -2
- data/Steepfile +1 -1
- data/core/array.rbs +573 -423
- data/core/basic_object.rbs +11 -39
- data/core/binding.rbs +1 -1
- data/core/builtin.rbs +8 -0
- data/core/class.rbs +37 -0
- data/core/comparable.rbs +7 -18
- data/core/complex.rbs +2 -2
- data/core/data.rbs +419 -0
- data/core/dir.rbs +52 -104
- data/core/encoding.rbs +22 -181
- data/core/enumerable.rbs +212 -175
- data/core/enumerator/product.rbs +96 -0
- data/core/enumerator.rbs +57 -8
- data/core/errors.rbs +8 -2
- data/core/exception.rbs +41 -0
- data/core/fiber.rbs +95 -12
- data/core/file.rbs +840 -275
- data/core/file_test.rbs +34 -19
- data/core/float.rbs +40 -96
- data/core/gc.rbs +15 -3
- data/core/hash.rbs +113 -175
- data/core/integer.rbs +85 -145
- data/core/io/buffer.rbs +187 -60
- data/core/io/wait.rbs +28 -16
- data/core/io.rbs +1859 -1389
- data/core/kernel.rbs +525 -961
- data/core/match_data.rbs +306 -142
- data/core/math.rbs +506 -234
- data/core/method.rbs +0 -24
- data/core/module.rbs +110 -17
- data/core/nil_class.rbs +2 -0
- data/core/numeric.rbs +76 -144
- data/core/object.rbs +88 -212
- data/core/proc.rbs +17 -5
- data/core/process.rbs +22 -5
- data/core/ractor.rbs +1 -1
- data/core/random.rbs +20 -3
- data/core/range.rbs +91 -89
- data/core/rational.rbs +2 -3
- data/core/rbs/unnamed/argf.rbs +177 -120
- data/core/rbs/unnamed/env_class.rbs +89 -163
- data/core/rbs/unnamed/random.rbs +36 -12
- data/core/refinement.rbs +8 -0
- data/core/regexp.rbs +462 -272
- data/core/ruby_vm.rbs +210 -0
- data/{stdlib/set/0 → core}/set.rbs +43 -47
- data/core/string.rbs +1403 -1332
- data/core/string_io.rbs +191 -107
- data/core/struct.rbs +67 -63
- data/core/symbol.rbs +187 -201
- data/core/thread.rbs +40 -35
- data/core/time.rbs +902 -826
- data/core/trace_point.rbs +55 -6
- data/core/unbound_method.rbs +48 -24
- data/docs/collection.md +4 -0
- data/docs/syntax.md +55 -0
- data/ext/rbs_extension/parser.c +5 -6
- data/lib/rbs/cli.rb +6 -1
- data/lib/rbs/collection/cleaner.rb +8 -1
- data/lib/rbs/collection/config/lockfile.rb +3 -1
- data/lib/rbs/collection/config/lockfile_generator.rb +16 -14
- data/lib/rbs/collection/config.rb +1 -1
- data/lib/rbs/collection/sources/git.rb +9 -2
- data/lib/rbs/collection/sources/local.rb +79 -0
- data/lib/rbs/collection/sources.rb +8 -1
- data/lib/rbs/environment.rb +6 -5
- data/lib/rbs/environment_loader.rb +3 -2
- data/lib/rbs/errors.rb +18 -0
- data/lib/rbs/locator.rb +26 -7
- data/lib/rbs/sorter.rb +2 -2
- data/lib/rbs/version.rb +1 -1
- data/sig/collection/sources.rbs +32 -3
- data/sig/environment.rbs +2 -3
- data/sig/locator.rbs +14 -2
- data/sig/shims/{abstract_syntax_tree.rbs → _abstract_syntax_tree.rbs} +0 -0
- data/stdlib/bigdecimal/0/big_decimal.rbs +16 -13
- data/stdlib/cgi/0/core.rbs +16 -0
- data/stdlib/coverage/0/coverage.rbs +50 -8
- data/stdlib/csv/0/csv.rbs +1 -1
- data/stdlib/date/0/date.rbs +856 -726
- data/stdlib/date/0/date_time.rbs +83 -210
- data/stdlib/erb/0/erb.rbs +13 -36
- data/stdlib/etc/0/etc.rbs +127 -20
- data/stdlib/fileutils/0/fileutils.rbs +1290 -381
- data/stdlib/logger/0/logger.rbs +466 -316
- data/stdlib/net-http/0/net-http.rbs +2211 -534
- data/stdlib/nkf/0/nkf.rbs +5 -5
- data/stdlib/objspace/0/objspace.rbs +31 -14
- data/stdlib/openssl/0/openssl.rbs +11 -7
- data/stdlib/optparse/0/optparse.rbs +20 -17
- data/stdlib/pathname/0/pathname.rbs +21 -4
- data/stdlib/pstore/0/pstore.rbs +378 -154
- data/stdlib/pty/0/pty.rbs +24 -8
- data/stdlib/ripper/0/ripper.rbs +1650 -0
- data/stdlib/socket/0/addrinfo.rbs +9 -15
- data/stdlib/socket/0/socket.rbs +36 -3
- data/stdlib/strscan/0/string_scanner.rbs +7 -5
- data/stdlib/tempfile/0/tempfile.rbs +104 -44
- data/stdlib/time/0/time.rbs +2 -2
- data/stdlib/uri/0/file.rbs +5 -0
- data/stdlib/uri/0/generic.rbs +2 -2
- data/stdlib/yaml/0/yaml.rbs +2 -2
- data/stdlib/zlib/0/zlib.rbs +1 -1
- metadata +8 -6
- data/core/deprecated.rbs +0 -9
- data/sig/shims/ripper.rbs +0 -8
data/core/trace_point.rbs
CHANGED
@@ -114,7 +114,7 @@ class TracePoint < Object
|
|
114
114
|
|
115
115
|
# <!--
|
116
116
|
# rdoc-file=trace_point.rb
|
117
|
-
# - TracePoint.allow_reentry
|
117
|
+
# - TracePoint.allow_reentry { block }
|
118
118
|
# -->
|
119
119
|
# In general, while a TracePoint callback is running, other registered callbacks
|
120
120
|
# are not called to avoid confusion by reentrance. This method allows the
|
@@ -124,6 +124,54 @@ class TracePoint < Object
|
|
124
124
|
# If this method is called when the reentrance is already allowed, it raises a
|
125
125
|
# RuntimeError.
|
126
126
|
#
|
127
|
+
# **Example:**
|
128
|
+
#
|
129
|
+
# # Without reentry
|
130
|
+
# # ---------------
|
131
|
+
#
|
132
|
+
# line_handler = TracePoint.new(:line) do |tp|
|
133
|
+
# next if tp.path != __FILE__ # only work in this file
|
134
|
+
# puts "Line handler"
|
135
|
+
# binding.eval("class C; end")
|
136
|
+
# end.enable
|
137
|
+
#
|
138
|
+
# class_handler = TracePoint.new(:class) do |tp|
|
139
|
+
# puts "Class handler"
|
140
|
+
# end.enable
|
141
|
+
#
|
142
|
+
# class B
|
143
|
+
# end
|
144
|
+
#
|
145
|
+
# # This script will print "Class handler" only once: when inside :line
|
146
|
+
# # handler, all other handlers are ignored
|
147
|
+
#
|
148
|
+
# # With reentry
|
149
|
+
# # ------------
|
150
|
+
#
|
151
|
+
# line_handler = TracePoint.new(:line) do |tp|
|
152
|
+
# next if tp.path != __FILE__ # only work in this file
|
153
|
+
# next if (__LINE__..__LINE__+3).cover?(tp.lineno) # don't be invoked from itself
|
154
|
+
# puts "Line handler"
|
155
|
+
# TracePoint.allow_reentry { binding.eval("class C; end") }
|
156
|
+
# end.enable
|
157
|
+
#
|
158
|
+
# class_handler = TracePoint.new(:class) do |tp|
|
159
|
+
# puts "Class handler"
|
160
|
+
# end.enable
|
161
|
+
#
|
162
|
+
# class B
|
163
|
+
# end
|
164
|
+
#
|
165
|
+
# # This wil print "Class handler" twice: inside allow_reentry block in :line
|
166
|
+
# # handler, other handlers are enabled.
|
167
|
+
#
|
168
|
+
# Note that the example shows the principal effect of the method, but its
|
169
|
+
# practical usage is for debugging libraries that sometimes require other
|
170
|
+
# libraries hooks to not be affected by debugger being inside trace point
|
171
|
+
# handling. Precautions should be taken against infinite recursion in this case
|
172
|
+
# (note that we needed to filter out calls by itself from :line handler,
|
173
|
+
# otherwise it will call itself infinitely).
|
174
|
+
#
|
127
175
|
def self.allow_reentry: () { () -> void } -> void
|
128
176
|
|
129
177
|
# <!--
|
@@ -163,7 +211,7 @@ class TracePoint < Object
|
|
163
211
|
# binding of the nearest Ruby method calling the C method, since C methods
|
164
212
|
# themselves do not have bindings.
|
165
213
|
#
|
166
|
-
def binding: () -> Binding
|
214
|
+
def binding: () -> Binding?
|
167
215
|
|
168
216
|
# <!--
|
169
217
|
# rdoc-file=trace_point.rb
|
@@ -251,7 +299,7 @@ class TracePoint < Object
|
|
251
299
|
# <!--
|
252
300
|
# rdoc-file=trace_point.rb
|
253
301
|
# - trace.enable(target: nil, target_line: nil, target_thread: nil) -> true or false
|
254
|
-
# - trace.enable(target: nil, target_line: nil, target_thread:
|
302
|
+
# - trace.enable(target: nil, target_line: nil, target_thread: :default) { block } -> obj
|
255
303
|
# -->
|
256
304
|
# Activates the trace.
|
257
305
|
#
|
@@ -264,15 +312,16 @@ class TracePoint < Object
|
|
264
312
|
# trace.enable #=> true (previous state)
|
265
313
|
# # trace is still enabled
|
266
314
|
#
|
267
|
-
# If a block is given, the trace will only be enabled
|
268
|
-
#
|
315
|
+
# If a block is given, the trace will only be enabled during the block call. If
|
316
|
+
# target and target_line are both nil, then target_thread will default to the
|
317
|
+
# current thread if a block is given.
|
269
318
|
#
|
270
319
|
# trace.enabled?
|
271
320
|
# #=> false
|
272
321
|
#
|
273
322
|
# trace.enable do
|
274
323
|
# trace.enabled?
|
275
|
-
# # only enabled for this block
|
324
|
+
# # only enabled for this block and thread
|
276
325
|
# end
|
277
326
|
#
|
278
327
|
# trace.enabled?
|
data/core/unbound_method.rbs
CHANGED
@@ -46,6 +46,22 @@
|
|
46
46
|
# um.bind(t).call #=> :original
|
47
47
|
#
|
48
48
|
class UnboundMethod
|
49
|
+
# <!--
|
50
|
+
# rdoc-file=proc.c
|
51
|
+
# - meth.eql?(other_meth) -> true or false
|
52
|
+
# - meth == other_meth -> true or false
|
53
|
+
# -->
|
54
|
+
# Two unbound method objects are equal if they refer to the same method
|
55
|
+
# definition.
|
56
|
+
#
|
57
|
+
# Array.instance_method(:each_slice) == Enumerable.instance_method(:each_slice)
|
58
|
+
# #=> true
|
59
|
+
#
|
60
|
+
# Array.instance_method(:sum) == Enumerable.instance_method(:sum)
|
61
|
+
# #=> false, Array redefines the method for efficiency
|
62
|
+
#
|
63
|
+
def ==: (untyped) -> bool
|
64
|
+
|
49
65
|
# <!--
|
50
66
|
# rdoc-file=proc.c
|
51
67
|
# - method.clone -> new_method
|
@@ -141,6 +157,38 @@ class UnboundMethod
|
|
141
157
|
#
|
142
158
|
def bind: (untyped obj) -> Method
|
143
159
|
|
160
|
+
# <!--
|
161
|
+
# rdoc-file=proc.c
|
162
|
+
# - meth.to_s -> string
|
163
|
+
# - meth.inspect -> string
|
164
|
+
# -->
|
165
|
+
# Returns a human-readable description of the underlying method.
|
166
|
+
#
|
167
|
+
# "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
|
168
|
+
# (1..3).method(:map).inspect #=> "#<Method: Range(Enumerable)#map()>"
|
169
|
+
#
|
170
|
+
# In the latter case, the method description includes the "owner" of the
|
171
|
+
# original method (`Enumerable` module, which is included into `Range`).
|
172
|
+
#
|
173
|
+
# `inspect` also provides, when possible, method argument names (call sequence)
|
174
|
+
# and source location.
|
175
|
+
#
|
176
|
+
# require 'net/http'
|
177
|
+
# Net::HTTP.method(:get).inspect
|
178
|
+
# #=> "#<Method: Net::HTTP.get(uri_or_host, path=..., port=...) <skip>/lib/ruby/2.7.0/net/http.rb:457>"
|
179
|
+
#
|
180
|
+
# `...` in argument definition means argument is optional (has some default
|
181
|
+
# value).
|
182
|
+
#
|
183
|
+
# For methods defined in C (language core and extensions), location and argument
|
184
|
+
# names can't be extracted, and only generic information is provided in form of
|
185
|
+
# `*` (any number of arguments) or `_` (some positional argument).
|
186
|
+
#
|
187
|
+
# "cat".method(:count).inspect #=> "#<Method: String#count(*)>"
|
188
|
+
# "cat".method(:+).inspect #=> "#<Method: String#+(_)>""
|
189
|
+
#
|
190
|
+
def inspect: () -> String
|
191
|
+
|
144
192
|
# <!--
|
145
193
|
# rdoc-file=proc.c
|
146
194
|
# - meth.name -> symbol
|
@@ -188,30 +236,6 @@ class UnboundMethod
|
|
188
236
|
def parameters: () -> ::Array[[ Symbol, Symbol ]]
|
189
237
|
| () -> ::Array[[ Symbol ]]
|
190
238
|
|
191
|
-
# <!--
|
192
|
-
# rdoc-file=proc.c
|
193
|
-
# - meth.private? -> true or false
|
194
|
-
# -->
|
195
|
-
# Returns whether the method is private.
|
196
|
-
#
|
197
|
-
def private?: () -> bool
|
198
|
-
|
199
|
-
# <!--
|
200
|
-
# rdoc-file=proc.c
|
201
|
-
# - meth.protected? -> true or false
|
202
|
-
# -->
|
203
|
-
# Returns whether the method is protected.
|
204
|
-
#
|
205
|
-
def protected?: () -> bool
|
206
|
-
|
207
|
-
# <!--
|
208
|
-
# rdoc-file=proc.c
|
209
|
-
# - meth.public? -> true or false
|
210
|
-
# -->
|
211
|
-
# Returns whether the method is public.
|
212
|
-
#
|
213
|
-
def public?: () -> bool
|
214
|
-
|
215
239
|
# <!--
|
216
240
|
# rdoc-file=proc.c
|
217
241
|
# - meth.source_location -> [String, Integer]
|
data/docs/collection.md
CHANGED
data/docs/syntax.md
CHANGED
@@ -501,6 +501,8 @@ private alias foo bar # Syntax error
|
|
501
501
|
```markdown
|
502
502
|
_decl_ ::= _class-decl_ # Class declaration
|
503
503
|
| _module-decl_ # Module declaration
|
504
|
+
| _class-alias-decl_ # Class alias declaration
|
505
|
+
| _module-alias-decl_ # Module alias declaration
|
504
506
|
| _interface-decl_ # Interface declaration
|
505
507
|
| _type-alias-decl_ # Type alias declaration
|
506
508
|
| _const-decl_ # Constant declaration
|
@@ -512,6 +514,10 @@ _class-decl_ ::= `class` _class-name_ _module-type-parameters_ _members_ `end`
|
|
512
514
|
_module-decl_ ::= `module` _module-name_ _module-type-parameters_ _members_ `end`
|
513
515
|
| `module` _module-name_ _module-type-parameters_ `:` _module-self-types_ _members_ `end`
|
514
516
|
|
517
|
+
_class-alias-decl_ ::= `class` _class-name_ `=` _class-name_
|
518
|
+
|
519
|
+
_module-alias-decl_ ::= `module` _module-name_ `=` _module-name_
|
520
|
+
|
515
521
|
_module-self-types_ ::= _class-name_ _type-arguments_ `,` _module-self-types_ (Class instance)
|
516
522
|
| _interface-name_ _type-arguments_ `,` _module-self-types_ (Interface)
|
517
523
|
|
@@ -554,6 +560,32 @@ end
|
|
554
560
|
|
555
561
|
The `Enumerable` module above requires `each` method for enumerating objects.
|
556
562
|
|
563
|
+
### Class/module alias declaration
|
564
|
+
|
565
|
+
An alias of a class or module can be defined in RBS.
|
566
|
+
|
567
|
+
```rbs
|
568
|
+
module Foo = Kernel
|
569
|
+
|
570
|
+
class Bar = Array
|
571
|
+
```
|
572
|
+
|
573
|
+
The syntax defines a class and the definition is equivalent to the right-hand-side.
|
574
|
+
|
575
|
+
```
|
576
|
+
class Baz < Bar[String] # Class alias can be inherited
|
577
|
+
include Foo # Module alias can be included
|
578
|
+
end
|
579
|
+
```
|
580
|
+
|
581
|
+
This is a definition corresponding to the following Ruby code.
|
582
|
+
|
583
|
+
```ruby
|
584
|
+
Foo = Kernel
|
585
|
+
|
586
|
+
Bar = Array
|
587
|
+
```
|
588
|
+
|
557
589
|
### Interface declaration
|
558
590
|
|
559
591
|
Interface declaration can have parameters but allows only a few of the members.
|
@@ -696,6 +728,29 @@ type int_printer = PrettyPrint[Integer] # Type error
|
|
696
728
|
|
697
729
|
The upper bound must be one of a class instance type, interface type, or class singleton type.
|
698
730
|
|
731
|
+
### Directives
|
732
|
+
|
733
|
+
Directives are placed at the top of a file and provides per-file-basis features.
|
734
|
+
|
735
|
+
```
|
736
|
+
_use-directive_ ::= `use` _use-clauses_
|
737
|
+
|
738
|
+
_use-clauses_ ::= _use-clause_ `,` ... `,` _use-clause_
|
739
|
+
|
740
|
+
_use-clause_ ::= _type-name_ # Single use clause
|
741
|
+
| _type-name_ `as` _simple-type-name_ # Single use clause with alias
|
742
|
+
| _namespace_ # Wildcard use clause
|
743
|
+
```
|
744
|
+
|
745
|
+
The *use directive* defines relative type names that is an alias of other type names.
|
746
|
+
We can use the simple type names if it is declared with *use*.
|
747
|
+
|
748
|
+
```
|
749
|
+
use RBS::Namespace # => Defines `Namespace`
|
750
|
+
use RBS::TypeName as TN # => Defines `TN`
|
751
|
+
use RBS::AST::* # => Defines modules under `::RBS::AST::` namespace
|
752
|
+
```
|
753
|
+
|
699
754
|
### Comments
|
700
755
|
|
701
756
|
You can write single line comments. Comments must be on their own line. Comments can lead with whitespace.
|
data/ext/rbs_extension/parser.c
CHANGED
@@ -2724,13 +2724,12 @@ VALUE parse_signature(parserstate *state) {
|
|
2724
2724
|
VALUE dirs = rb_ary_new();
|
2725
2725
|
VALUE decls = rb_ary_new();
|
2726
2726
|
|
2727
|
+
while (state->next_token.type == kUSE) {
|
2728
|
+
rb_ary_push(dirs, parse_use_directive(state));
|
2729
|
+
}
|
2730
|
+
|
2727
2731
|
while (state->next_token.type != pEOF) {
|
2728
|
-
|
2729
|
-
VALUE use = parse_use_directive(state);
|
2730
|
-
rb_ary_push(dirs, use);
|
2731
|
-
} else {
|
2732
|
-
rb_ary_push(decls, parse_decl(state));
|
2733
|
-
}
|
2732
|
+
rb_ary_push(decls, parse_decl(state));
|
2734
2733
|
}
|
2735
2734
|
|
2736
2735
|
VALUE ret = rb_ary_new();
|
data/lib/rbs/cli.rb
CHANGED
@@ -1076,11 +1076,16 @@ EOB
|
|
1076
1076
|
config_path.write(<<~'YAML')
|
1077
1077
|
# Download sources
|
1078
1078
|
sources:
|
1079
|
-
-
|
1079
|
+
- type: git
|
1080
|
+
name: ruby/gem_rbs_collection
|
1080
1081
|
remote: https://github.com/ruby/gem_rbs_collection.git
|
1081
1082
|
revision: main
|
1082
1083
|
repo_dir: gems
|
1083
1084
|
|
1085
|
+
# You can specify local directories as sources also.
|
1086
|
+
# - type: local
|
1087
|
+
# path: path/to/your/local/repository
|
1088
|
+
|
1084
1089
|
# A directory to install the downloaded RBSs
|
1085
1090
|
path: .gem_rbs_collection
|
1086
1091
|
|
@@ -16,7 +16,14 @@ module RBS
|
|
16
16
|
version or raise
|
17
17
|
next if needed? gem_name, version
|
18
18
|
|
19
|
-
|
19
|
+
case
|
20
|
+
when dir.symlink?
|
21
|
+
dir.unlink
|
22
|
+
when dir.directory?
|
23
|
+
FileUtils.remove_entry_secure(dir.to_s)
|
24
|
+
else
|
25
|
+
raise
|
26
|
+
end
|
20
27
|
end
|
21
28
|
end
|
22
29
|
|
@@ -75,7 +75,7 @@ module RBS
|
|
75
75
|
if gems = data["gems"]
|
76
76
|
gems.each do |gem|
|
77
77
|
src = gem["source"]
|
78
|
-
source = Sources.from_config_entry(src)
|
78
|
+
source = Sources.from_config_entry(src, base_directory: lockfile_path.dirname)
|
79
79
|
lockfile.gems[gem["name"]] = {
|
80
80
|
name: gem["name"],
|
81
81
|
version: gem["version"],
|
@@ -106,6 +106,8 @@ module RBS
|
|
106
106
|
meta_path = fullpath.join(gem[:name], gem[:version], Sources::Git::METADATA_FILENAME)
|
107
107
|
raise CollectionNotAvailable unless meta_path.exist?
|
108
108
|
raise CollectionNotAvailable unless library_data(gem) == YAML.load(meta_path.read)
|
109
|
+
when Sources::Local
|
110
|
+
raise CollectionNotAvailable unless fullpath.join(gem[:name], gem[:version]).symlink?
|
109
111
|
end
|
110
112
|
end
|
111
113
|
end
|
@@ -105,27 +105,29 @@ module RBS
|
|
105
105
|
unless locked
|
106
106
|
source =
|
107
107
|
if src_data
|
108
|
-
Sources.from_config_entry(src_data)
|
108
|
+
Sources.from_config_entry(src_data, base_directory: config.config_path.dirname)
|
109
109
|
else
|
110
|
-
find_source(name: name)
|
110
|
+
find_source(name: name)
|
111
111
|
end
|
112
112
|
|
113
|
-
|
114
|
-
|
113
|
+
if source
|
114
|
+
installed_version = version
|
115
|
+
best_version = find_best_version(version: installed_version, versions: source.versions(name))
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
117
|
+
locked = {
|
118
|
+
name: name,
|
119
|
+
version: best_version.to_s,
|
120
|
+
source: source,
|
121
|
+
}
|
122
|
+
end
|
121
123
|
end
|
122
124
|
|
123
|
-
locked
|
124
|
-
|
125
|
-
lockfile.gems[name] = locked
|
125
|
+
if locked
|
126
|
+
lockfile.gems[name] = locked
|
126
127
|
|
127
|
-
|
128
|
-
|
128
|
+
locked[:source].dependencies_of(locked[:name], locked[:version])&.each do |dep|
|
129
|
+
assign_stdlib(name: dep["name"], from_gem: name)
|
130
|
+
end
|
129
131
|
end
|
130
132
|
|
131
133
|
gem_hash[name].dependencies.each do |dep|
|
@@ -66,7 +66,7 @@ module RBS
|
|
66
66
|
def sources
|
67
67
|
@sources ||= (
|
68
68
|
@data['sources']
|
69
|
-
.map { |c| Sources.from_config_entry(c) }
|
69
|
+
.map { |c| Sources.from_config_entry(c, base_directory: @config_path.dirname) }
|
70
70
|
.push(Sources::Stdlib.instance)
|
71
71
|
.push(Sources::Rubygems.instance)
|
72
72
|
)
|
@@ -45,7 +45,12 @@ module RBS
|
|
45
45
|
|
46
46
|
gem_dir = dest.join(name, version)
|
47
47
|
|
48
|
-
|
48
|
+
case
|
49
|
+
when gem_dir.symlink?
|
50
|
+
stdout.puts "Updating to #{format_config_entry(name, version)} from a local source"
|
51
|
+
gem_dir.unlink
|
52
|
+
_install(dest: dest, name: name, version: version)
|
53
|
+
when gem_dir.directory?
|
49
54
|
prev = load_metadata(dir: gem_dir)
|
50
55
|
|
51
56
|
if prev == metadata_content(name: name, version: version)
|
@@ -55,9 +60,11 @@ module RBS
|
|
55
60
|
FileUtils.remove_entry_secure(gem_dir.to_s)
|
56
61
|
_install(dest: dest, name: name, version: version)
|
57
62
|
end
|
58
|
-
|
63
|
+
when !gem_dir.exist?
|
59
64
|
stdout.puts "Installing #{format_config_entry(name, version)}"
|
60
65
|
_install(dest: dest, name: name, version: version)
|
66
|
+
else
|
67
|
+
raise
|
61
68
|
end
|
62
69
|
end
|
63
70
|
|
@@ -0,0 +1,79 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module RBS
|
4
|
+
module Collection
|
5
|
+
module Sources
|
6
|
+
class Local
|
7
|
+
include Base
|
8
|
+
|
9
|
+
attr_reader :path, :full_path
|
10
|
+
|
11
|
+
def initialize(path:, base_directory:)
|
12
|
+
# TODO: resolve relative path from dir of rbs_collection.yaml
|
13
|
+
@path = Pathname(path)
|
14
|
+
@full_path = base_directory / path
|
15
|
+
end
|
16
|
+
|
17
|
+
def has?(name, version)
|
18
|
+
if version
|
19
|
+
@full_path.join(name, version).directory?
|
20
|
+
else
|
21
|
+
not versions(name).empty?
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def versions(name)
|
26
|
+
@full_path.join(name).glob('*/').map { |path| path.basename.to_s }
|
27
|
+
end
|
28
|
+
|
29
|
+
# Create a symlink instead of copying file to refer files in @path.
|
30
|
+
# By avoiding copying RBS files, the users do not need re-run `rbs collection install`
|
31
|
+
# when the RBS files are updated.
|
32
|
+
def install(dest:, name:, version:, stdout:)
|
33
|
+
from = @full_path.join(name, version)
|
34
|
+
gem_dir = dest.join(name, version)
|
35
|
+
|
36
|
+
case
|
37
|
+
when gem_dir.symlink? && gem_dir.readlink == from
|
38
|
+
stdout.puts "Using #{name}:#{version} (#{from})"
|
39
|
+
when gem_dir.symlink?
|
40
|
+
prev = gem_dir.readlink
|
41
|
+
gem_dir.unlink
|
42
|
+
_install(from, dest.join(name, version))
|
43
|
+
stdout.puts "Updating #{name}:#{version} to #{from} from #{prev}"
|
44
|
+
when gem_dir.directory?
|
45
|
+
# TODO: Show version of git source
|
46
|
+
FileUtils.remove_entry_secure(gem_dir.to_s)
|
47
|
+
_install(from, dest.join(name, version))
|
48
|
+
stdout.puts "Updating #{name}:#{version} from git source"
|
49
|
+
when !gem_dir.exist?
|
50
|
+
_install(from, dest.join(name, version))
|
51
|
+
stdout.puts "Installing #{name}:#{version} (#{from})"
|
52
|
+
else
|
53
|
+
raise
|
54
|
+
end
|
55
|
+
end
|
56
|
+
|
57
|
+
private def _install(src, dst)
|
58
|
+
dst.dirname.mkpath
|
59
|
+
File.symlink(src, dst)
|
60
|
+
end
|
61
|
+
|
62
|
+
def manifest_of(name, version)
|
63
|
+
gem_dir = @full_path.join(name, version)
|
64
|
+
raise unless gem_dir.exist?
|
65
|
+
|
66
|
+
manifest_path = gem_dir.join('manifest.yaml')
|
67
|
+
YAML.safe_load(manifest_path.read) if manifest_path.exist?
|
68
|
+
end
|
69
|
+
|
70
|
+
def to_lockfile
|
71
|
+
{
|
72
|
+
'type' => 'local',
|
73
|
+
'path' => @path.to_s,
|
74
|
+
}
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
@@ -4,11 +4,12 @@ require_relative './sources/base'
|
|
4
4
|
require_relative './sources/git'
|
5
5
|
require_relative './sources/stdlib'
|
6
6
|
require_relative './sources/rubygems'
|
7
|
+
require_relative './sources/local'
|
7
8
|
|
8
9
|
module RBS
|
9
10
|
module Collection
|
10
11
|
module Sources
|
11
|
-
def self.from_config_entry(source_entry)
|
12
|
+
def self.from_config_entry(source_entry, base_directory:)
|
12
13
|
case source_entry['type']
|
13
14
|
when 'git', nil # git source by default
|
14
15
|
# @type var source_entry: Git::source_entry
|
@@ -18,6 +19,12 @@ module RBS
|
|
18
19
|
remote: source_entry["remote"],
|
19
20
|
repo_dir: source_entry["repo_dir"]
|
20
21
|
)
|
22
|
+
when 'local'
|
23
|
+
# @type var source_entry: Local::source_entry
|
24
|
+
Local.new(
|
25
|
+
path: source_entry['path'],
|
26
|
+
base_directory: base_directory,
|
27
|
+
)
|
21
28
|
when 'stdlib'
|
22
29
|
Stdlib.instance
|
23
30
|
when 'rubygems'
|
data/lib/rbs/environment.rb
CHANGED
@@ -773,13 +773,14 @@ module RBS
|
|
773
773
|
hash
|
774
774
|
end
|
775
775
|
|
776
|
-
def
|
776
|
+
def unload(buffers)
|
777
777
|
env = Environment.new
|
778
778
|
|
779
|
-
|
780
|
-
|
781
|
-
|
782
|
-
|
779
|
+
buffers_decls.each do |buf, decls|
|
780
|
+
next if buffers.include?(buf)
|
781
|
+
|
782
|
+
dirs = buffer_directives.fetch(buf)
|
783
|
+
env.add_signature(buffer: buf, directives: dirs, decls: decls)
|
783
784
|
end
|
784
785
|
|
785
786
|
env
|
@@ -47,8 +47,9 @@ module RBS
|
|
47
47
|
when path
|
48
48
|
dirs << path
|
49
49
|
when library
|
50
|
-
|
51
|
-
|
50
|
+
case library
|
51
|
+
when 'rubygems', 'set'
|
52
|
+
RBS.logger.warn "`#{library}` has been moved to core library, so it is always loaded. Remove explicit loading `#{library}`"
|
52
53
|
return
|
53
54
|
end
|
54
55
|
|
data/lib/rbs/errors.rb
CHANGED
@@ -20,7 +20,25 @@ module RBS
|
|
20
20
|
class LoadingError < BaseError; end
|
21
21
|
class DefinitionError < BaseError; end
|
22
22
|
|
23
|
+
module DetailedMessageable
|
24
|
+
def detailed_message(highlight: false, **)
|
25
|
+
indent = " " * location.start_column
|
26
|
+
marker = "^" * (location.end_column - location.start_column)
|
27
|
+
|
28
|
+
io = StringIO.new
|
29
|
+
io.puts super
|
30
|
+
io.puts
|
31
|
+
io.print "\e[1m" if highlight
|
32
|
+
io.puts " #{location.buffer.lines[location.end_line - 1]}"
|
33
|
+
io.puts " #{indent}#{marker}"
|
34
|
+
io.print "\e[m" if highlight
|
35
|
+
io.string
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
23
39
|
class ParsingError < BaseError
|
40
|
+
include DetailedMessageable
|
41
|
+
|
24
42
|
attr_reader :location
|
25
43
|
attr_reader :error_message
|
26
44
|
attr_reader :token_type
|
data/lib/rbs/locator.rb
CHANGED
@@ -2,21 +2,24 @@
|
|
2
2
|
|
3
3
|
module RBS
|
4
4
|
class Locator
|
5
|
-
attr_reader :decls
|
5
|
+
attr_reader :decls, :dirs, :buffer
|
6
6
|
|
7
|
-
def initialize(decls:)
|
7
|
+
def initialize(buffer:, dirs:, decls:)
|
8
|
+
@buffer = buffer
|
9
|
+
@dirs = dirs
|
8
10
|
@decls = decls
|
9
11
|
end
|
10
12
|
|
11
|
-
def buffer
|
12
|
-
decls[0].location&.buffer or raise
|
13
|
-
end
|
14
|
-
|
15
13
|
def find(line:, column:)
|
16
14
|
pos = buffer.loc_to_pos([line, column])
|
17
15
|
|
16
|
+
dirs.each do |dir|
|
17
|
+
array = [] #: Array[component]
|
18
|
+
find_in_directive(pos, dir, array) and return array
|
19
|
+
end
|
20
|
+
|
18
21
|
decls.each do |decl|
|
19
|
-
array = []
|
22
|
+
array = [] #: Array[component]
|
20
23
|
find_in_decl(pos, decl: decl, array: array) and return array
|
21
24
|
end
|
22
25
|
|
@@ -36,6 +39,22 @@ module RBS
|
|
36
39
|
end
|
37
40
|
end
|
38
41
|
|
42
|
+
def find_in_directive(pos, dir, array)
|
43
|
+
if test_loc(pos, location: dir.location)
|
44
|
+
array.unshift(dir)
|
45
|
+
|
46
|
+
dir.clauses.each do |clause|
|
47
|
+
if test_loc(pos, location: clause.location)
|
48
|
+
array.unshift(clause)
|
49
|
+
find_in_loc(pos, location: clause.location, array: array)
|
50
|
+
return true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
false
|
56
|
+
end
|
57
|
+
|
39
58
|
def find_in_decl(pos, decl:, array:)
|
40
59
|
if test_loc(pos, location: decl.location)
|
41
60
|
array.unshift(decl)
|
data/lib/rbs/sorter.rb
CHANGED
@@ -34,7 +34,7 @@ module RBS
|
|
34
34
|
-3
|
35
35
|
when Declarations::Constant
|
36
36
|
-2
|
37
|
-
when Declarations::Class, Declarations::Module
|
37
|
+
when Declarations::Class, Declarations::Module, Declarations::Interface
|
38
38
|
-1
|
39
39
|
when Members::Include
|
40
40
|
0.0
|
@@ -102,7 +102,7 @@ module RBS
|
|
102
102
|
member.name.to_s
|
103
103
|
when Declarations::TypeAlias
|
104
104
|
member.name.to_s
|
105
|
-
when Declarations::Class, Declarations::Module
|
105
|
+
when Declarations::Class, Declarations::Module, Declarations::Interface
|
106
106
|
member.name.to_s
|
107
107
|
else
|
108
108
|
raise
|