rbs 0.2.0
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 +7 -0
- data/.github/workflows/ruby.yml +28 -0
- data/.gitignore +12 -0
- data/.rubocop.yml +15 -0
- data/BSDL +22 -0
- data/CHANGELOG.md +9 -0
- data/COPYING +56 -0
- data/Gemfile +6 -0
- data/README.md +93 -0
- data/Rakefile +142 -0
- data/bin/annotate-with-rdoc +157 -0
- data/bin/console +14 -0
- data/bin/query-rdoc +103 -0
- data/bin/setup +10 -0
- data/bin/sort +89 -0
- data/bin/test_runner.rb +16 -0
- data/docs/CONTRIBUTING.md +97 -0
- data/docs/sigs.md +148 -0
- data/docs/stdlib.md +152 -0
- data/docs/syntax.md +528 -0
- data/exe/rbs +7 -0
- data/lib/rbs.rb +64 -0
- data/lib/rbs/ast/annotation.rb +27 -0
- data/lib/rbs/ast/comment.rb +27 -0
- data/lib/rbs/ast/declarations.rb +395 -0
- data/lib/rbs/ast/members.rb +362 -0
- data/lib/rbs/buffer.rb +50 -0
- data/lib/rbs/builtin_names.rb +55 -0
- data/lib/rbs/cli.rb +558 -0
- data/lib/rbs/constant.rb +26 -0
- data/lib/rbs/constant_table.rb +150 -0
- data/lib/rbs/definition.rb +170 -0
- data/lib/rbs/definition_builder.rb +919 -0
- data/lib/rbs/environment.rb +281 -0
- data/lib/rbs/environment_loader.rb +136 -0
- data/lib/rbs/environment_walker.rb +124 -0
- data/lib/rbs/errors.rb +187 -0
- data/lib/rbs/location.rb +102 -0
- data/lib/rbs/method_type.rb +123 -0
- data/lib/rbs/namespace.rb +91 -0
- data/lib/rbs/parser.y +1344 -0
- data/lib/rbs/prototype/rb.rb +553 -0
- data/lib/rbs/prototype/rbi.rb +587 -0
- data/lib/rbs/prototype/runtime.rb +381 -0
- data/lib/rbs/substitution.rb +46 -0
- data/lib/rbs/test.rb +26 -0
- data/lib/rbs/test/errors.rb +61 -0
- data/lib/rbs/test/hook.rb +294 -0
- data/lib/rbs/test/setup.rb +58 -0
- data/lib/rbs/test/spy.rb +325 -0
- data/lib/rbs/test/test_helper.rb +183 -0
- data/lib/rbs/test/type_check.rb +254 -0
- data/lib/rbs/type_name.rb +70 -0
- data/lib/rbs/types.rb +936 -0
- data/lib/rbs/variance_calculator.rb +138 -0
- data/lib/rbs/vendorer.rb +47 -0
- data/lib/rbs/version.rb +3 -0
- data/lib/rbs/writer.rb +269 -0
- data/lib/ruby/signature.rb +7 -0
- data/rbs.gemspec +46 -0
- data/stdlib/abbrev/abbrev.rbs +60 -0
- data/stdlib/base64/base64.rbs +71 -0
- data/stdlib/benchmark/benchmark.rbs +372 -0
- data/stdlib/builtin/array.rbs +1997 -0
- data/stdlib/builtin/basic_object.rbs +280 -0
- data/stdlib/builtin/binding.rbs +177 -0
- data/stdlib/builtin/builtin.rbs +45 -0
- data/stdlib/builtin/class.rbs +145 -0
- data/stdlib/builtin/comparable.rbs +116 -0
- data/stdlib/builtin/complex.rbs +400 -0
- data/stdlib/builtin/constants.rbs +37 -0
- data/stdlib/builtin/data.rbs +5 -0
- data/stdlib/builtin/deprecated.rbs +2 -0
- data/stdlib/builtin/dir.rbs +413 -0
- data/stdlib/builtin/encoding.rbs +607 -0
- data/stdlib/builtin/enumerable.rbs +404 -0
- data/stdlib/builtin/enumerator.rbs +260 -0
- data/stdlib/builtin/errno.rbs +781 -0
- data/stdlib/builtin/errors.rbs +582 -0
- data/stdlib/builtin/exception.rbs +194 -0
- data/stdlib/builtin/false_class.rbs +40 -0
- data/stdlib/builtin/fiber.rbs +68 -0
- data/stdlib/builtin/fiber_error.rbs +12 -0
- data/stdlib/builtin/file.rbs +1076 -0
- data/stdlib/builtin/file_test.rbs +59 -0
- data/stdlib/builtin/float.rbs +696 -0
- data/stdlib/builtin/gc.rbs +243 -0
- data/stdlib/builtin/hash.rbs +1029 -0
- data/stdlib/builtin/integer.rbs +707 -0
- data/stdlib/builtin/io.rbs +683 -0
- data/stdlib/builtin/kernel.rbs +576 -0
- data/stdlib/builtin/marshal.rbs +161 -0
- data/stdlib/builtin/match_data.rbs +271 -0
- data/stdlib/builtin/math.rbs +369 -0
- data/stdlib/builtin/method.rbs +185 -0
- data/stdlib/builtin/module.rbs +1104 -0
- data/stdlib/builtin/nil_class.rbs +82 -0
- data/stdlib/builtin/numeric.rbs +409 -0
- data/stdlib/builtin/object.rbs +824 -0
- data/stdlib/builtin/proc.rbs +429 -0
- data/stdlib/builtin/process.rbs +1227 -0
- data/stdlib/builtin/random.rbs +267 -0
- data/stdlib/builtin/range.rbs +226 -0
- data/stdlib/builtin/rational.rbs +424 -0
- data/stdlib/builtin/rb_config.rbs +57 -0
- data/stdlib/builtin/regexp.rbs +1083 -0
- data/stdlib/builtin/ruby_vm.rbs +14 -0
- data/stdlib/builtin/signal.rbs +55 -0
- data/stdlib/builtin/string.rbs +1901 -0
- data/stdlib/builtin/string_io.rbs +284 -0
- data/stdlib/builtin/struct.rbs +40 -0
- data/stdlib/builtin/symbol.rbs +228 -0
- data/stdlib/builtin/thread.rbs +1108 -0
- data/stdlib/builtin/thread_group.rbs +23 -0
- data/stdlib/builtin/time.rbs +1047 -0
- data/stdlib/builtin/trace_point.rbs +290 -0
- data/stdlib/builtin/true_class.rbs +46 -0
- data/stdlib/builtin/unbound_method.rbs +153 -0
- data/stdlib/builtin/warning.rbs +17 -0
- data/stdlib/coverage/coverage.rbs +62 -0
- data/stdlib/csv/csv.rbs +773 -0
- data/stdlib/erb/erb.rbs +392 -0
- data/stdlib/find/find.rbs +40 -0
- data/stdlib/ipaddr/ipaddr.rbs +247 -0
- data/stdlib/json/json.rbs +335 -0
- data/stdlib/pathname/pathname.rbs +1093 -0
- data/stdlib/prime/integer-extension.rbs +23 -0
- data/stdlib/prime/prime.rbs +188 -0
- data/stdlib/securerandom/securerandom.rbs +9 -0
- data/stdlib/set/set.rbs +301 -0
- data/stdlib/tmpdir/tmpdir.rbs +53 -0
- metadata +292 -0
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class VarianceCalculator
|
|
3
|
+
class Result
|
|
4
|
+
attr_reader :result
|
|
5
|
+
|
|
6
|
+
def initialize(variables:)
|
|
7
|
+
@result = {}
|
|
8
|
+
variables.each do |x|
|
|
9
|
+
result[x] = :unused
|
|
10
|
+
end
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def covariant(x)
|
|
14
|
+
case result[x]
|
|
15
|
+
when :unused
|
|
16
|
+
result[x] = :covariant
|
|
17
|
+
when :contravariant
|
|
18
|
+
result[x] = :invariant
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def contravariant(x)
|
|
23
|
+
case result[x]
|
|
24
|
+
when :unused
|
|
25
|
+
result[x] = :contravariant
|
|
26
|
+
when :covariant
|
|
27
|
+
result[x] = :invariant
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def invariant(x)
|
|
32
|
+
result[x] = :invariant
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
def each(&block)
|
|
36
|
+
result.each(&block)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def include?(name)
|
|
40
|
+
result.key?(name)
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def compatible?(var, with_annotation:)
|
|
44
|
+
variance = result[var]
|
|
45
|
+
|
|
46
|
+
case
|
|
47
|
+
when variance == :unused
|
|
48
|
+
true
|
|
49
|
+
when with_annotation == :invariant
|
|
50
|
+
true
|
|
51
|
+
when variance == with_annotation
|
|
52
|
+
true
|
|
53
|
+
else
|
|
54
|
+
false
|
|
55
|
+
end
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
attr_reader :builder
|
|
60
|
+
|
|
61
|
+
def initialize(builder:)
|
|
62
|
+
@builder = builder
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
def env
|
|
66
|
+
builder.env
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def in_method_type(method_type:, variables:)
|
|
70
|
+
result = Result.new(variables: variables)
|
|
71
|
+
|
|
72
|
+
method_type.type.each_param do |param|
|
|
73
|
+
type(param.type, result: result, context: :contravariant)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
if method_type.block
|
|
77
|
+
method_type.block.type.each_param do |param|
|
|
78
|
+
type(param.type, result: result, context: :covariant)
|
|
79
|
+
end
|
|
80
|
+
type(method_type.block.type.return_type, result: result, context: :contravariant)
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
type(method_type.type.return_type, result: result, context: :covariant)
|
|
84
|
+
|
|
85
|
+
result
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
def in_inherit(name:, args:, variables:)
|
|
89
|
+
type = Types::ClassInstance.new(name: name, args: args, location: nil)
|
|
90
|
+
|
|
91
|
+
Result.new(variables: variables).tap do |result|
|
|
92
|
+
type(type, result: result, context: :covariant)
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def type(type, result:, context:)
|
|
97
|
+
case type
|
|
98
|
+
when Types::Variable
|
|
99
|
+
if result.include?(type.name)
|
|
100
|
+
case context
|
|
101
|
+
when :covariant
|
|
102
|
+
result.covariant(type.name)
|
|
103
|
+
when :contravariant
|
|
104
|
+
result.contravariant(type.name)
|
|
105
|
+
when :invariant
|
|
106
|
+
result.invariant(type.name)
|
|
107
|
+
end
|
|
108
|
+
end
|
|
109
|
+
when Types::ClassInstance, Types::Interface
|
|
110
|
+
decl = env.find_class(type.name)
|
|
111
|
+
type.args.each.with_index do |ty, i|
|
|
112
|
+
var = decl.type_params.params[i]
|
|
113
|
+
case var.variance
|
|
114
|
+
when :invariant
|
|
115
|
+
type(ty, result: result, context: :invariant)
|
|
116
|
+
when :covariant
|
|
117
|
+
type(ty, result: result, context: context)
|
|
118
|
+
when :contravariant
|
|
119
|
+
con = case context
|
|
120
|
+
when :invariant
|
|
121
|
+
:invariant
|
|
122
|
+
when :covariant
|
|
123
|
+
:contravariant
|
|
124
|
+
when :contravariant
|
|
125
|
+
:covariant
|
|
126
|
+
end
|
|
127
|
+
type(ty, result: result, context: con)
|
|
128
|
+
end
|
|
129
|
+
end
|
|
130
|
+
when Types::Tuple, Types::Record, Types::Union, Types::Intersection
|
|
131
|
+
# Covariant types
|
|
132
|
+
type.each_type do |ty|
|
|
133
|
+
type(ty, result: result, context: context)
|
|
134
|
+
end
|
|
135
|
+
end
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
end
|
data/lib/rbs/vendorer.rb
ADDED
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class Vendorer
|
|
3
|
+
attr_reader :vendor_dir
|
|
4
|
+
|
|
5
|
+
def initialize(vendor_dir:)
|
|
6
|
+
@vendor_dir = vendor_dir
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def ensure_dir
|
|
10
|
+
unless vendor_dir.directory?
|
|
11
|
+
vendor_dir.mkpath
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
yield
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
def clean!
|
|
18
|
+
ensure_dir do
|
|
19
|
+
RBS.logger.info "Cleaning vendor root: #{vendor_dir}..."
|
|
20
|
+
vendor_dir.rmtree
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def stdlib!()
|
|
25
|
+
ensure_dir do
|
|
26
|
+
RBS.logger.info "Vendoring stdlib: #{EnvironmentLoader::STDLIB_ROOT} => #{vendor_dir + "stdlib"}..."
|
|
27
|
+
FileUtils.copy_entry EnvironmentLoader::STDLIB_ROOT, vendor_dir + "stdlib"
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def gem!(name, version)
|
|
32
|
+
ensure_dir do
|
|
33
|
+
sig_path = EnvironmentLoader.gem_sig_path(name, version)
|
|
34
|
+
RBS.logger.debug "Checking gem signature path: name=#{name}, version=#{version}, path=#{sig_path}"
|
|
35
|
+
|
|
36
|
+
if sig_path&.directory?
|
|
37
|
+
gems_dir = vendor_dir + "gems"
|
|
38
|
+
gems_dir.mkpath unless gems_dir.directory?
|
|
39
|
+
|
|
40
|
+
gem_dir = gems_dir + name
|
|
41
|
+
RBS.logger.info "Vendoring gem(#{name}:#{version}): #{sig_path} => #{gem_dir}..."
|
|
42
|
+
FileUtils.copy_entry sig_path, gem_dir
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/rbs/version.rb
ADDED
data/lib/rbs/writer.rb
ADDED
|
@@ -0,0 +1,269 @@
|
|
|
1
|
+
module RBS
|
|
2
|
+
class Writer
|
|
3
|
+
attr_reader :out
|
|
4
|
+
|
|
5
|
+
def initialize(out:)
|
|
6
|
+
@out = out
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
def write_annotation(annotations, level:)
|
|
10
|
+
prefix = " " * level
|
|
11
|
+
|
|
12
|
+
annotations.each do |annotation|
|
|
13
|
+
string = annotation.string
|
|
14
|
+
case
|
|
15
|
+
when string !~ /\}/
|
|
16
|
+
out.puts "#{prefix}%a{#{string}}"
|
|
17
|
+
when string !~ /\)/
|
|
18
|
+
out.puts "#{prefix}%a(#{string})"
|
|
19
|
+
when string !~ /\]/
|
|
20
|
+
out.puts "#{prefix}%a[#{string}]"
|
|
21
|
+
when string !~ /\>/
|
|
22
|
+
out.puts "#{prefix}%a<#{string}>"
|
|
23
|
+
when string !~ /\|/
|
|
24
|
+
out.puts "#{prefix}%a|#{string}|"
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def write_comment(comment, level:)
|
|
30
|
+
if comment
|
|
31
|
+
prefix = " " * level
|
|
32
|
+
comment.string.lines.each do |line|
|
|
33
|
+
line = " #{line}" unless line.chomp.empty?
|
|
34
|
+
out.puts "#{prefix}##{line}"
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
def write(decls)
|
|
40
|
+
[nil, *decls].each_cons(2) do |prev, decl|
|
|
41
|
+
preserve_empty_line(prev, decl)
|
|
42
|
+
write_decl decl
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def write_decl(decl)
|
|
47
|
+
case decl
|
|
48
|
+
when AST::Declarations::Class
|
|
49
|
+
super_class = if decl.super_class
|
|
50
|
+
" < #{name_and_args(decl.super_class.name, decl.super_class.args)}"
|
|
51
|
+
end
|
|
52
|
+
write_comment decl.comment, level: 0
|
|
53
|
+
write_annotation decl.annotations, level: 0
|
|
54
|
+
out.puts "class #{name_and_params(decl.name, decl.type_params)}#{super_class}"
|
|
55
|
+
|
|
56
|
+
[nil, *decl.members].each_cons(2) do |prev, member|
|
|
57
|
+
preserve_empty_line prev, member
|
|
58
|
+
write_member member
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
out.puts "end"
|
|
62
|
+
|
|
63
|
+
when AST::Declarations::Module
|
|
64
|
+
self_type = if decl.self_type
|
|
65
|
+
" : #{decl.self_type}"
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
write_comment decl.comment, level: 0
|
|
69
|
+
write_annotation decl.annotations, level: 0
|
|
70
|
+
out.puts "module #{name_and_params(decl.name, decl.type_params)}#{self_type}"
|
|
71
|
+
decl.members.each.with_index do |member, index|
|
|
72
|
+
if index > 0
|
|
73
|
+
out.puts
|
|
74
|
+
end
|
|
75
|
+
write_member member
|
|
76
|
+
end
|
|
77
|
+
out.puts "end"
|
|
78
|
+
when AST::Declarations::Constant
|
|
79
|
+
write_comment decl.comment, level: 0
|
|
80
|
+
out.puts "#{decl.name}: #{decl.type}"
|
|
81
|
+
|
|
82
|
+
when AST::Declarations::Global
|
|
83
|
+
write_comment decl.comment, level: 0
|
|
84
|
+
out.puts "#{decl.name}: #{decl.type}"
|
|
85
|
+
|
|
86
|
+
when AST::Declarations::Alias
|
|
87
|
+
write_comment decl.comment, level: 0
|
|
88
|
+
write_annotation decl.annotations, level: 0
|
|
89
|
+
out.puts "type #{decl.name} = #{decl.type}"
|
|
90
|
+
|
|
91
|
+
when AST::Declarations::Interface
|
|
92
|
+
write_comment decl.comment, level: 0
|
|
93
|
+
write_annotation decl.annotations, level: 0
|
|
94
|
+
out.puts "interface #{name_and_params(decl.name, decl.type_params)}"
|
|
95
|
+
decl.members.each.with_index do |member, index|
|
|
96
|
+
if index > 0
|
|
97
|
+
out.puts
|
|
98
|
+
end
|
|
99
|
+
write_member member
|
|
100
|
+
end
|
|
101
|
+
out.puts "end"
|
|
102
|
+
|
|
103
|
+
when AST::Declarations::Extension
|
|
104
|
+
write_comment decl.comment, level: 0
|
|
105
|
+
write_annotation decl.annotations, level: 0
|
|
106
|
+
out.puts "extension #{name_and_args(decl.name, decl.type_params)} (#{decl.extension_name})"
|
|
107
|
+
decl.members.each.with_index do |member, index|
|
|
108
|
+
if index > 0
|
|
109
|
+
out.puts
|
|
110
|
+
end
|
|
111
|
+
write_member member
|
|
112
|
+
end
|
|
113
|
+
out.puts "end"
|
|
114
|
+
end
|
|
115
|
+
end
|
|
116
|
+
|
|
117
|
+
def name_and_params(name, params)
|
|
118
|
+
if params.empty?
|
|
119
|
+
"#{name}"
|
|
120
|
+
else
|
|
121
|
+
ps = params.each.map do |param|
|
|
122
|
+
s = ""
|
|
123
|
+
if param.skip_validation
|
|
124
|
+
s << "unchecked "
|
|
125
|
+
end
|
|
126
|
+
case param.variance
|
|
127
|
+
when :invariant
|
|
128
|
+
# nop
|
|
129
|
+
when :covariant
|
|
130
|
+
s << "out "
|
|
131
|
+
when :contravariant
|
|
132
|
+
s << "in "
|
|
133
|
+
end
|
|
134
|
+
s + param.name.to_s
|
|
135
|
+
end
|
|
136
|
+
|
|
137
|
+
"#{name}[#{ps.join(", ")}]"
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
def name_and_args(name, args)
|
|
142
|
+
if name && args
|
|
143
|
+
if args.empty?
|
|
144
|
+
"#{name}"
|
|
145
|
+
else
|
|
146
|
+
"#{name}[#{args.join(", ")}]"
|
|
147
|
+
end
|
|
148
|
+
end
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def write_member(member)
|
|
152
|
+
case member
|
|
153
|
+
when AST::Members::Include
|
|
154
|
+
write_comment member.comment, level: 2
|
|
155
|
+
write_annotation member.annotations, level: 2
|
|
156
|
+
out.puts " include #{name_and_args(member.name, member.args)}"
|
|
157
|
+
when AST::Members::Extend
|
|
158
|
+
write_comment member.comment, level: 2
|
|
159
|
+
write_annotation member.annotations, level: 2
|
|
160
|
+
out.puts " extend #{name_and_args(member.name, member.args)}"
|
|
161
|
+
when AST::Members::Prepend
|
|
162
|
+
write_comment member.comment, level: 2
|
|
163
|
+
write_annotation member.annotations, level: 2
|
|
164
|
+
out.puts " prepend #{name_and_args(member.name, member.args)}"
|
|
165
|
+
when AST::Members::AttrAccessor
|
|
166
|
+
write_comment member.comment, level: 2
|
|
167
|
+
write_annotation member.annotations, level: 2
|
|
168
|
+
out.puts " #{attribute(:accessor, member)}"
|
|
169
|
+
when AST::Members::AttrReader
|
|
170
|
+
write_comment member.comment, level: 2
|
|
171
|
+
write_annotation member.annotations, level: 2
|
|
172
|
+
out.puts " #{attribute(:reader, member)}"
|
|
173
|
+
when AST::Members::AttrWriter
|
|
174
|
+
write_comment member.comment, level: 2
|
|
175
|
+
write_annotation member.annotations, level: 2
|
|
176
|
+
out.puts " #{attribute(:writer, member)}"
|
|
177
|
+
when AST::Members::Public
|
|
178
|
+
out.puts " public"
|
|
179
|
+
when AST::Members::Private
|
|
180
|
+
out.puts " private"
|
|
181
|
+
when AST::Members::Alias
|
|
182
|
+
write_comment member.comment, level: 2
|
|
183
|
+
write_annotation member.annotations, level: 2
|
|
184
|
+
new_name = member.singleton? ? "self.#{member.new_name}" : member.new_name
|
|
185
|
+
old_name = member.singleton? ? "self.#{member.old_name}" : member.old_name
|
|
186
|
+
out.puts " alias #{new_name} #{old_name}"
|
|
187
|
+
when AST::Members::InstanceVariable
|
|
188
|
+
write_comment member.comment, level: 2
|
|
189
|
+
out.puts " #{member.name}: #{member.type}"
|
|
190
|
+
when AST::Members::ClassInstanceVariable
|
|
191
|
+
write_comment member.comment, level: 2
|
|
192
|
+
out.puts " self.#{member.name}: #{member.type}"
|
|
193
|
+
when AST::Members::ClassVariable
|
|
194
|
+
write_comment member.comment, level: 2
|
|
195
|
+
out.puts " #{member.name}: #{member.type}"
|
|
196
|
+
when AST::Members::MethodDefinition
|
|
197
|
+
write_comment member.comment, level: 2
|
|
198
|
+
write_annotation member.annotations, level: 2
|
|
199
|
+
write_def member
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
def method_name(name)
|
|
204
|
+
s = name.to_s
|
|
205
|
+
|
|
206
|
+
if /\A#{Parser::KEYWORDS_RE}\z/.match?(s)
|
|
207
|
+
"`#{s}`"
|
|
208
|
+
else
|
|
209
|
+
s
|
|
210
|
+
end
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
def write_def(member)
|
|
214
|
+
name = case member.kind
|
|
215
|
+
when :instance
|
|
216
|
+
"#{method_name(member.name)}"
|
|
217
|
+
when :singleton_instance
|
|
218
|
+
"self?.#{method_name(member.name)}"
|
|
219
|
+
when :singleton
|
|
220
|
+
"self.#{method_name(member.name)}"
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
attrs = member.attributes.empty? ? "" : member.attributes.join(" ") + " "
|
|
224
|
+
prefix = " #{attrs}def #{name}:"
|
|
225
|
+
padding = " " * (prefix.size-1)
|
|
226
|
+
|
|
227
|
+
out.print prefix
|
|
228
|
+
|
|
229
|
+
member.types.each.with_index do |type, index|
|
|
230
|
+
if index > 0
|
|
231
|
+
out.print padding
|
|
232
|
+
out.print "|"
|
|
233
|
+
end
|
|
234
|
+
out.puts " #{type}"
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
|
|
238
|
+
def attribute(kind, attr)
|
|
239
|
+
var = case attr.ivar_name
|
|
240
|
+
when nil
|
|
241
|
+
""
|
|
242
|
+
when false
|
|
243
|
+
"()"
|
|
244
|
+
else
|
|
245
|
+
"(#{attr.ivar_name})"
|
|
246
|
+
end
|
|
247
|
+
"attr_#{kind} #{attr.name}#{var}: #{attr.type}"
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
def preserve_empty_line(prev, decl)
|
|
251
|
+
return unless prev
|
|
252
|
+
|
|
253
|
+
decl = decl.comment if decl.respond_to?(:comment) && decl.comment
|
|
254
|
+
|
|
255
|
+
# When the signature is not constructed by the parser,
|
|
256
|
+
# it always inserts an empty line.
|
|
257
|
+
if !prev.location || !decl.location
|
|
258
|
+
out.puts
|
|
259
|
+
return
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
prev_end_line = prev.location.end_line
|
|
263
|
+
start_line = decl.location.start_line
|
|
264
|
+
if start_line - prev_end_line > 1
|
|
265
|
+
out.puts
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
end
|