steep 0.33.0 → 0.38.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 +4 -4
- data/CHANGELOG.md +28 -0
- data/lib/steep.rb +9 -0
- data/lib/steep/annotation_parser.rb +1 -1
- data/lib/steep/ast/types/factory.rb +167 -102
- data/lib/steep/ast/types/logic.rb +20 -1
- data/lib/steep/ast/types/proc.rb +32 -20
- data/lib/steep/cli.rb +15 -2
- data/lib/steep/drivers/print_project.rb +11 -0
- data/lib/steep/drivers/stats.rb +85 -0
- data/lib/steep/drivers/vendor.rb +1 -20
- data/lib/steep/errors.rb +38 -15
- data/lib/steep/index/rbs_index.rb +334 -0
- data/lib/steep/index/signature_symbol_provider.rb +154 -0
- data/lib/steep/index/source_index.rb +100 -0
- data/lib/steep/interface/block.rb +79 -0
- data/lib/steep/interface/function.rb +770 -0
- data/lib/steep/interface/method_type.rb +41 -832
- data/lib/steep/method_name.rb +28 -0
- data/lib/steep/project/completion_provider.rb +24 -15
- data/lib/steep/project/dsl.rb +13 -17
- data/lib/steep/project/options.rb +4 -4
- data/lib/steep/project/source_file.rb +2 -1
- data/lib/steep/project/target.rb +19 -10
- data/lib/steep/server/interaction_worker.rb +1 -1
- data/lib/steep/server/master.rb +5 -1
- data/lib/steep/server/signature_worker.rb +63 -6
- data/lib/steep/subtyping/check.rb +70 -32
- data/lib/steep/subtyping/variable_occurrence.rb +4 -2
- data/lib/steep/subtyping/variable_variance.rb +2 -2
- data/lib/steep/type_construction.rb +780 -495
- data/lib/steep/type_inference/block_params.rb +1 -1
- data/lib/steep/type_inference/constant_env.rb +5 -1
- data/lib/steep/type_inference/context.rb +7 -3
- data/lib/steep/type_inference/local_variable_type_env.rb +10 -1
- data/lib/steep/type_inference/logic_type_interpreter.rb +3 -0
- data/lib/steep/type_inference/method_call.rb +116 -0
- data/lib/steep/typing.rb +46 -10
- data/lib/steep/version.rb +1 -1
- data/smoke/regression/range.rb +5 -0
- data/smoke/tsort/Steepfile +6 -0
- data/smoke/tsort/a.rb +15 -0
- data/steep.gemspec +1 -1
- metadata +17 -6
@@ -18,7 +18,7 @@ module Steep
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def ==(other)
|
21
|
-
other.class ==self.class
|
21
|
+
other.class == self.class
|
22
22
|
end
|
23
23
|
|
24
24
|
alias eql? ==
|
@@ -57,6 +57,25 @@ module Steep
|
|
57
57
|
@location = location
|
58
58
|
end
|
59
59
|
end
|
60
|
+
|
61
|
+
class Env < Base
|
62
|
+
attr_reader :truthy, :falsy
|
63
|
+
|
64
|
+
def initialize(truthy:, falsy:, location: nil)
|
65
|
+
@truthy = truthy
|
66
|
+
@falsy = falsy
|
67
|
+
end
|
68
|
+
|
69
|
+
def ==(other)
|
70
|
+
other.is_a?(Env) && other.truthy == truthy && other.falsy == falsy
|
71
|
+
end
|
72
|
+
|
73
|
+
alias eql? ==
|
74
|
+
|
75
|
+
def hash
|
76
|
+
self.class.hash ^ truthy.hash ^ falsy.hash
|
77
|
+
end
|
78
|
+
end
|
60
79
|
end
|
61
80
|
end
|
62
81
|
end
|
data/lib/steep/ast/types/proc.rb
CHANGED
@@ -3,68 +3,76 @@ module Steep
|
|
3
3
|
module Types
|
4
4
|
class Proc
|
5
5
|
attr_reader :location
|
6
|
-
attr_reader :
|
7
|
-
attr_reader :
|
6
|
+
attr_reader :type
|
7
|
+
attr_reader :block
|
8
8
|
|
9
|
-
def initialize(
|
9
|
+
def initialize(type:, block:, location: type.location)
|
10
|
+
@type = type
|
11
|
+
@block = block
|
10
12
|
@location = location
|
11
|
-
@params = params
|
12
|
-
@return_type = return_type
|
13
13
|
end
|
14
14
|
|
15
15
|
def ==(other)
|
16
|
-
other.is_a?(self.class) &&
|
17
|
-
other.params == params &&
|
18
|
-
other.return_type == return_type
|
16
|
+
other.is_a?(self.class) && other.type == type && other.block == block
|
19
17
|
end
|
20
18
|
|
21
19
|
def hash
|
22
|
-
self.class.hash
|
20
|
+
self.class.hash ^ type.hash ^ block.hash
|
23
21
|
end
|
24
22
|
|
25
23
|
alias eql? ==
|
26
24
|
|
27
25
|
def subst(s)
|
28
26
|
self.class.new(
|
29
|
-
|
30
|
-
|
27
|
+
type: type.subst(s),
|
28
|
+
block: block&.subst(s),
|
31
29
|
location: location
|
32
30
|
)
|
33
31
|
end
|
34
32
|
|
35
33
|
def to_s
|
36
|
-
|
34
|
+
if block
|
35
|
+
"^#{type.params} #{block} -> #{type.return_type}"
|
36
|
+
else
|
37
|
+
"^#{type.params} -> #{type.return_type}"
|
38
|
+
end
|
37
39
|
end
|
38
40
|
|
39
41
|
def free_variables()
|
40
|
-
@fvs ||= Set.
|
41
|
-
|
42
|
-
|
42
|
+
@fvs ||= Set[].tap do |fvs|
|
43
|
+
fvs.merge(type.free_variables)
|
44
|
+
fvs.merge(block.free_variables) if block
|
43
45
|
end
|
44
46
|
end
|
45
47
|
|
46
48
|
def level
|
47
|
-
children = params.each_type.to_a + [return_type]
|
49
|
+
children = type.params.each_type.to_a + [type.return_type]
|
50
|
+
if block
|
51
|
+
children.push(*block.type.params.each_type.to_a)
|
52
|
+
children.push(block.type.return_type)
|
53
|
+
end
|
48
54
|
[0] + level_of_children(children)
|
49
55
|
end
|
50
56
|
|
51
57
|
def closed?
|
52
|
-
|
58
|
+
type.closed? && (block.nil? || block.closed?)
|
53
59
|
end
|
54
60
|
|
55
61
|
def with_location(new_location)
|
56
|
-
self.class.new(location: new_location,
|
62
|
+
self.class.new(location: new_location, block: block, type: type)
|
57
63
|
end
|
58
64
|
|
59
65
|
def map_type(&block)
|
60
66
|
self.class.new(
|
61
|
-
|
62
|
-
|
67
|
+
type: type.map_type(&block),
|
68
|
+
block: self.block&.map_type(&block),
|
63
69
|
location: location
|
64
70
|
)
|
65
71
|
end
|
66
72
|
|
67
73
|
def one_arg?
|
74
|
+
params = type.params
|
75
|
+
|
68
76
|
params.required.size == 1 &&
|
69
77
|
params.optional.empty? &&
|
70
78
|
!params.rest &&
|
@@ -78,6 +86,10 @@ module Steep
|
|
78
86
|
args: [],
|
79
87
|
location: location)
|
80
88
|
end
|
89
|
+
|
90
|
+
def block_required?
|
91
|
+
block && !block.optional?
|
92
|
+
end
|
81
93
|
end
|
82
94
|
end
|
83
95
|
end
|
data/lib/steep/cli.rb
CHANGED
@@ -16,7 +16,7 @@ module Steep
|
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.available_commands
|
19
|
-
[:init, :check, :validate, :annotations, :version, :project, :watch, :langserver, :
|
19
|
+
[:init, :check, :validate, :annotations, :version, :project, :watch, :langserver, :stats]
|
20
20
|
end
|
21
21
|
|
22
22
|
def process_global_options
|
@@ -34,7 +34,7 @@ module Steep
|
|
34
34
|
|
35
35
|
def setup_command
|
36
36
|
@command = argv.shift&.to_sym
|
37
|
-
if CLI.available_commands.include?(@command) || @command == :worker
|
37
|
+
if CLI.available_commands.include?(@command) || @command == :worker || @command == :vendor
|
38
38
|
true
|
39
39
|
else
|
40
40
|
stderr.puts "Unknown command: #{command}"
|
@@ -91,6 +91,19 @@ module Steep
|
|
91
91
|
end.run
|
92
92
|
end
|
93
93
|
|
94
|
+
def process_stats
|
95
|
+
Drivers::Stats.new(stdout: stdout, stderr: stderr).tap do |check|
|
96
|
+
OptionParser.new do |opts|
|
97
|
+
opts.banner = "Usage: steep stats [options] [sources]"
|
98
|
+
|
99
|
+
opts.on("--steepfile=PATH") {|path| check.steepfile = Pathname(path) }
|
100
|
+
handle_logging_options opts
|
101
|
+
end.parse!(argv)
|
102
|
+
|
103
|
+
check.command_line_patterns.push *argv
|
104
|
+
end.run
|
105
|
+
end
|
106
|
+
|
94
107
|
def process_validate
|
95
108
|
Drivers::Validate.new(stdout: stdout, stderr: stderr).tap do |command|
|
96
109
|
OptionParser.new do |opts|
|
@@ -47,6 +47,17 @@ module Steep
|
|
47
47
|
target.options.libraries.each do |lib|
|
48
48
|
stdout.puts " - #{lib}"
|
49
49
|
end
|
50
|
+
stdout.puts " library dirs:"
|
51
|
+
Project::Target.construct_env_loader(options: target.options).tap do |loader|
|
52
|
+
loader.each_dir do |lib, path|
|
53
|
+
case lib
|
54
|
+
when :core
|
55
|
+
stdout.puts " - core: #{path}"
|
56
|
+
else
|
57
|
+
stdout.puts " - #{lib.name}: #{path}"
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
50
61
|
end
|
51
62
|
|
52
63
|
0
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require "csv"
|
2
|
+
|
3
|
+
module Steep
|
4
|
+
module Drivers
|
5
|
+
class Stats
|
6
|
+
attr_reader :stdout
|
7
|
+
attr_reader :stderr
|
8
|
+
attr_reader :command_line_patterns
|
9
|
+
|
10
|
+
include Utils::DriverHelper
|
11
|
+
|
12
|
+
def initialize(stdout:, stderr:)
|
13
|
+
@stdout = stdout
|
14
|
+
@stderr = stderr
|
15
|
+
@command_line_patterns = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def run
|
19
|
+
project = load_config()
|
20
|
+
|
21
|
+
loader = Project::FileLoader.new(project: project)
|
22
|
+
loader.load_sources(command_line_patterns)
|
23
|
+
loader.load_signatures()
|
24
|
+
|
25
|
+
type_check(project)
|
26
|
+
|
27
|
+
stdout.puts(
|
28
|
+
CSV.generate do |csv|
|
29
|
+
csv << ["Target", "File", "Status", "Typed calls", "Untyped calls", "All calls", "Typed %"]
|
30
|
+
|
31
|
+
project.targets.each do |target|
|
32
|
+
case (status = target.status)
|
33
|
+
when Project::Target::TypeCheckStatus
|
34
|
+
status.type_check_sources.each do |source_file|
|
35
|
+
case source_file.status
|
36
|
+
when Project::SourceFile::TypeCheckStatus
|
37
|
+
typing = source_file.status.typing
|
38
|
+
|
39
|
+
typed = 0
|
40
|
+
untyped = 0
|
41
|
+
total = 0
|
42
|
+
typing.method_calls.each_value do |call|
|
43
|
+
case call
|
44
|
+
when TypeInference::MethodCall::Typed
|
45
|
+
typed += 1
|
46
|
+
when TypeInference::MethodCall::Untyped
|
47
|
+
untyped += 1
|
48
|
+
end
|
49
|
+
|
50
|
+
total += 1
|
51
|
+
end
|
52
|
+
|
53
|
+
csv << format_stats(target, source_file.path, "success", typed, untyped, total)
|
54
|
+
when Project::SourceFile::TypeCheckErrorStatus
|
55
|
+
csv << format_stats(target, source_file.path, "error", 0, 0, 0)
|
56
|
+
else
|
57
|
+
csv << format_stats(target, source_file.path, "unknown (#{source_file.status.class.to_s.split(/::/).last})", 0, 0, 0)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
)
|
64
|
+
|
65
|
+
0
|
66
|
+
end
|
67
|
+
|
68
|
+
def format_stats(target, path, status, typed, untyped, total)
|
69
|
+
[
|
70
|
+
target.name,
|
71
|
+
path.to_s,
|
72
|
+
status,
|
73
|
+
typed,
|
74
|
+
untyped,
|
75
|
+
total,
|
76
|
+
if total.nonzero?
|
77
|
+
format("%.2f", (typed.to_f/total)*100)
|
78
|
+
else
|
79
|
+
0
|
80
|
+
end
|
81
|
+
]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/steep/drivers/vendor.rb
CHANGED
@@ -18,26 +18,7 @@ module Steep
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def run
|
21
|
-
stdout.puts "
|
22
|
-
|
23
|
-
vendorer = RBS::Vendorer.new(vendor_dir: vendor_dir)
|
24
|
-
|
25
|
-
if clean_before
|
26
|
-
stdout.puts " Cleaning directory..."
|
27
|
-
vendorer.clean!
|
28
|
-
end
|
29
|
-
|
30
|
-
stdout.puts " Vendoring standard libraries..."
|
31
|
-
vendorer.stdlib!
|
32
|
-
|
33
|
-
if defined?(Bundler)
|
34
|
-
Bundler.locked_gems.specs.each do |spec|
|
35
|
-
if RBS::EnvironmentLoader.gem_sig_path(spec.name, spec.version.to_s).directory?
|
36
|
-
stdout.puts " Vendoring rubygem: #{spec.full_name}..."
|
37
|
-
vendorer.gem! spec.name, spec.version.to_s
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
21
|
+
stdout.puts "`steep vendor` is deprecated. Use `rbs vendor` command directly"
|
41
22
|
|
42
23
|
0
|
43
24
|
end
|
data/lib/steep/errors.rb
CHANGED
@@ -101,20 +101,6 @@ module Steep
|
|
101
101
|
end
|
102
102
|
end
|
103
103
|
|
104
|
-
class IncompatibleBlockParameters < Base
|
105
|
-
attr_reader :node
|
106
|
-
attr_reader :method_type
|
107
|
-
|
108
|
-
def initialize(node:, method_type:)
|
109
|
-
super(node: node)
|
110
|
-
@method_type = method_type
|
111
|
-
end
|
112
|
-
|
113
|
-
def to_s
|
114
|
-
"#{location_to_str}: IncompatibleBlockParameters: method_type=#{method_type}"
|
115
|
-
end
|
116
|
-
end
|
117
|
-
|
118
104
|
class BlockParameterTypeMismatch < Base
|
119
105
|
attr_reader :expected
|
120
106
|
attr_reader :actual
|
@@ -186,7 +172,7 @@ module Steep
|
|
186
172
|
end
|
187
173
|
|
188
174
|
def to_s
|
189
|
-
"#{location_to_str}: RequiredBlockMissing: method_type=#{method_type.
|
175
|
+
"#{location_to_str}: RequiredBlockMissing: method_type=#{method_type.to_s}"
|
190
176
|
end
|
191
177
|
end
|
192
178
|
|
@@ -209,6 +195,25 @@ module Steep
|
|
209
195
|
end
|
210
196
|
end
|
211
197
|
|
198
|
+
class BlockBodyTypeMismatch < Base
|
199
|
+
attr_reader :expected
|
200
|
+
attr_reader :actual
|
201
|
+
attr_reader :result
|
202
|
+
|
203
|
+
include ResultPrinter
|
204
|
+
|
205
|
+
def initialize(node:, expected:, actual:, result:)
|
206
|
+
super(node: node)
|
207
|
+
@expected = expected
|
208
|
+
@actual = actual
|
209
|
+
@result = result
|
210
|
+
end
|
211
|
+
|
212
|
+
def to_s
|
213
|
+
"#{location_to_str}: BlockBodyTypeMismatch: expected=#{expected}, actual=#{actual}"
|
214
|
+
end
|
215
|
+
end
|
216
|
+
|
212
217
|
class BreakTypeMismatch < Base
|
213
218
|
attr_reader :expected
|
214
219
|
attr_reader :actual
|
@@ -557,5 +562,23 @@ module Steep
|
|
557
562
|
"#{location_to_str}: UnsupportedSyntax: #{msg}"
|
558
563
|
end
|
559
564
|
end
|
565
|
+
|
566
|
+
class UnexpectedError < Base
|
567
|
+
attr_reader :message
|
568
|
+
attr_reader :error
|
569
|
+
|
570
|
+
def initialize(node:, error:)
|
571
|
+
super(node: node)
|
572
|
+
@error = error
|
573
|
+
@message = error.message
|
574
|
+
end
|
575
|
+
|
576
|
+
def to_s
|
577
|
+
<<-MESSAGE
|
578
|
+
#{location_to_str}: UnexpectedError: #{error.class}
|
579
|
+
>> #{message}
|
580
|
+
MESSAGE
|
581
|
+
end
|
582
|
+
end
|
560
583
|
end
|
561
584
|
end
|
@@ -0,0 +1,334 @@
|
|
1
|
+
module Steep
|
2
|
+
module Index
|
3
|
+
class RBSIndex
|
4
|
+
class TypeEntry
|
5
|
+
attr_reader :type_name
|
6
|
+
attr_reader :declarations
|
7
|
+
attr_reader :references
|
8
|
+
|
9
|
+
def initialize(type_name:)
|
10
|
+
@type_name = type_name
|
11
|
+
@declarations = Set[]
|
12
|
+
@references = Set[]
|
13
|
+
end
|
14
|
+
|
15
|
+
def add_declaration(decl)
|
16
|
+
case decl
|
17
|
+
when RBS::AST::Declarations::Class, RBS::AST::Declarations::Module
|
18
|
+
declarations << decl
|
19
|
+
when RBS::AST::Declarations::Interface
|
20
|
+
declarations << decl
|
21
|
+
when RBS::AST::Declarations::Alias
|
22
|
+
declarations << decl
|
23
|
+
else
|
24
|
+
raise "Unexpected type declaration: #{decl}"
|
25
|
+
end
|
26
|
+
|
27
|
+
self
|
28
|
+
end
|
29
|
+
|
30
|
+
def add_reference(ref)
|
31
|
+
case ref
|
32
|
+
when RBS::AST::Members::MethodDefinition
|
33
|
+
references << ref
|
34
|
+
when RBS::AST::Members::AttrAccessor, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter
|
35
|
+
references << ref
|
36
|
+
when RBS::AST::Members::InstanceVariable, RBS::AST::Members::ClassInstanceVariable, RBS::AST::Members::ClassVariable
|
37
|
+
references << ref
|
38
|
+
when RBS::AST::Members::Include, RBS::AST::Members::Extend
|
39
|
+
references << ref
|
40
|
+
when RBS::AST::Declarations::Module, RBS::AST::Declarations::Class
|
41
|
+
references << ref
|
42
|
+
when RBS::AST::Declarations::Constant, RBS::AST::Declarations::Global
|
43
|
+
references << ref
|
44
|
+
when RBS::AST::Declarations::Alias
|
45
|
+
references << ref
|
46
|
+
else
|
47
|
+
raise "Unexpected type reference: #{ref}"
|
48
|
+
end
|
49
|
+
|
50
|
+
self
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
class MethodEntry
|
55
|
+
attr_reader :method_name
|
56
|
+
attr_reader :declarations
|
57
|
+
attr_reader :references
|
58
|
+
|
59
|
+
def initialize(method_name:)
|
60
|
+
@method_name = method_name
|
61
|
+
@declarations = Set[]
|
62
|
+
@references = Set[]
|
63
|
+
end
|
64
|
+
|
65
|
+
def add_declaration(decl)
|
66
|
+
case decl
|
67
|
+
when RBS::AST::Members::MethodDefinition,
|
68
|
+
RBS::AST::Members::Alias,
|
69
|
+
RBS::AST::Members::AttrWriter,
|
70
|
+
RBS::AST::Members::AttrReader,
|
71
|
+
RBS::AST::Members::AttrAccessor
|
72
|
+
declarations << decl
|
73
|
+
else
|
74
|
+
raise "Unexpected method declaration: #{decl}"
|
75
|
+
end
|
76
|
+
|
77
|
+
self
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
class ConstantEntry
|
82
|
+
attr_reader :const_name
|
83
|
+
attr_reader :declarations
|
84
|
+
|
85
|
+
def initialize(const_name:)
|
86
|
+
@const_name = const_name
|
87
|
+
@declarations = Set[]
|
88
|
+
end
|
89
|
+
|
90
|
+
def add_declaration(decl)
|
91
|
+
case decl
|
92
|
+
when RBS::AST::Declarations::Constant
|
93
|
+
declarations << decl
|
94
|
+
else
|
95
|
+
raise
|
96
|
+
end
|
97
|
+
|
98
|
+
self
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
class GlobalEntry
|
103
|
+
attr_reader :global_name
|
104
|
+
attr_reader :declarations
|
105
|
+
|
106
|
+
def initialize(global_name:)
|
107
|
+
@global_name = global_name
|
108
|
+
@declarations = Set[]
|
109
|
+
end
|
110
|
+
|
111
|
+
def add_declaration(decl)
|
112
|
+
case decl
|
113
|
+
when RBS::AST::Declarations::Global
|
114
|
+
declarations << decl
|
115
|
+
else
|
116
|
+
raise
|
117
|
+
end
|
118
|
+
|
119
|
+
self
|
120
|
+
end
|
121
|
+
end
|
122
|
+
|
123
|
+
attr_reader :type_index
|
124
|
+
attr_reader :method_index
|
125
|
+
attr_reader :const_index
|
126
|
+
attr_reader :global_index
|
127
|
+
|
128
|
+
def initialize()
|
129
|
+
@type_index = {}
|
130
|
+
@method_index = {}
|
131
|
+
@const_index = {}
|
132
|
+
@global_index = {}
|
133
|
+
end
|
134
|
+
|
135
|
+
def entry(type_name: nil, method_name: nil, const_name: nil, global_name: nil)
|
136
|
+
case
|
137
|
+
when type_name
|
138
|
+
type_index[type_name] ||= TypeEntry.new(type_name: type_name)
|
139
|
+
when method_name
|
140
|
+
method_index[method_name] ||= MethodEntry.new(method_name: method_name)
|
141
|
+
when const_name
|
142
|
+
const_index[const_name] ||= ConstantEntry.new(const_name: const_name)
|
143
|
+
when global_name
|
144
|
+
global_index[global_name] ||= GlobalEntry.new(global_name: global_name)
|
145
|
+
else
|
146
|
+
raise
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def each_entry(&block)
|
151
|
+
if block_given?
|
152
|
+
type_index.each_value(&block)
|
153
|
+
method_index.each_value(&block)
|
154
|
+
const_index.each_value(&block)
|
155
|
+
global_index.each_value(&block)
|
156
|
+
else
|
157
|
+
enum_for(:each_entry)
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def add_type_declaration(type_name, declaration)
|
162
|
+
entry(type_name: type_name).add_declaration(declaration)
|
163
|
+
end
|
164
|
+
|
165
|
+
def add_method_declaration(method_name, member)
|
166
|
+
entry(method_name: method_name).add_declaration(member)
|
167
|
+
end
|
168
|
+
|
169
|
+
def add_constant_declaration(const_name, decl)
|
170
|
+
entry(const_name: const_name).add_declaration(decl)
|
171
|
+
end
|
172
|
+
|
173
|
+
def add_global_declaration(global_name, decl)
|
174
|
+
entry(global_name: global_name).add_declaration(decl)
|
175
|
+
end
|
176
|
+
|
177
|
+
def each_declaration(type_name: nil, method_name: nil, const_name: nil, global_name: nil, &block)
|
178
|
+
if block
|
179
|
+
entry = entry(type_name: type_name, method_name: method_name, const_name: const_name, global_name: global_name)
|
180
|
+
entry.declarations.each(&block)
|
181
|
+
else
|
182
|
+
enum_for(:each_declaration, type_name: type_name, method_name: method_name, const_name: const_name, global_name: global_name)
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
def add_type_reference(type_name, ref)
|
187
|
+
entry(type_name: type_name).add_reference(ref)
|
188
|
+
end
|
189
|
+
|
190
|
+
def each_reference(type_name: nil, &block)
|
191
|
+
if block
|
192
|
+
entry(type_name: type_name).references.each(&block)
|
193
|
+
else
|
194
|
+
enum_for(:each_reference, type_name: type_name)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
class Builder
|
199
|
+
attr_reader :index
|
200
|
+
|
201
|
+
def initialize(index:)
|
202
|
+
@index = index
|
203
|
+
end
|
204
|
+
|
205
|
+
def member(type_name, member)
|
206
|
+
case member
|
207
|
+
when RBS::AST::Members::MethodDefinition
|
208
|
+
member.types.each do |method_type|
|
209
|
+
method_type.each_type do |type|
|
210
|
+
type_reference type, from: member
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
if member.instance?
|
215
|
+
method_name = InstanceMethodName.new(type_name: type_name, method_name: member.name)
|
216
|
+
index.add_method_declaration(method_name, member)
|
217
|
+
end
|
218
|
+
|
219
|
+
if member.singleton?
|
220
|
+
method_name = SingletonMethodName.new(type_name: type_name, method_name: member.name)
|
221
|
+
index.add_method_declaration(method_name, member)
|
222
|
+
end
|
223
|
+
|
224
|
+
when RBS::AST::Members::AttrAccessor, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter
|
225
|
+
type_reference member.type, from: member
|
226
|
+
|
227
|
+
if member.is_a?(RBS::AST::Members::AttrReader) || member.is_a?(RBS::AST::Members::AttrAccessor)
|
228
|
+
method_name = case member.kind
|
229
|
+
when :instance
|
230
|
+
InstanceMethodName.new(type_name: type_name, method_name: member.name)
|
231
|
+
when :singleton
|
232
|
+
SingletonMethodName.new(type_name: type_name, method_name: member.name)
|
233
|
+
end
|
234
|
+
index.add_method_declaration(method_name, member)
|
235
|
+
end
|
236
|
+
|
237
|
+
if member.is_a?(RBS::AST::Members::AttrWriter) || member.is_a?(RBS::AST::Members::AttrAccessor)
|
238
|
+
method_name = case member.kind
|
239
|
+
when :instance
|
240
|
+
InstanceMethodName.new(type_name: type_name, method_name: "#{member.name}=".to_sym)
|
241
|
+
when :singleton
|
242
|
+
SingletonMethodName.new(type_name: type_name, method_name: "#{member.name}=".to_sym)
|
243
|
+
end
|
244
|
+
index.add_method_declaration(method_name, member)
|
245
|
+
end
|
246
|
+
|
247
|
+
when RBS::AST::Members::InstanceVariable, RBS::AST::Members::ClassVariable, RBS::AST::Members::ClassInstanceVariable
|
248
|
+
type_reference member.type, from: member
|
249
|
+
|
250
|
+
when RBS::AST::Members::Include, RBS::AST::Members::Extend
|
251
|
+
index.add_type_reference member.name, member
|
252
|
+
member.args.each do |type|
|
253
|
+
type_reference type, from: member
|
254
|
+
end
|
255
|
+
|
256
|
+
when RBS::AST::Members::Alias
|
257
|
+
if member.instance?
|
258
|
+
new_name = InstanceMethodName.new(type_name: type_name, method_name: member.new_name)
|
259
|
+
index.add_method_declaration(new_name, member)
|
260
|
+
end
|
261
|
+
|
262
|
+
if member.singleton?
|
263
|
+
new_name = SingletonMethodName.new(type_name: type_name, method_name: member.new_name)
|
264
|
+
index.add_method_declaration(new_name, member)
|
265
|
+
end
|
266
|
+
end
|
267
|
+
end
|
268
|
+
|
269
|
+
def type_reference(type, from:)
|
270
|
+
case type
|
271
|
+
when RBS::Types::ClassInstance, RBS::Types::ClassSingleton, RBS::Types::Alias, RBS::Types::Interface
|
272
|
+
index.add_type_reference(type.name, from)
|
273
|
+
end
|
274
|
+
|
275
|
+
type.each_type do |ty|
|
276
|
+
type_reference ty, from: from
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
def env(env)
|
281
|
+
env.class_decls.each do |name, decl|
|
282
|
+
decl.decls.each do |d|
|
283
|
+
index.add_type_declaration(name, d.decl)
|
284
|
+
|
285
|
+
case d.decl
|
286
|
+
when RBS::AST::Declarations::Class
|
287
|
+
if super_class = d.decl.super_class
|
288
|
+
index.add_type_reference(super_class.name, d.decl)
|
289
|
+
super_class.args.each do |type|
|
290
|
+
type_reference(type, from: d.decl)
|
291
|
+
end
|
292
|
+
end
|
293
|
+
when RBS::AST::Declarations::Module
|
294
|
+
d.decl.self_types.each do |self_type|
|
295
|
+
index.add_type_reference(self_type.name, d.decl)
|
296
|
+
self_type.args.each do |type|
|
297
|
+
type_reference(type, from: d.decl)
|
298
|
+
end
|
299
|
+
end
|
300
|
+
end
|
301
|
+
|
302
|
+
d.decl.members.each do |member|
|
303
|
+
member(name, member)
|
304
|
+
end
|
305
|
+
end
|
306
|
+
end
|
307
|
+
|
308
|
+
env.interface_decls.each do |name, decl|
|
309
|
+
index.add_type_declaration(name, decl.decl)
|
310
|
+
|
311
|
+
decl.decl.members.each do |member|
|
312
|
+
member(name, member)
|
313
|
+
end
|
314
|
+
end
|
315
|
+
|
316
|
+
env.alias_decls.each do |name, decl|
|
317
|
+
index.add_type_declaration(name, decl.decl)
|
318
|
+
type_reference decl.decl.type, from: decl.decl
|
319
|
+
end
|
320
|
+
|
321
|
+
env.constant_decls.each do |name, decl|
|
322
|
+
index.add_constant_declaration(name, decl.decl)
|
323
|
+
type_reference decl.decl.type, from: decl.decl
|
324
|
+
end
|
325
|
+
|
326
|
+
env.global_decls.each do |name, decl|
|
327
|
+
index.add_global_declaration(name, decl.decl)
|
328
|
+
type_reference decl.decl.type, from: decl.decl
|
329
|
+
end
|
330
|
+
end
|
331
|
+
end
|
332
|
+
end
|
333
|
+
end
|
334
|
+
end
|