rbs 0.18.1 → 1.0.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +31 -0
- data/Rakefile +12 -0
- data/Steepfile +2 -1
- data/bin/annotate-with-rdoc +0 -4
- data/core/builtin.rbs +4 -0
- data/core/file.rbs +3 -4
- data/core/hash.rbs +1 -3
- data/core/io.rbs +165 -7
- data/core/kernel.rbs +1 -1
- data/core/module.rbs +41 -0
- data/core/time.rbs +0 -12
- data/docs/syntax.md +0 -17
- data/goodcheck.yml +22 -2
- data/lib/rbs.rb +2 -0
- data/lib/rbs/ast/declarations.rb +7 -49
- data/lib/rbs/ast/members.rb +10 -4
- data/lib/rbs/cli.rb +10 -10
- data/lib/rbs/definition.rb +70 -3
- data/lib/rbs/definition_builder.rb +573 -984
- data/lib/rbs/definition_builder/ancestor_builder.rb +525 -0
- data/lib/rbs/definition_builder/method_builder.rb +217 -0
- data/lib/rbs/environment.rb +6 -8
- data/lib/rbs/environment_loader.rb +8 -4
- data/lib/rbs/errors.rb +88 -121
- data/lib/rbs/method_type.rb +1 -31
- data/lib/rbs/parser.rb +1082 -1014
- data/lib/rbs/parser.y +108 -76
- data/lib/rbs/prototype/rb.rb +18 -3
- data/lib/rbs/prototype/rbi.rb +6 -6
- data/lib/rbs/prototype/runtime.rb +71 -35
- data/lib/rbs/substitution.rb +4 -0
- data/lib/rbs/test.rb +3 -1
- data/lib/rbs/test/hook.rb +26 -8
- data/lib/rbs/types.rb +68 -7
- data/lib/rbs/validator.rb +4 -2
- data/lib/rbs/variance_calculator.rb +5 -1
- data/lib/rbs/version.rb +1 -1
- data/lib/rbs/writer.rb +13 -4
- data/schema/members.json +5 -1
- data/sig/ancestor_builder.rbs +98 -0
- data/sig/declarations.rbs +4 -16
- data/sig/definition.rbs +6 -1
- data/sig/definition_builder.rbs +15 -67
- data/sig/errors.rbs +159 -0
- data/sig/members.rbs +4 -1
- data/sig/method_builder.rbs +71 -0
- data/sig/method_types.rbs +3 -16
- data/sig/substitution.rbs +3 -0
- data/sig/type_name_resolver.rbs +4 -2
- data/sig/types.rbs +17 -15
- data/sig/validator.rbs +12 -0
- data/stdlib/csv/0/csv.rbs +3 -0
- data/stdlib/dbm/0/dbm.rbs +0 -2
- data/stdlib/logger/0/log_device.rbs +1 -2
- data/stdlib/monitor/0/monitor.rbs +119 -0
- data/stdlib/pathname/0/pathname.rbs +1 -1
- data/stdlib/prime/0/prime.rbs +6 -0
- data/stdlib/securerandom/0/securerandom.rbs +2 -0
- data/stdlib/time/0/time.rbs +327 -0
- data/stdlib/tsort/0/tsort.rbs +8 -0
- data/stdlib/uri/0/common.rbs +401 -0
- data/stdlib/uri/0/rfc2396_parser.rbs +9 -0
- data/stdlib/uri/0/rfc3986_parser.rbs +2 -0
- data/steep/Gemfile.lock +13 -14
- metadata +16 -5
data/lib/rbs/substitution.rb
CHANGED
data/lib/rbs/test.rb
CHANGED
data/lib/rbs/test/hook.rb
CHANGED
@@ -67,12 +67,20 @@ module RBS
|
|
67
67
|
end
|
68
68
|
end
|
69
69
|
|
70
|
-
def self.hook_method_source(prefix, method_name, key, random:)
|
70
|
+
def self.hook_method_source(prefix, method_name, key, random:, params:)
|
71
71
|
with_name, without_name = alias_names(method_name, random)
|
72
72
|
full_method_name = "#{prefix}#{method_name}"
|
73
73
|
|
74
|
+
param_source = params.take_while {|param| param[0] == :req }.map(&:last) + ["*rest_args__#{random}"]
|
75
|
+
block_param = "block__#{random}"
|
76
|
+
|
77
|
+
RBS.logger.debug {
|
78
|
+
"Generating method definition: def #{with_name}(#{param_source.join(", ")}, &#{block_param}) ..."
|
79
|
+
}
|
80
|
+
|
74
81
|
[__LINE__ + 1, <<RUBY]
|
75
|
-
def #{with_name}(
|
82
|
+
def #{with_name}(#{param_source.join(", ")}, &#{block_param})
|
83
|
+
args = [#{param_source.join(", ")}]
|
76
84
|
::RBS.logger.debug { "#{full_method_name} with arguments: [" + args.map(&:inspect).join(", ") + "]" }
|
77
85
|
|
78
86
|
begin
|
@@ -81,14 +89,20 @@ def #{with_name}(*args, &block)
|
|
81
89
|
|
82
90
|
if block_given?
|
83
91
|
receiver = self
|
84
|
-
|
92
|
+
block_receives_block = #{block_param}.parameters.last&.yield_self {|type, _| type == :block }
|
93
|
+
|
94
|
+
wrapped_block = proc do |*block_args, &block2|
|
85
95
|
return_from_block = false
|
86
96
|
|
87
97
|
begin
|
88
98
|
block_result = if receiver.equal?(self)
|
89
|
-
|
99
|
+
if block_receives_block
|
100
|
+
#{block_param}.call(*block_args, &block2)
|
101
|
+
else
|
102
|
+
yield(*block_args)
|
103
|
+
end
|
90
104
|
else
|
91
|
-
instance_exec(*block_args,
|
105
|
+
instance_exec(*block_args, &#{block_param})
|
92
106
|
end
|
93
107
|
|
94
108
|
return_from_block = true
|
@@ -117,7 +131,9 @@ def #{with_name}(*args, &block)
|
|
117
131
|
end
|
118
132
|
|
119
133
|
block_result
|
120
|
-
end
|
134
|
+
end.ruby2_keywords
|
135
|
+
|
136
|
+
result = __send__(:"#{without_name}", *args, &wrapped_block)
|
121
137
|
else
|
122
138
|
result = __send__(:"#{without_name}", *args)
|
123
139
|
end
|
@@ -163,7 +179,8 @@ RUBY
|
|
163
179
|
|
164
180
|
def self.hook_instance_method(klass, method, key:)
|
165
181
|
random = SecureRandom.hex(4)
|
166
|
-
|
182
|
+
params = klass.instance_method(method).parameters
|
183
|
+
line, source = hook_method_source("#{klass}#", method, key, random: random, params: params)
|
167
184
|
|
168
185
|
klass.module_eval(source, __FILE__, line)
|
169
186
|
setup_alias_method_chain klass, method, random: random
|
@@ -171,7 +188,8 @@ RUBY
|
|
171
188
|
|
172
189
|
def self.hook_singleton_method(klass, method, key:)
|
173
190
|
random = SecureRandom.hex(4)
|
174
|
-
|
191
|
+
params = klass.method(method).parameters
|
192
|
+
line, source = hook_method_source("#{klass}.",method, key, random: random, params: params)
|
175
193
|
|
176
194
|
klass.singleton_class.module_eval(source, __FILE__, line)
|
177
195
|
setup_alias_method_chain klass.singleton_class, method, random: random
|
data/lib/rbs/types.rb
CHANGED
@@ -943,48 +943,108 @@ module RBS
|
|
943
943
|
end
|
944
944
|
|
945
945
|
def has_keyword?
|
946
|
-
!required_keywords.empty? || !optional_keywords.empty? || rest_keywords
|
946
|
+
if !required_keywords.empty? || !optional_keywords.empty? || rest_keywords
|
947
|
+
true
|
948
|
+
else
|
949
|
+
false
|
950
|
+
end
|
951
|
+
end
|
952
|
+
end
|
953
|
+
|
954
|
+
class Block
|
955
|
+
attr_reader :type
|
956
|
+
attr_reader :required
|
957
|
+
|
958
|
+
def initialize(type:, required:)
|
959
|
+
@type = type
|
960
|
+
@required = required ? true : false
|
961
|
+
end
|
962
|
+
|
963
|
+
def ==(other)
|
964
|
+
other.is_a?(Block) &&
|
965
|
+
other.type == type &&
|
966
|
+
other.required == required
|
967
|
+
end
|
968
|
+
|
969
|
+
def to_json(*a)
|
970
|
+
{
|
971
|
+
type: type,
|
972
|
+
required: required
|
973
|
+
}.to_json(*a)
|
974
|
+
end
|
975
|
+
|
976
|
+
def sub(s)
|
977
|
+
self.class.new(
|
978
|
+
type: type.sub(s),
|
979
|
+
required: required
|
980
|
+
)
|
981
|
+
end
|
982
|
+
|
983
|
+
def map_type(&block)
|
984
|
+
Block.new(
|
985
|
+
required: required,
|
986
|
+
type: type.map_type(&block)
|
987
|
+
)
|
947
988
|
end
|
948
989
|
end
|
949
990
|
|
950
991
|
class Proc
|
951
992
|
attr_reader :type
|
993
|
+
attr_reader :block
|
952
994
|
attr_reader :location
|
953
995
|
|
954
|
-
def initialize(location:, type:)
|
996
|
+
def initialize(location:, type:, block:)
|
955
997
|
@type = type
|
998
|
+
@block = block
|
956
999
|
@location = location
|
957
1000
|
end
|
958
1001
|
|
959
1002
|
def ==(other)
|
960
|
-
other.is_a?(Proc) && other.type == type
|
1003
|
+
other.is_a?(Proc) && other.type == type && other.block == block
|
961
1004
|
end
|
962
1005
|
|
963
1006
|
alias eql? ==
|
964
1007
|
|
965
1008
|
def hash
|
966
|
-
self.class.hash ^ type.hash
|
1009
|
+
self.class.hash ^ type.hash ^ block.hash
|
967
1010
|
end
|
968
1011
|
|
969
1012
|
def free_variables(set = Set[])
|
970
1013
|
type.free_variables(set)
|
1014
|
+
block&.type&.free_variables(set)
|
1015
|
+
set
|
971
1016
|
end
|
972
1017
|
|
973
1018
|
def to_json(*a)
|
974
|
-
{
|
1019
|
+
{
|
1020
|
+
class: :proc,
|
1021
|
+
type: type,
|
1022
|
+
block: block,
|
1023
|
+
location: location
|
1024
|
+
}.to_json(*a)
|
975
1025
|
end
|
976
1026
|
|
977
1027
|
def sub(s)
|
978
|
-
self.class.new(type: type.sub(s), location: location)
|
1028
|
+
self.class.new(type: type.sub(s), block: block&.sub(s), location: location)
|
979
1029
|
end
|
980
1030
|
|
981
1031
|
def to_s(level = 0)
|
982
|
-
|
1032
|
+
case
|
1033
|
+
when b = block
|
1034
|
+
if b.required
|
1035
|
+
"^(#{type.param_to_s}) { (#{b.type.param_to_s}) -> #{b.type.return_to_s} } -> #{type.return_to_s}"
|
1036
|
+
else
|
1037
|
+
"^(#{type.param_to_s}) ?{ (#{b.type.param_to_s}) -> #{b.type.return_to_s} } -> #{type.return_to_s}"
|
1038
|
+
end
|
1039
|
+
else
|
1040
|
+
"^(#{type.param_to_s}) -> #{type.return_to_s}"
|
1041
|
+
end
|
983
1042
|
end
|
984
1043
|
|
985
1044
|
def each_type(&block)
|
986
1045
|
if block
|
987
1046
|
type.each_type(&block)
|
1047
|
+
self.block&.type&.each_type(&block)
|
988
1048
|
else
|
989
1049
|
enum_for :each_type
|
990
1050
|
end
|
@@ -993,6 +1053,7 @@ module RBS
|
|
993
1053
|
def map_type_name(&block)
|
994
1054
|
Proc.new(
|
995
1055
|
type: type.map_type_name(&block),
|
1056
|
+
block: self.block&.map_type {|type| type.map_type_name(&block) },
|
996
1057
|
location: location
|
997
1058
|
)
|
998
1059
|
end
|
data/lib/rbs/validator.rb
CHANGED
@@ -18,8 +18,9 @@ module RBS
|
|
18
18
|
def validate_type(type, context:)
|
19
19
|
case type
|
20
20
|
when Types::ClassInstance, Types::Interface
|
21
|
+
# @type var type: Types::ClassInstance | Types::Interface
|
21
22
|
if type.name.namespace.relative?
|
22
|
-
type = absolute_type(type, context: context) do |
|
23
|
+
type = _ = absolute_type(type, context: context) do |_|
|
23
24
|
NoTypeFoundError.check!(type.name.absolute!, env: env, location: type.location)
|
24
25
|
end
|
25
26
|
end
|
@@ -43,7 +44,8 @@ module RBS
|
|
43
44
|
)
|
44
45
|
|
45
46
|
when Types::Alias, Types::ClassSingleton
|
46
|
-
type
|
47
|
+
# @type var type: Types::Alias | Types::ClassSingleton
|
48
|
+
type = _ = absolute_type(type, context: context) { type.name.absolute! }
|
47
49
|
NoTypeFoundError.check!(type.name, env: env, location: type.location)
|
48
50
|
end
|
49
51
|
|
@@ -86,7 +86,11 @@ module RBS
|
|
86
86
|
end
|
87
87
|
|
88
88
|
def in_inherit(name:, args:, variables:)
|
89
|
-
type =
|
89
|
+
type = if name.class?
|
90
|
+
Types::ClassInstance.new(name: name, args: args, location: nil)
|
91
|
+
else
|
92
|
+
Types::Interface.new(name: name, args: args, location: nil)
|
93
|
+
end
|
90
94
|
|
91
95
|
Result.new(variables: variables).tap do |result|
|
92
96
|
type(type, result: result, context: :covariant)
|
data/lib/rbs/version.rb
CHANGED
data/lib/rbs/writer.rb
CHANGED
@@ -232,10 +232,11 @@ module RBS
|
|
232
232
|
def method_name(name)
|
233
233
|
s = name.to_s
|
234
234
|
|
235
|
-
if
|
236
|
-
|
237
|
-
else
|
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))
|
238
237
|
s
|
238
|
+
else
|
239
|
+
"`#{s}`"
|
239
240
|
end
|
240
241
|
end
|
241
242
|
|
@@ -285,7 +286,15 @@ module RBS
|
|
285
286
|
else
|
286
287
|
"(#{attr.ivar_name})"
|
287
288
|
end
|
288
|
-
|
289
|
+
|
290
|
+
receiver = case attr.kind
|
291
|
+
when :singleton
|
292
|
+
"self."
|
293
|
+
when :instance
|
294
|
+
""
|
295
|
+
end
|
296
|
+
|
297
|
+
"attr_#{kind} #{receiver}#{attr.name}#{var}: #{attr.type}"
|
289
298
|
end
|
290
299
|
|
291
300
|
def preserve_empty_line(prev, decl)
|
data/schema/members.json
CHANGED
@@ -165,6 +165,10 @@
|
|
165
165
|
"name": {
|
166
166
|
"type": "string"
|
167
167
|
},
|
168
|
+
"kind": {
|
169
|
+
"type": "string",
|
170
|
+
"enum": ["instance", "singleton"]
|
171
|
+
},
|
168
172
|
"type": {
|
169
173
|
"$ref": "types.json"
|
170
174
|
},
|
@@ -194,7 +198,7 @@
|
|
194
198
|
"$ref": "location.json"
|
195
199
|
}
|
196
200
|
},
|
197
|
-
"required": ["member", "name", "ivar_name", "type", "annotations", "comment", "location"]
|
201
|
+
"required": ["member", "name", "ivar_name", "type", "annotations", "kind", "comment", "location"]
|
198
202
|
},
|
199
203
|
"visibility": {
|
200
204
|
"title": "Visibility specifier",
|
@@ -0,0 +1,98 @@
|
|
1
|
+
module RBS
|
2
|
+
class DefinitionBuilder
|
3
|
+
class AncestorBuilder
|
4
|
+
class OneAncestors
|
5
|
+
attr_reader type_name: TypeName
|
6
|
+
attr_reader params: Array[Symbol]?
|
7
|
+
attr_reader super_class: Definition::Ancestor::t?
|
8
|
+
attr_reader self_types: Array[Definition::Ancestor::Instance]?
|
9
|
+
attr_reader included_modules: Array[Definition::Ancestor::Instance]?
|
10
|
+
attr_reader included_interfaces: Array[Definition::Ancestor::Instance]?
|
11
|
+
attr_reader prepended_modules: Array[Definition::Ancestor::Instance]?
|
12
|
+
attr_reader extended_modules: Array[Definition::Ancestor::Instance]?
|
13
|
+
attr_reader extended_interfaces: Array[Definition::Ancestor::Instance]?
|
14
|
+
|
15
|
+
def initialize: (type_name: TypeName,
|
16
|
+
params: Array[Symbol]?,
|
17
|
+
super_class: Definition::Ancestor::t?,
|
18
|
+
self_types: Array[Definition::Ancestor::Instance]?,
|
19
|
+
included_modules: Array[Definition::Ancestor::Instance]?,
|
20
|
+
included_interfaces: Array[Definition::Ancestor::Instance]?,
|
21
|
+
prepended_modules: Array[Definition::Ancestor::Instance]?,
|
22
|
+
extended_modules: Array[Definition::Ancestor::Instance]?,
|
23
|
+
extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void
|
24
|
+
|
25
|
+
def each_ancestor: { (Definition::Ancestor::t) -> void } -> void
|
26
|
+
| -> Enumerator[Definition::Ancestor::t, void]
|
27
|
+
|
28
|
+
def self.class_instance: (type_name: TypeName, params: Array[Symbol], super_class: Definition::Ancestor::t?) -> instance
|
29
|
+
|
30
|
+
def self.singleton: (type_name: TypeName, super_class: Definition::Ancestor::t?) -> instance
|
31
|
+
|
32
|
+
def self.module_instance: (type_name: TypeName, params: Array[Symbol]) -> instance
|
33
|
+
|
34
|
+
def self.interface: (type_name: TypeName, params: Array[Symbol]) -> instance
|
35
|
+
|
36
|
+
def each_included_module: () { (Definition::Ancestor::Instance) -> void } -> void
|
37
|
+
| () -> Enumerator[Definition::Ancestor::Instance, void]
|
38
|
+
|
39
|
+
def each_included_interface: () { (Definition::Ancestor::Instance) -> void } -> void
|
40
|
+
| () -> Enumerator[Definition::Ancestor::Instance, void]
|
41
|
+
|
42
|
+
def each_prepended_module: () { (Definition::Ancestor::Instance) -> void } -> void
|
43
|
+
| () -> Enumerator[Definition::Ancestor::Instance, void]
|
44
|
+
|
45
|
+
def each_extended_module: () { (Definition::Ancestor::Instance) -> void } -> void
|
46
|
+
| () -> Enumerator[Definition::Ancestor::Instance, void]
|
47
|
+
|
48
|
+
def each_extended_interface: () { (Definition::Ancestor::Instance) -> void } -> void
|
49
|
+
| () -> Enumerator[Definition::Ancestor::Instance, void]
|
50
|
+
|
51
|
+
def each_self_type: () { (Definition::Ancestor::Instance) -> void } -> void
|
52
|
+
| () -> Enumerator[Definition::Ancestor::Instance, void]
|
53
|
+
end
|
54
|
+
|
55
|
+
attr_reader env: Environment
|
56
|
+
|
57
|
+
attr_reader one_instance_ancestors_cache: Hash[TypeName, OneAncestors]
|
58
|
+
attr_reader instance_ancestors_cache: Hash[TypeName, Definition::InstanceAncestors]
|
59
|
+
|
60
|
+
attr_reader one_singleton_ancestors_cache: Hash[TypeName, OneAncestors]
|
61
|
+
attr_reader singleton_ancestors_cache: Hash[TypeName, Definition::SingletonAncestors]
|
62
|
+
|
63
|
+
attr_reader one_interface_ancestors_cache: Hash[TypeName, OneAncestors]
|
64
|
+
attr_reader interface_ancestors_cache: Hash[TypeName, Definition::InstanceAncestors]
|
65
|
+
|
66
|
+
def initialize: (env: Environment) -> void
|
67
|
+
|
68
|
+
def validate_super_class!: (TypeName, Environment::ClassEntry) -> void
|
69
|
+
|
70
|
+
def one_instance_ancestors: (TypeName) -> OneAncestors
|
71
|
+
|
72
|
+
def one_singleton_ancestors: (TypeName) -> OneAncestors
|
73
|
+
|
74
|
+
def one_interface_ancestors: (TypeName) -> OneAncestors
|
75
|
+
|
76
|
+
def instance_ancestors: (TypeName, ?building_ancestors: Array[Definition::Ancestor::t]) -> Definition::InstanceAncestors
|
77
|
+
|
78
|
+
def singleton_ancestors: (TypeName, ?building_ancestors: Array[Definition::Ancestor::t]) -> Definition::SingletonAncestors
|
79
|
+
|
80
|
+
def interface_ancestors: (TypeName, ?building_ancestors: Array[Definition::Ancestor::t]) -> Definition::InstanceAncestors
|
81
|
+
|
82
|
+
def mixin_ancestors: (Environment::ClassEntry | Environment::ModuleEntry,
|
83
|
+
included_modules: Array[Definition::Ancestor::Instance]?,
|
84
|
+
included_interfaces:Array[Definition::Ancestor::Instance]?,
|
85
|
+
prepended_modules: Array[Definition::Ancestor::Instance]?,
|
86
|
+
extended_modules: Array[Definition::Ancestor::Instance]?,
|
87
|
+
extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void
|
88
|
+
|
89
|
+
def mixin_ancestors0: (AST::Declarations::Class | AST::Declarations::Module | AST::Declarations::Interface,
|
90
|
+
align_params: Substitution?,
|
91
|
+
included_modules: Array[Definition::Ancestor::Instance]?,
|
92
|
+
included_interfaces:Array[Definition::Ancestor::Instance]?,
|
93
|
+
prepended_modules: Array[Definition::Ancestor::Instance]?,
|
94
|
+
extended_modules: Array[Definition::Ancestor::Instance]?,
|
95
|
+
extended_interfaces: Array[Definition::Ancestor::Instance]?) -> void
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
data/sig/declarations.rbs
CHANGED
@@ -73,8 +73,9 @@ module RBS
|
|
73
73
|
class Super
|
74
74
|
attr_reader name: TypeName
|
75
75
|
attr_reader args: Array[Types::t]
|
76
|
+
attr_reader location: Location?
|
76
77
|
|
77
|
-
def initialize: (name: TypeName, args: Array[Types::t]) -> void
|
78
|
+
def initialize: (name: TypeName, args: Array[Types::t], location: Location?) -> void
|
78
79
|
|
79
80
|
include _HashEqual
|
80
81
|
include _ToJson
|
@@ -130,21 +131,6 @@ module RBS
|
|
130
131
|
include _ToJson
|
131
132
|
end
|
132
133
|
|
133
|
-
class Extension < Base
|
134
|
-
attr_reader name: TypeName
|
135
|
-
attr_reader type_params: ModuleTypeParams
|
136
|
-
attr_reader extension_name: Symbol
|
137
|
-
attr_reader members: Array[Members::t]
|
138
|
-
attr_reader annotations: Array[Annotation]
|
139
|
-
attr_reader location: Location?
|
140
|
-
attr_reader comment: Comment?
|
141
|
-
|
142
|
-
def initialize: (name: TypeName, type_params: ModuleTypeParams, extension_name: Symbol, members: Array[Members::t], annotations: Array[Annotation], location: Location?, comment: Comment?) -> void
|
143
|
-
|
144
|
-
include _HashEqual
|
145
|
-
include _ToJson
|
146
|
-
end
|
147
|
-
|
148
134
|
class Interface
|
149
135
|
type member = Members::t
|
150
136
|
|
@@ -157,6 +143,8 @@ module RBS
|
|
157
143
|
|
158
144
|
def initialize: (name: TypeName, type_params: ModuleTypeParams, members: Array[member], annotations: Array[Annotation], location: Location?, comment: Comment?) -> void
|
159
145
|
|
146
|
+
include MixinHelper
|
147
|
+
|
160
148
|
include _HashEqual
|
161
149
|
include _ToJson
|
162
150
|
end
|