rbs 1.7.0.beta.5 → 1.8.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.
- checksums.yaml +4 -4
- data/.gitignore +0 -1
- data/CHANGELOG.md +64 -3
- data/Steepfile +0 -1
- data/core/array.rbs +3 -3
- data/core/builtin.rbs +4 -0
- data/core/enumerable.rbs +3 -3
- data/core/env.rbs +881 -0
- data/core/false_class.rbs +2 -0
- data/core/nil_class.rbs +2 -0
- data/core/symbol.rbs +2 -0
- data/core/thread.rbs +1 -1
- data/core/true_class.rbs +2 -0
- data/docs/syntax.md +23 -20
- data/ext/rbs_extension/parser.c +97 -95
- data/ext/rbs_extension/ruby_objs.c +8 -6
- data/ext/rbs_extension/ruby_objs.h +2 -2
- data/lib/rbs/ast/declarations.rb +6 -2
- data/lib/rbs/cli.rb +1 -1
- data/lib/rbs/collection/sources/git.rb +9 -7
- data/lib/rbs/definition_builder.rb +58 -2
- data/lib/rbs/environment.rb +1 -0
- data/lib/rbs/environment_walker.rb +4 -1
- data/lib/rbs/errors.rb +12 -0
- data/lib/rbs/test/setup.rb +1 -0
- data/lib/rbs/type_alias_regularity.rb +115 -0
- data/lib/rbs/types.rb +11 -23
- data/lib/rbs/validator.rb +44 -15
- data/lib/rbs/variance_calculator.rb +52 -24
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +1 -1
- data/lib/rbs.rb +1 -0
- data/schema/decls.json +13 -1
- data/schema/types.json +8 -2
- data/sig/collection/collections.rbs +4 -2
- data/sig/declarations.rbs +9 -6
- data/sig/definition_builder.rbs +36 -0
- data/sig/environment_walker.rbs +26 -0
- data/sig/errors.rbs +10 -0
- data/sig/type_alias_regularity.rbs +92 -0
- data/sig/types.rbs +11 -8
- data/sig/validator.rbs +7 -0
- data/sig/variance_calculator.rbs +50 -0
- data/stdlib/bigdecimal/0/big_decimal.rbs +44 -0
- data/stdlib/csv/0/csv.rbs +49 -3
- data/stdlib/date/0/date.rbs +2 -2
- data/stdlib/set/0/set.rbs +3 -3
- data/steep/Gemfile.lock +10 -10
- metadata +7 -6
- data/lib/rbs/parser.y +0 -1805
- data/lib/ruby/signature.rb +0 -7
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class TypeAliasRegularity
|
|
3
|
+
class Diagnostic
|
|
4
|
+
attr_reader :type_name, :nonregular_type
|
|
5
|
+
|
|
6
|
+
def initialize(type_name:, nonregular_type:)
|
|
7
|
+
@type_name = type_name
|
|
8
|
+
@nonregular_type = nonregular_type
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
attr_reader :env, :builder, :diagnostics
|
|
13
|
+
|
|
14
|
+
def initialize(env:)
|
|
15
|
+
@env = env
|
|
16
|
+
@builder = DefinitionBuilder.new(env: env)
|
|
17
|
+
@diagnostics = {}
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def validate
|
|
21
|
+
diagnostics.clear
|
|
22
|
+
|
|
23
|
+
each_mutual_alias_defs do |names|
|
|
24
|
+
# Find the first generic type alias in strongly connected component.
|
|
25
|
+
# This is to skip the regularity check when the alias is not generic.
|
|
26
|
+
names.each do |name|
|
|
27
|
+
# @type break: nil
|
|
28
|
+
if type = build_alias_type(name)
|
|
29
|
+
# Running validation only once from the first generic type is enough, because they are mutual recursive definition.
|
|
30
|
+
validate_alias_type(type, names, {})
|
|
31
|
+
break
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def validate_alias_type(alias_type, names, types)
|
|
38
|
+
if names.include?(alias_type.name)
|
|
39
|
+
if ex_type = types[alias_type.name]
|
|
40
|
+
unless compatible_args?(ex_type.args, alias_type.args)
|
|
41
|
+
diagnostics[alias_type.name] ||=
|
|
42
|
+
Diagnostic.new(type_name: alias_type.name, nonregular_type: alias_type)
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
return
|
|
46
|
+
else
|
|
47
|
+
types[alias_type.name] = alias_type
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
expanded = builder.expand_alias2(alias_type.name, alias_type.args)
|
|
51
|
+
each_alias_type(expanded) do |at|
|
|
52
|
+
validate_alias_type(at, names, types)
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
def build_alias_type(name)
|
|
58
|
+
entry = env.alias_decls[name] or raise "Unknown alias name: #{name}"
|
|
59
|
+
unless entry.decl.type_params.empty?
|
|
60
|
+
as = entry.decl.type_params.each.map {|param| Types::Variable.new(name: param.name, location: nil) }
|
|
61
|
+
Types::Alias.new(name: name, args: as, location: nil)
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def compatible_args?(args1, args2)
|
|
66
|
+
if args1.size == args2.size
|
|
67
|
+
args1.zip(args2).all? do |t1, t2|
|
|
68
|
+
t1.is_a?(Types::Bases::Any) ||
|
|
69
|
+
t2.is_a?(Types::Bases::Any) ||
|
|
70
|
+
t1 == t2
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
def nonregular?(type_name)
|
|
76
|
+
diagnostics[type_name]
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def each_mutual_alias_defs(&block)
|
|
80
|
+
# @type var each_node: TSort::_EachNode[TypeName]
|
|
81
|
+
each_node = __skip__ = -> (&block) do
|
|
82
|
+
env.alias_decls.each_value do |decl|
|
|
83
|
+
block[decl.name]
|
|
84
|
+
end
|
|
85
|
+
end
|
|
86
|
+
# @type var each_child: TSort::_EachChild[TypeName]
|
|
87
|
+
each_child = __skip__ = -> (name, &block) do
|
|
88
|
+
type = builder.expand_alias1(name)
|
|
89
|
+
each_alias_type(type) do |ty|
|
|
90
|
+
block[ty.name]
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
TSort.each_strongly_connected_component(each_node, each_child) do |names|
|
|
95
|
+
yield Set.new(names)
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
|
|
99
|
+
def each_alias_type(type, &block)
|
|
100
|
+
if type.is_a?(RBS::Types::Alias)
|
|
101
|
+
yield type
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
type.each_type do |ty|
|
|
105
|
+
each_alias_type(ty, &block)
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
def self.validate(env:)
|
|
110
|
+
self.new(env: env).tap do |validator|
|
|
111
|
+
validator.validate()
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
end
|
data/lib/rbs/types.rb
CHANGED
|
@@ -295,39 +295,27 @@ module RBS
|
|
|
295
295
|
|
|
296
296
|
class Alias
|
|
297
297
|
attr_reader :location
|
|
298
|
-
attr_reader :name
|
|
299
298
|
|
|
300
|
-
|
|
299
|
+
include Application
|
|
300
|
+
|
|
301
|
+
def initialize(name:, args:, location:)
|
|
301
302
|
@name = name
|
|
303
|
+
@args = args
|
|
302
304
|
@location = location
|
|
303
305
|
end
|
|
304
306
|
|
|
305
|
-
def ==(other)
|
|
306
|
-
other.is_a?(Alias) && other.name == name
|
|
307
|
-
end
|
|
308
|
-
|
|
309
|
-
alias eql? ==
|
|
310
|
-
|
|
311
|
-
def hash
|
|
312
|
-
self.class.hash ^ name.hash
|
|
313
|
-
end
|
|
314
|
-
|
|
315
|
-
include NoFreeVariables
|
|
316
|
-
include NoSubst
|
|
317
|
-
|
|
318
307
|
def to_json(state = _ = nil)
|
|
319
|
-
{ class: :alias, name: name, location: location }.to_json(state)
|
|
308
|
+
{ class: :alias, name: name, args: args, location: location }.to_json(state)
|
|
320
309
|
end
|
|
321
310
|
|
|
322
|
-
def
|
|
323
|
-
name.
|
|
311
|
+
def sub(s)
|
|
312
|
+
Alias.new(name: name, args: args.map {|ty| ty.sub(s) }, location: location)
|
|
324
313
|
end
|
|
325
314
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
def map_type_name
|
|
315
|
+
def map_type_name(&block)
|
|
329
316
|
Alias.new(
|
|
330
317
|
name: yield(name, location, self),
|
|
318
|
+
args: args.map {|arg| arg.map_type_name(&block) },
|
|
331
319
|
location: location
|
|
332
320
|
)
|
|
333
321
|
end
|
|
@@ -433,7 +421,7 @@ module RBS
|
|
|
433
421
|
return "{ }" if self.fields.empty?
|
|
434
422
|
|
|
435
423
|
fields = self.fields.map do |key, type|
|
|
436
|
-
if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/)
|
|
424
|
+
if key.is_a?(Symbol) && key.match?(/\A[A-Za-z_][A-Za-z_]*\z/)
|
|
437
425
|
"#{key}: #{type}"
|
|
438
426
|
else
|
|
439
427
|
"#{key.inspect} => #{type}"
|
|
@@ -690,7 +678,7 @@ module RBS
|
|
|
690
678
|
|
|
691
679
|
def to_s
|
|
692
680
|
if name
|
|
693
|
-
if Parser::KEYWORDS.include?(name)
|
|
681
|
+
if Parser::KEYWORDS.include?(name.to_s)
|
|
694
682
|
"#{type} `#{name}`"
|
|
695
683
|
else
|
|
696
684
|
"#{type} #{name}"
|
data/lib/rbs/validator.rb
CHANGED
|
@@ -2,10 +2,12 @@ module RBS
|
|
|
2
2
|
class Validator
|
|
3
3
|
attr_reader :env
|
|
4
4
|
attr_reader :resolver
|
|
5
|
+
attr_reader :definition_builder
|
|
5
6
|
|
|
6
7
|
def initialize(env:, resolver:)
|
|
7
8
|
@env = env
|
|
8
9
|
@resolver = resolver
|
|
10
|
+
@definition_builder = DefinitionBuilder.new(env: env)
|
|
9
11
|
end
|
|
10
12
|
|
|
11
13
|
def absolute_type(type, context:)
|
|
@@ -17,25 +19,25 @@ module RBS
|
|
|
17
19
|
# Validates presence of the relative type, and application arity match.
|
|
18
20
|
def validate_type(type, context:)
|
|
19
21
|
case type
|
|
20
|
-
when Types::ClassInstance, Types::Interface
|
|
21
|
-
# @type var type: Types::ClassInstance | Types::Interface
|
|
22
|
+
when Types::ClassInstance, Types::Interface, Types::Alias
|
|
23
|
+
# @type var type: Types::ClassInstance | Types::Interface | Types::Alias
|
|
22
24
|
if type.name.namespace.relative?
|
|
23
25
|
type = _ = absolute_type(type, context: context) do |_|
|
|
24
26
|
NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
|
|
25
27
|
end
|
|
26
28
|
end
|
|
27
29
|
|
|
30
|
+
definition_builder.validate_type_name(type.name, type.location)
|
|
31
|
+
|
|
28
32
|
type_params = case type
|
|
29
33
|
when Types::ClassInstance
|
|
30
|
-
env.class_decls[type.name]
|
|
34
|
+
env.class_decls[type.name].type_params
|
|
31
35
|
when Types::Interface
|
|
32
|
-
env.interface_decls[type.name]
|
|
36
|
+
env.interface_decls[type.name].decl.type_params
|
|
37
|
+
when Types::Alias
|
|
38
|
+
env.alias_decls[type.name].decl.type_params
|
|
33
39
|
end
|
|
34
40
|
|
|
35
|
-
unless type_params
|
|
36
|
-
raise NoTypeFoundError.new(type_name: type.name, location: type.location)
|
|
37
|
-
end
|
|
38
|
-
|
|
39
41
|
InvalidTypeApplicationError.check!(
|
|
40
42
|
type_name: type.name,
|
|
41
43
|
args: type.args,
|
|
@@ -43,10 +45,8 @@ module RBS
|
|
|
43
45
|
location: type.location
|
|
44
46
|
)
|
|
45
47
|
|
|
46
|
-
when Types::
|
|
47
|
-
|
|
48
|
-
type = _ = absolute_type(type, context: context) { type.name.absolute! }
|
|
49
|
-
NoTypeFoundError.check!(type.name, env: env, location: type.location)
|
|
48
|
+
when Types::ClassSingleton
|
|
49
|
+
definition_builder.validate_type_presence(type)
|
|
50
50
|
end
|
|
51
51
|
|
|
52
52
|
type.each_type do |type|
|
|
@@ -55,11 +55,40 @@ module RBS
|
|
|
55
55
|
end
|
|
56
56
|
|
|
57
57
|
def validate_type_alias(entry:)
|
|
58
|
-
|
|
59
|
-
|
|
58
|
+
type_name = entry.decl.name
|
|
59
|
+
|
|
60
|
+
if type_alias_dependency.circular_definition?(type_name)
|
|
60
61
|
location = entry.decl.location or raise
|
|
61
|
-
raise RecursiveTypeAliasError.new(alias_names: [
|
|
62
|
+
raise RecursiveTypeAliasError.new(alias_names: [type_name], location: location)
|
|
62
63
|
end
|
|
64
|
+
|
|
65
|
+
if diagnostic = type_alias_regularity.nonregular?(type_name)
|
|
66
|
+
location = entry.decl.location or raise
|
|
67
|
+
raise NonregularTypeAliasError.new(diagnostic: diagnostic, location: location)
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
unless entry.decl.type_params.empty?
|
|
71
|
+
calculator = VarianceCalculator.new(builder: definition_builder)
|
|
72
|
+
result = calculator.in_type_alias(name: type_name)
|
|
73
|
+
if set = result.incompatible?(entry.decl.type_params)
|
|
74
|
+
set.each do |param_name|
|
|
75
|
+
param = entry.decl.type_params[param_name] or raise
|
|
76
|
+
raise InvalidVarianceAnnotationError.new(
|
|
77
|
+
type_name: type_name,
|
|
78
|
+
param: param,
|
|
79
|
+
location: entry.decl.type.location
|
|
80
|
+
)
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
def type_alias_dependency
|
|
87
|
+
@type_alias_dependency ||= TypeAliasDependency.new(env: env)
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
def type_alias_regularity
|
|
91
|
+
@type_alias_regularity ||= TypeAliasRegularity.validate(env: env)
|
|
63
92
|
end
|
|
64
93
|
end
|
|
65
94
|
end
|
|
@@ -54,6 +54,21 @@ module RBS
|
|
|
54
54
|
false
|
|
55
55
|
end
|
|
56
56
|
end
|
|
57
|
+
|
|
58
|
+
def incompatible?(params)
|
|
59
|
+
# @type set: Hash[Symbol]
|
|
60
|
+
set = Set[]
|
|
61
|
+
|
|
62
|
+
params.each do |param|
|
|
63
|
+
unless compatible?(param.name, with_annotation: param.variance)
|
|
64
|
+
set << param.name
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
unless set.empty?
|
|
69
|
+
set
|
|
70
|
+
end
|
|
71
|
+
end
|
|
57
72
|
end
|
|
58
73
|
|
|
59
74
|
attr_reader :builder
|
|
@@ -69,19 +84,12 @@ module RBS
|
|
|
69
84
|
def in_method_type(method_type:, variables:)
|
|
70
85
|
result = Result.new(variables: variables)
|
|
71
86
|
|
|
72
|
-
method_type.type
|
|
73
|
-
type(param.type, result: result, context: :contravariant)
|
|
74
|
-
end
|
|
87
|
+
function(method_type.type, result: result, context: :covariant)
|
|
75
88
|
|
|
76
89
|
if block = method_type.block
|
|
77
|
-
block.type
|
|
78
|
-
type(param.type, result: result, context: :covariant)
|
|
79
|
-
end
|
|
80
|
-
type(block.type.return_type, result: result, context: :contravariant)
|
|
90
|
+
function(block.type, result: result, context: :contravariant)
|
|
81
91
|
end
|
|
82
92
|
|
|
83
|
-
type(method_type.type.return_type, result: result, context: :covariant)
|
|
84
|
-
|
|
85
93
|
result
|
|
86
94
|
end
|
|
87
95
|
|
|
@@ -97,6 +105,14 @@ module RBS
|
|
|
97
105
|
end
|
|
98
106
|
end
|
|
99
107
|
|
|
108
|
+
def in_type_alias(name:)
|
|
109
|
+
decl = env.alias_decls[name].decl or raise
|
|
110
|
+
variables = decl.type_params.each.map(&:name)
|
|
111
|
+
Result.new(variables: variables).tap do |result|
|
|
112
|
+
type(decl.type, result: result, context: :covariant)
|
|
113
|
+
end
|
|
114
|
+
end
|
|
115
|
+
|
|
100
116
|
def type(type, result:, context:)
|
|
101
117
|
case type
|
|
102
118
|
when Types::Variable
|
|
@@ -110,7 +126,7 @@ module RBS
|
|
|
110
126
|
result.invariant(type.name)
|
|
111
127
|
end
|
|
112
128
|
end
|
|
113
|
-
when Types::ClassInstance, Types::Interface
|
|
129
|
+
when Types::ClassInstance, Types::Interface, Types::Alias
|
|
114
130
|
NoTypeFoundError.check!(type.name,
|
|
115
131
|
env: env,
|
|
116
132
|
location: type.location)
|
|
@@ -120,6 +136,8 @@ module RBS
|
|
|
120
136
|
env.class_decls[type.name].type_params
|
|
121
137
|
when Types::Interface
|
|
122
138
|
env.interface_decls[type.name].decl.type_params
|
|
139
|
+
when Types::Alias
|
|
140
|
+
env.alias_decls[type.name].decl.type_params
|
|
123
141
|
end
|
|
124
142
|
|
|
125
143
|
type.args.each.with_index do |ty, i|
|
|
@@ -130,26 +148,36 @@ module RBS
|
|
|
130
148
|
when :covariant
|
|
131
149
|
type(ty, result: result, context: context)
|
|
132
150
|
when :contravariant
|
|
133
|
-
|
|
134
|
-
con = case context
|
|
135
|
-
when :invariant
|
|
136
|
-
:invariant
|
|
137
|
-
when :covariant
|
|
138
|
-
:contravariant
|
|
139
|
-
when :contravariant
|
|
140
|
-
:covariant
|
|
141
|
-
else
|
|
142
|
-
raise
|
|
143
|
-
end
|
|
144
|
-
type(ty, result: result, context: con)
|
|
151
|
+
type(ty, result: result, context: negate(context))
|
|
145
152
|
end
|
|
146
153
|
end
|
|
147
|
-
when Types::
|
|
148
|
-
|
|
154
|
+
when Types::Proc
|
|
155
|
+
function(type.type, result: result, context: context)
|
|
156
|
+
else
|
|
149
157
|
type.each_type do |ty|
|
|
150
158
|
type(ty, result: result, context: context)
|
|
151
159
|
end
|
|
152
160
|
end
|
|
153
161
|
end
|
|
162
|
+
|
|
163
|
+
def function(type, result:, context:)
|
|
164
|
+
type.each_param do |param|
|
|
165
|
+
type(param.type, result: result, context: negate(context))
|
|
166
|
+
end
|
|
167
|
+
type(type.return_type, result: result, context: context)
|
|
168
|
+
end
|
|
169
|
+
|
|
170
|
+
def negate(variance)
|
|
171
|
+
case variance
|
|
172
|
+
when :invariant
|
|
173
|
+
:invariant
|
|
174
|
+
when :covariant
|
|
175
|
+
:contravariant
|
|
176
|
+
when :contravariant
|
|
177
|
+
:covariant
|
|
178
|
+
else
|
|
179
|
+
raise
|
|
180
|
+
end
|
|
181
|
+
end
|
|
154
182
|
end
|
|
155
183
|
end
|
data/lib/rbs/version.rb
CHANGED
data/lib/rbs/writer.rb
CHANGED
|
@@ -119,7 +119,7 @@ module RBS
|
|
|
119
119
|
when AST::Declarations::Alias
|
|
120
120
|
write_comment decl.comment
|
|
121
121
|
write_annotation decl.annotations
|
|
122
|
-
puts "type #{decl.name} = #{decl.type}"
|
|
122
|
+
puts "type #{name_and_params(decl.name, decl.type_params)} = #{decl.type}"
|
|
123
123
|
|
|
124
124
|
when AST::Declarations::Interface
|
|
125
125
|
write_comment decl.comment
|
data/lib/rbs.rb
CHANGED
data/schema/decls.json
CHANGED
|
@@ -12,6 +12,18 @@
|
|
|
12
12
|
"name": {
|
|
13
13
|
"type": "string"
|
|
14
14
|
},
|
|
15
|
+
"type_params": {
|
|
16
|
+
"type": "object",
|
|
17
|
+
"properties": {
|
|
18
|
+
"params": {
|
|
19
|
+
"type": "array",
|
|
20
|
+
"items": {
|
|
21
|
+
"$ref": "#/definitions/moduleTypeParam"
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
"required": ["params"]
|
|
26
|
+
},
|
|
15
27
|
"type": {
|
|
16
28
|
"$ref": "types.json"
|
|
17
29
|
},
|
|
@@ -28,7 +40,7 @@
|
|
|
28
40
|
"$ref": "comment.json"
|
|
29
41
|
}
|
|
30
42
|
},
|
|
31
|
-
"required": ["declaration", "name", "type", "annotations", "location", "comment"]
|
|
43
|
+
"required": ["declaration", "name", "type_params", "type", "annotations", "location", "comment"]
|
|
32
44
|
},
|
|
33
45
|
"constant": {
|
|
34
46
|
"title": "Constant declaration: `VERSION: String`, ...",
|
data/schema/types.json
CHANGED
|
@@ -106,7 +106,7 @@
|
|
|
106
106
|
"required": ["class", "name", "args", "location"]
|
|
107
107
|
},
|
|
108
108
|
"alias": {
|
|
109
|
-
"title": "Type alias: `u`, `ty`, `json`, ...",
|
|
109
|
+
"title": "Type alias: `u`, `ty`, `json`, `list[Integer]`, ...",
|
|
110
110
|
"type": "object",
|
|
111
111
|
"properties": {
|
|
112
112
|
"class": {
|
|
@@ -116,11 +116,17 @@
|
|
|
116
116
|
"name": {
|
|
117
117
|
"type": "string"
|
|
118
118
|
},
|
|
119
|
+
"args": {
|
|
120
|
+
"type": "array",
|
|
121
|
+
"items": {
|
|
122
|
+
"$ref": "#"
|
|
123
|
+
}
|
|
124
|
+
},
|
|
119
125
|
"location": {
|
|
120
126
|
"$ref": "location.json"
|
|
121
127
|
}
|
|
122
128
|
},
|
|
123
|
-
"required": ["class", "name", "location"]
|
|
129
|
+
"required": ["class", "name", "args", "location"]
|
|
124
130
|
},
|
|
125
131
|
"tuple": {
|
|
126
132
|
"title": "Tuple type: `[Foo, bar]`, ...",
|
|
@@ -46,6 +46,8 @@ module RBS
|
|
|
46
46
|
|
|
47
47
|
def _install: (dest: Pathname , config_entry: Config::gem_entry) -> void
|
|
48
48
|
|
|
49
|
+
def cp_r: (Pathname, Pathname) -> void
|
|
50
|
+
|
|
49
51
|
def setup!: (revision: String) -> void
|
|
50
52
|
|
|
51
53
|
def need_to_fetch?: (String revision ) -> bool
|
|
@@ -60,9 +62,9 @@ module RBS
|
|
|
60
62
|
|
|
61
63
|
def resolve_revision: () -> String
|
|
62
64
|
|
|
63
|
-
def git: (*String cmd) -> String
|
|
65
|
+
def git: (*String cmd, **untyped opt) -> String
|
|
64
66
|
|
|
65
|
-
def sh!: (*String cmd) -> String
|
|
67
|
+
def sh!: (*String cmd, **untyped opt) -> String
|
|
66
68
|
|
|
67
69
|
def format_config_entry: (Config::gem_entry) -> String
|
|
68
70
|
end
|
data/sig/declarations.rbs
CHANGED
|
@@ -217,19 +217,22 @@ module RBS
|
|
|
217
217
|
end
|
|
218
218
|
|
|
219
219
|
class Alias < Base
|
|
220
|
-
# type loc = Location
|
|
221
|
-
# ^^^^
|
|
222
|
-
# ^^^
|
|
223
|
-
#
|
|
224
|
-
|
|
220
|
+
# type loc[T] = Location[T, bot]
|
|
221
|
+
# ^^^^ keyword
|
|
222
|
+
# ^^^ name
|
|
223
|
+
# ^^^ type_params
|
|
224
|
+
# ^ eq
|
|
225
|
+
#
|
|
226
|
+
type loc = Location[:keyword | :name | :eq, :type_params]
|
|
225
227
|
|
|
226
228
|
attr_reader name: TypeName
|
|
229
|
+
attr_reader type_params: ModuleTypeParams
|
|
227
230
|
attr_reader type: Types::t
|
|
228
231
|
attr_reader annotations: Array[Annotation]
|
|
229
232
|
attr_reader location: loc?
|
|
230
233
|
attr_reader comment: Comment?
|
|
231
234
|
|
|
232
|
-
def initialize: (name: TypeName, type: Types::t, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
|
|
235
|
+
def initialize: (name: TypeName, type_params: ModuleTypeParams, type: Types::t, annotations: Array[Annotation], location: loc?, comment: Comment?) -> void
|
|
233
236
|
|
|
234
237
|
include _HashEqual
|
|
235
238
|
include _ToJson
|
data/sig/definition_builder.rbs
CHANGED
|
@@ -43,8 +43,44 @@ module RBS
|
|
|
43
43
|
|
|
44
44
|
def define_methods: (Definition, interface_methods: Hash[Symbol, Definition::Method], methods: MethodBuilder::Methods, super_interface_method: bool) -> void
|
|
45
45
|
|
|
46
|
+
# Validates presence of type names recursively.
|
|
47
|
+
# Assumes the type names are already resolved.
|
|
48
|
+
#
|
|
49
|
+
def validate_type_presence: (Types::t) -> void
|
|
50
|
+
|
|
51
|
+
def validate_type_name: (TypeName, Location[untyped, untyped]?) -> void
|
|
52
|
+
|
|
53
|
+
# Expand a type alias of given name without type arguments.
|
|
54
|
+
# Raises an error if the type alias requires arguments.
|
|
55
|
+
#
|
|
56
|
+
# Assume `type foo[T] = [T, T]`:
|
|
57
|
+
#
|
|
58
|
+
# ```
|
|
59
|
+
# expand_alias("::foo") # => error
|
|
60
|
+
# ```
|
|
61
|
+
#
|
|
46
62
|
def expand_alias: (TypeName) -> Types::t
|
|
47
63
|
|
|
64
|
+
# Expand a type alias of given name with arguments of `untyped`.
|
|
65
|
+
#
|
|
66
|
+
# Assume `type foo[T] = [T, T]`:
|
|
67
|
+
#
|
|
68
|
+
# ```
|
|
69
|
+
# expand_alias1("::foo") # => [untyped, untyped]
|
|
70
|
+
# ```
|
|
71
|
+
#
|
|
72
|
+
def expand_alias1: (TypeName) -> Types::t
|
|
73
|
+
|
|
74
|
+
# Expand a type alias of given name with `args`.
|
|
75
|
+
#
|
|
76
|
+
# Assume `type foo[T] = [T, T]`:
|
|
77
|
+
#
|
|
78
|
+
# ```
|
|
79
|
+
# expand_alias2("::foo", ["::Integer"]) # => [::Integer, ::Integer]
|
|
80
|
+
# ```
|
|
81
|
+
#
|
|
82
|
+
def expand_alias2: (TypeName, Array[Types::t] args) -> Types::t
|
|
83
|
+
|
|
48
84
|
def update: (env: Environment, ancestor_builder: AncestorBuilder, except: _Each[TypeName]) -> DefinitionBuilder
|
|
49
85
|
end
|
|
50
86
|
end
|
data/sig/environment_walker.rbs
CHANGED
|
@@ -1,4 +1,28 @@
|
|
|
1
1
|
module RBS
|
|
2
|
+
# EnvironmentWalker provides topological sort of class/module definitions.
|
|
3
|
+
#
|
|
4
|
+
# If a method, attribute, or ancestor in a class definition have a reference to another class, it is dependency.
|
|
5
|
+
#
|
|
6
|
+
# ```rb
|
|
7
|
+
# walker = EnvironmentWalker.new(env: env)
|
|
8
|
+
#
|
|
9
|
+
# walker.each_strongly_connected_component do |scc|
|
|
10
|
+
# # Yields an array of strongly connected components.
|
|
11
|
+
# end
|
|
12
|
+
# ```
|
|
13
|
+
#
|
|
14
|
+
# The `#only_ancestors!` method limits the dependency only to ancestors.
|
|
15
|
+
# Only super classes and included modules are dependencies with the option.
|
|
16
|
+
# This is useful to calculate the dependencies of class hierarchy.
|
|
17
|
+
#
|
|
18
|
+
# ```rb
|
|
19
|
+
# walker = EnvironmentWalker.new(env: env).only_ancestors!
|
|
20
|
+
#
|
|
21
|
+
# walker.each_strongly_connected_component do |scc|
|
|
22
|
+
# # Yields an array of strongly connected components.
|
|
23
|
+
# end
|
|
24
|
+
# ```
|
|
25
|
+
#
|
|
2
26
|
class EnvironmentWalker
|
|
3
27
|
class InstanceNode
|
|
4
28
|
attr_reader type_name: TypeName
|
|
@@ -32,6 +56,8 @@ module RBS
|
|
|
32
56
|
|
|
33
57
|
def tsort_each_child: (node) { (node) -> void } -> void
|
|
34
58
|
|
|
59
|
+
private
|
|
60
|
+
|
|
35
61
|
def each_type_name: (Types::t) { (TypeName) -> void } -> void
|
|
36
62
|
|
|
37
63
|
def each_type_node: (Types::t) { (node) -> void } -> void
|
data/sig/errors.rbs
CHANGED
|
@@ -220,4 +220,14 @@ module RBS
|
|
|
220
220
|
|
|
221
221
|
def name: () -> String
|
|
222
222
|
end
|
|
223
|
+
|
|
224
|
+
class NonregularTypeAliasError < LoadingError
|
|
225
|
+
# Diagnostic reported from `TypeAliasRegularity`.
|
|
226
|
+
attr_reader diagnostic: TypeAliasRegularity::Diagnostic
|
|
227
|
+
|
|
228
|
+
# Location of the definition.
|
|
229
|
+
attr_reader location: Location[untyped, untyped]?
|
|
230
|
+
|
|
231
|
+
def initialize: (diagnostic: TypeAliasRegularity::Diagnostic, location: Location[untyped, untyped]?) -> void
|
|
232
|
+
end
|
|
223
233
|
end
|