steep 1.9.0.dev.2 → 1.9.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/CHANGELOG.md +82 -0
- data/README.md +9 -4
- data/Rakefile +1 -0
- data/Steepfile +11 -0
- data/bin/generate-diagnostics-docs.rb +112 -0
- data/lib/steep/ast/builtin.rb +1 -0
- data/lib/steep/ast/ignore.rb +1 -1
- data/lib/steep/ast/types/factory.rb +2 -0
- data/lib/steep/cli.rb +9 -2
- data/lib/steep/diagnostic/lsp_formatter.rb +8 -1
- data/lib/steep/diagnostic/ruby.rb +65 -3
- data/lib/steep/diagnostic/signature.rb +4 -4
- data/lib/steep/drivers/annotations.rb +1 -1
- data/lib/steep/drivers/check.rb +3 -3
- data/lib/steep/drivers/diagnostic_printer.rb +1 -1
- data/lib/steep/drivers/init.rb +6 -3
- data/lib/steep/expectations.rb +1 -1
- data/lib/steep/interface/builder.rb +7 -5
- data/lib/steep/interface/function.rb +13 -0
- data/lib/steep/interface/method_type.rb +5 -0
- data/lib/steep/interface/shape.rb +1 -1
- data/lib/steep/project/dsl.rb +11 -1
- data/lib/steep/project/target.rb +3 -1
- data/lib/steep/server/change_buffer.rb +1 -1
- data/lib/steep/server/interaction_worker.rb +5 -5
- data/lib/steep/server/master.rb +2 -17
- data/lib/steep/server/type_check_controller.rb +3 -3
- data/lib/steep/server/type_check_worker.rb +1 -1
- data/lib/steep/services/completion_provider.rb +4 -4
- data/lib/steep/services/goto_service.rb +3 -3
- data/lib/steep/services/hover_provider/rbs.rb +1 -1
- data/lib/steep/services/hover_provider/ruby.rb +6 -6
- data/lib/steep/services/signature_help_provider.rb +8 -8
- data/lib/steep/services/signature_service.rb +12 -8
- data/lib/steep/services/type_check_service.rb +9 -9
- data/lib/steep/signature/validator.rb +3 -3
- data/lib/steep/source.rb +4 -4
- data/lib/steep/subtyping/check.rb +3 -3
- data/lib/steep/subtyping/constraints.rb +4 -4
- data/lib/steep/type_construction.rb +84 -45
- data/lib/steep/type_inference/block_params.rb +3 -3
- data/lib/steep/type_inference/context.rb +1 -1
- data/lib/steep/type_inference/method_params.rb +1 -1
- data/lib/steep/type_inference/type_env.rb +3 -3
- data/lib/steep/version.rb +1 -1
- data/manual/annotations.md +37 -0
- data/manual/ignore.md +20 -0
- data/manual/ruby-diagnostics.md +1812 -0
- data/steep.gemspec +1 -1
- metadata +8 -5
@@ -1057,6 +1057,19 @@ module Steep
|
|
1057
1057
|
)
|
1058
1058
|
end
|
1059
1059
|
|
1060
|
+
def accept_one_arg?
|
1061
|
+
return false unless params
|
1062
|
+
return false unless params.keyword_params.requireds.empty?
|
1063
|
+
head = params.positional_params or return false
|
1064
|
+
|
1065
|
+
case head.head
|
1066
|
+
when Params::PositionalParams::Required
|
1067
|
+
!head.tail.is_a?(Params::PositionalParams::Required)
|
1068
|
+
else
|
1069
|
+
true
|
1070
|
+
end
|
1071
|
+
end
|
1072
|
+
|
1060
1073
|
def to_s
|
1061
1074
|
if params
|
1062
1075
|
"#{params} -> #{return_type}"
|
data/lib/steep/project/dsl.rb
CHANGED
@@ -119,6 +119,7 @@ module Steep
|
|
119
119
|
attr_reader :project
|
120
120
|
attr_reader :unreferenced
|
121
121
|
attr_reader :groups
|
122
|
+
attr_reader :implicitly_returns_nil
|
122
123
|
|
123
124
|
def initialize(name, project:)
|
124
125
|
@name = name
|
@@ -127,6 +128,7 @@ module Steep
|
|
127
128
|
@project = project
|
128
129
|
@collection_config_path = collection_config_path
|
129
130
|
@unreferenced = false
|
131
|
+
@implicitly_returns_nil = false
|
130
132
|
@groups = []
|
131
133
|
end
|
132
134
|
|
@@ -144,6 +146,7 @@ module Steep
|
|
144
146
|
@project = other.project
|
145
147
|
@collection_config_path = other.collection_config_path
|
146
148
|
@unreferenced = other.unreferenced
|
149
|
+
@implicitly_returns_nil = other.implicitly_returns_nil
|
147
150
|
@groups = other.groups.dup
|
148
151
|
end
|
149
152
|
|
@@ -151,6 +154,10 @@ module Steep
|
|
151
154
|
@unreferenced = value
|
152
155
|
end
|
153
156
|
|
157
|
+
def implicitly_returns_nil!(value = true)
|
158
|
+
@implicitly_returns_nil = value
|
159
|
+
end
|
160
|
+
|
154
161
|
def configure_code_diagnostics(hash = nil)
|
155
162
|
if hash
|
156
163
|
code_diagnostics_config.merge!(hash)
|
@@ -164,6 +171,7 @@ module Steep
|
|
164
171
|
end
|
165
172
|
|
166
173
|
def group(name, &block)
|
174
|
+
name = name.to_str.to_sym unless Symbol === name
|
167
175
|
group = GroupDSL.new(name, self)
|
168
176
|
|
169
177
|
Steep.logger.tagged "group=#{name}" do
|
@@ -230,6 +238,7 @@ module Steep
|
|
230
238
|
end
|
231
239
|
|
232
240
|
def target(name, &block)
|
241
|
+
name = name.to_str.to_sym unless Symbol === name
|
233
242
|
dsl = TargetDSL.new(name, project: project)
|
234
243
|
|
235
244
|
Steep.logger.tagged "target=#{name}" do
|
@@ -243,7 +252,8 @@ module Steep
|
|
243
252
|
options: dsl.library_configured? ? dsl.to_library_options : nil,
|
244
253
|
code_diagnostics_config: dsl.code_diagnostics_config,
|
245
254
|
project: project,
|
246
|
-
unreferenced: dsl.unreferenced
|
255
|
+
unreferenced: dsl.unreferenced,
|
256
|
+
implicitly_returns_nil: dsl.implicitly_returns_nil
|
247
257
|
)
|
248
258
|
|
249
259
|
dsl.groups.each do
|
data/lib/steep/project/target.rb
CHANGED
@@ -10,8 +10,9 @@ module Steep
|
|
10
10
|
attr_reader :project
|
11
11
|
attr_reader :unreferenced
|
12
12
|
attr_reader :groups
|
13
|
+
attr_reader :implicitly_returns_nil
|
13
14
|
|
14
|
-
def initialize(name:, options:, source_pattern:, signature_pattern:, code_diagnostics_config:, project:, unreferenced:)
|
15
|
+
def initialize(name:, options:, source_pattern:, signature_pattern:, code_diagnostics_config:, project:, unreferenced:, implicitly_returns_nil:)
|
15
16
|
@name = name
|
16
17
|
@target_options = options
|
17
18
|
@source_pattern = source_pattern
|
@@ -20,6 +21,7 @@ module Steep
|
|
20
21
|
@project = project
|
21
22
|
@unreferenced = unreferenced
|
22
23
|
@groups = []
|
24
|
+
@implicitly_returns_nil = implicitly_returns_nil
|
23
25
|
end
|
24
26
|
|
25
27
|
def options
|
@@ -46,7 +46,7 @@ module Steep
|
|
46
46
|
|
47
47
|
changes[path] ||= []
|
48
48
|
request[:params][:contentChanges].each do |change|
|
49
|
-
changes
|
49
|
+
changes.fetch(path) << Services::ContentChange.new(
|
50
50
|
range: change[:range]&.yield_self {|range|
|
51
51
|
[
|
52
52
|
range[:start].yield_self {|pos| Services::ContentChange::Position.new(line: pos[:line] + 1, column: pos[:character]) },
|
@@ -156,7 +156,7 @@ module Steep
|
|
156
156
|
case
|
157
157
|
when target = project.target_for_source_path(job.path)
|
158
158
|
file = service.source_files[job.path] or return
|
159
|
-
subtyping = service.signature_services
|
159
|
+
subtyping = service.signature_services.fetch(target.name).current_subtyping or return
|
160
160
|
|
161
161
|
provider = Services::CompletionProvider.new(source_text: file.content, path: job.path, subtyping: subtyping)
|
162
162
|
items = begin
|
@@ -184,12 +184,12 @@ module Steep
|
|
184
184
|
case sig_service.status
|
185
185
|
when Services::SignatureService::SyntaxErrorStatus, Services::SignatureService::AncestorErrorStatus
|
186
186
|
if buffer = sig_service.latest_env.buffers.find {|buf| Pathname(buf.name) == Pathname(relative_path) }
|
187
|
-
dirs = sig_service.latest_env.signatures
|
187
|
+
dirs = sig_service.latest_env.signatures.fetch(buffer)[0]
|
188
188
|
else
|
189
189
|
dirs = [] #: Array[RBS::AST::Directives::t]
|
190
190
|
end
|
191
191
|
else
|
192
|
-
signature = sig_service.files
|
192
|
+
signature = sig_service.files.fetch(relative_path).signature
|
193
193
|
signature.is_a?(Array) or raise
|
194
194
|
buffer, dirs, decls = signature
|
195
195
|
|
@@ -210,7 +210,7 @@ module Steep
|
|
210
210
|
end
|
211
211
|
end
|
212
212
|
|
213
|
-
buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files
|
213
|
+
buffer = RBS::Buffer.new(name: relative_path, content: sig_service.files.fetch(relative_path).content)
|
214
214
|
prefix = Services::TypeNameCompletion::Prefix.parse(buffer, line: job.line, column: job.column)
|
215
215
|
|
216
216
|
completion = Services::TypeNameCompletion.new(env: sig_service.latest_env, context: context, dirs: dirs)
|
@@ -451,7 +451,7 @@ module Steep
|
|
451
451
|
Steep.logger.tagged("##{__method__}") do
|
452
452
|
if target = project.target_for_source_path(job.path)
|
453
453
|
file = service.source_files[job.path] or return
|
454
|
-
subtyping = service.signature_services
|
454
|
+
subtyping = service.signature_services.fetch(target.name).current_subtyping or return
|
455
455
|
source =
|
456
456
|
Source.parse(file.content, path: file.path, factory: subtyping.factory)
|
457
457
|
.without_unrelated_defs(line: job.line, column: job.column)
|
data/lib/steep/server/master.rb
CHANGED
@@ -178,7 +178,6 @@ module Steep
|
|
178
178
|
attr_reader :job_queue, :write_queue
|
179
179
|
|
180
180
|
attr_reader :current_type_check_request
|
181
|
-
attr_reader :current_diagnostics
|
182
181
|
attr_reader :controller
|
183
182
|
attr_reader :result_controller
|
184
183
|
|
@@ -197,7 +196,6 @@ module Steep
|
|
197
196
|
@commandline_args = []
|
198
197
|
@job_queue = queue
|
199
198
|
@write_queue = SizedQueue.new(100)
|
200
|
-
@current_diagnostics = {}
|
201
199
|
|
202
200
|
@controller = TypeCheckController.new(project: project)
|
203
201
|
@result_controller = ResultController.new()
|
@@ -802,15 +800,7 @@ module Steep
|
|
802
800
|
Steep.logger.info "Starting new progress..."
|
803
801
|
|
804
802
|
@current_type_check_request = request
|
805
|
-
|
806
|
-
checking_paths = request.each_path.to_set
|
807
|
-
current_diagnostics.keep_if do |path, _|
|
808
|
-
checking_paths.include?(path)
|
809
|
-
end
|
810
|
-
else
|
811
|
-
current_diagnostics.clear
|
812
|
-
end
|
813
|
-
|
803
|
+
|
814
804
|
if progress
|
815
805
|
# If `request:` keyword arg is not given
|
816
806
|
request.work_done_progress.begin("Type checking", request_id: fresh_request_id)
|
@@ -909,15 +899,10 @@ module Steep
|
|
909
899
|
|
910
900
|
def push_diagnostics(path, diagnostics)
|
911
901
|
if diagnostics
|
912
|
-
ds = (current_diagnostics[path] ||= [])
|
913
|
-
|
914
|
-
ds.concat(diagnostics)
|
915
|
-
ds.uniq!
|
916
|
-
|
917
902
|
write_queue.push SendMessageJob.to_client(
|
918
903
|
message: {
|
919
904
|
method: :"textDocument/publishDiagnostics",
|
920
|
-
params: { uri: Steep::PathHelper.to_uri(path).to_s, diagnostics:
|
905
|
+
params: { uri: Steep::PathHelper.to_uri(path).to_s, diagnostics: diagnostics }
|
921
906
|
}
|
922
907
|
)
|
923
908
|
end
|
@@ -185,7 +185,7 @@ module Steep
|
|
185
185
|
loader = Services::FileLoader.new(base_dir: project.base_dir)
|
186
186
|
|
187
187
|
project.targets.each do |target|
|
188
|
-
signature_service = Services::SignatureService.load_from(target.new_env_loader())
|
188
|
+
signature_service = Services::SignatureService.load_from(target.new_env_loader(), implicitly_returns_nil: target.implicitly_returns_nil)
|
189
189
|
files.add_library_path(target, *signature_service.env_rbs_paths.to_a)
|
190
190
|
end
|
191
191
|
|
@@ -266,7 +266,7 @@ module Steep
|
|
266
266
|
request.code_paths << [target_group.name, path]
|
267
267
|
end
|
268
268
|
else
|
269
|
-
group_set = groups.
|
269
|
+
group_set = groups.filter_map do |group_name|
|
270
270
|
target_name, group_name = group_name.split(".", 2)
|
271
271
|
target_name or raise
|
272
272
|
|
@@ -280,7 +280,7 @@ module Steep
|
|
280
280
|
else
|
281
281
|
project.targets.find {|target| target.name == target_name }
|
282
282
|
end
|
283
|
-
end.
|
283
|
+
end.to_set
|
284
284
|
|
285
285
|
files.signature_paths.each do |path, target_group|
|
286
286
|
if group_set.include?(target_group)
|
@@ -223,7 +223,7 @@ module Steep
|
|
223
223
|
Steep.measure "Generating workspace symbol list for query=`#{query}`" do
|
224
224
|
provider = Index::SignatureSymbolProvider.new(project: project, assignment: assignment)
|
225
225
|
project.targets.each do |target|
|
226
|
-
index = service.signature_services
|
226
|
+
index = service.signature_services.fetch(target.name).latest_rbs_index
|
227
227
|
provider.indexes[target] = index
|
228
228
|
end
|
229
229
|
|
@@ -105,9 +105,9 @@ module Steep
|
|
105
105
|
def decl
|
106
106
|
case
|
107
107
|
when absolute_type_name.interface?
|
108
|
-
env.interface_decls
|
108
|
+
env.interface_decls.fetch(absolute_type_name).decl
|
109
109
|
when absolute_type_name.alias?
|
110
|
-
env.type_alias_decls
|
110
|
+
env.type_alias_decls.fetch(absolute_type_name).decl
|
111
111
|
when absolute_type_name.class?
|
112
112
|
case entry = env.module_class_entry(absolute_type_name)
|
113
113
|
when RBS::Environment::ClassEntry, RBS::Environment::ModuleEntry
|
@@ -127,11 +127,11 @@ module Steep
|
|
127
127
|
|
128
128
|
case
|
129
129
|
when absolute_type_name.interface?
|
130
|
-
if comment = env.interface_decls
|
130
|
+
if comment = env.interface_decls.fetch(absolute_type_name).decl.comment
|
131
131
|
comments << comment
|
132
132
|
end
|
133
133
|
when absolute_type_name.alias?
|
134
|
-
if comment = env.type_alias_decls
|
134
|
+
if comment = env.type_alias_decls.fetch(absolute_type_name).decl.comment
|
135
135
|
comments << comment
|
136
136
|
end
|
137
137
|
when absolute_type_name.class?
|
@@ -97,7 +97,7 @@ module Steep
|
|
97
97
|
relative_path = project.relative_path(path)
|
98
98
|
|
99
99
|
target = type_check.project.target_for_path(relative_path) or return []
|
100
|
-
source = type_check.source_files
|
100
|
+
source = type_check.source_files.fetch(relative_path)
|
101
101
|
typing, signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column)
|
102
102
|
|
103
103
|
typing or return []
|
@@ -163,7 +163,7 @@ module Steep
|
|
163
163
|
|
164
164
|
case
|
165
165
|
when target = type_check.project.target_for_source_path(relative_path)
|
166
|
-
source = type_check.source_files
|
166
|
+
source = type_check.source_files.fetch(relative_path, nil) or return []
|
167
167
|
typing, _signature = type_check_path(target: target, path: relative_path, content: source.content, line: line, column: column)
|
168
168
|
if typing
|
169
169
|
node, *parents = typing.source.find_nodes(line: line, column: column)
|
@@ -284,7 +284,7 @@ module Steep
|
|
284
284
|
end
|
285
285
|
|
286
286
|
def type_check_path(target:, path:, content:, line:, column:)
|
287
|
-
signature_service = type_check.signature_services
|
287
|
+
signature_service = type_check.signature_services.fetch(target.name)
|
288
288
|
subtyping = signature_service.current_subtyping or return
|
289
289
|
source = Source.parse(content, path: path, factory: subtyping.factory)
|
290
290
|
source = source.without_unrelated_defs(line: line, column: column)
|
@@ -17,7 +17,7 @@ module Steep
|
|
17
17
|
end
|
18
18
|
|
19
19
|
def content_for(target:, path:, line:, column:)
|
20
|
-
service = self.service.signature_services
|
20
|
+
service = self.service.signature_services.fetch(target.name)
|
21
21
|
|
22
22
|
env = service.latest_env
|
23
23
|
buffer = env.buffers.find {|buf| buf.name.to_s == path.to_s } or return
|
@@ -65,14 +65,14 @@ module Steep
|
|
65
65
|
def method_definition_for(factory, type_name, singleton_method: nil, instance_method: nil)
|
66
66
|
case
|
67
67
|
when instance_method
|
68
|
-
factory.definition_builder.build_instance(type_name).methods
|
68
|
+
factory.definition_builder.build_instance(type_name).methods.fetch(instance_method)
|
69
69
|
when singleton_method
|
70
70
|
methods = factory.definition_builder.build_singleton(type_name).methods
|
71
71
|
|
72
72
|
if singleton_method == :new
|
73
|
-
methods[:new] || methods
|
73
|
+
methods[:new] || methods.fetch(:initialize)
|
74
74
|
else
|
75
|
-
methods
|
75
|
+
methods.fetch(singleton_method)
|
76
76
|
end
|
77
77
|
else
|
78
78
|
raise "One of the instance_method or singleton_method is required"
|
@@ -80,7 +80,7 @@ module Steep
|
|
80
80
|
end
|
81
81
|
|
82
82
|
def typecheck(target, path:, content:, line:, column:)
|
83
|
-
subtyping = service.signature_services
|
83
|
+
subtyping = service.signature_services.fetch(target.name).current_subtyping or return
|
84
84
|
source = Source.parse(content, path: path, factory: subtyping.factory)
|
85
85
|
source = source.without_unrelated_defs(line: line, column: column)
|
86
86
|
resolver = ::RBS::Resolver::ConstantResolver.new(builder: subtyping.factory.definition_builder)
|
@@ -145,8 +145,8 @@ module Steep
|
|
145
145
|
result_node =
|
146
146
|
case parents[0]&.type
|
147
147
|
when :block, :numblock
|
148
|
-
if node == parents
|
149
|
-
parents
|
148
|
+
if node == parents.fetch(0).children[0]
|
149
|
+
parents.fetch(0)
|
150
150
|
else
|
151
151
|
node
|
152
152
|
end
|
@@ -145,13 +145,13 @@ module Steep
|
|
145
145
|
# Cursor is not on the argument (maybe on comma after argument)
|
146
146
|
return 0 if last_argument_nodes.nil? # No arguments
|
147
147
|
|
148
|
-
case last_argument_nodes
|
148
|
+
case last_argument_nodes.fetch(-2).type
|
149
149
|
when :splat
|
150
150
|
method_type.type.required_positionals.size + method_type.type.optional_positionals.size + 1 if method_type.type.rest_positionals
|
151
151
|
when :kwargs
|
152
|
-
case last_argument_nodes
|
152
|
+
case last_argument_nodes.fetch(-3).type
|
153
153
|
when :pair
|
154
|
-
argname = last_argument_nodes
|
154
|
+
argname = last_argument_nodes.fetch(-3).children.first.children.first
|
155
155
|
if method_type.type.required_keywords.key?(argname)
|
156
156
|
positionals + method_type.type.required_keywords.keys.index(argname).to_i + 1
|
157
157
|
elsif method_type.type.optional_keywords.key?(argname)
|
@@ -163,7 +163,7 @@ module Steep
|
|
163
163
|
positionals + method_type.type.required_keywords.size + method_type.type.optional_keywords.size if method_type.type.rest_keywords
|
164
164
|
end
|
165
165
|
else
|
166
|
-
pos = (node.children[2...] || raise).index { |c| c.location == last_argument_nodes
|
166
|
+
pos = (node.children[2...] || raise).index { |c| c.location == last_argument_nodes.fetch(-2).location }.to_i
|
167
167
|
if method_type.type.rest_positionals
|
168
168
|
[pos + 1, positionals - 1].min
|
169
169
|
else
|
@@ -172,14 +172,14 @@ module Steep
|
|
172
172
|
end
|
173
173
|
else
|
174
174
|
# Cursor is on the argument
|
175
|
-
case argument_nodes
|
175
|
+
case argument_nodes.fetch(-2).type
|
176
176
|
when :splat
|
177
177
|
method_type.type.required_positionals.size + method_type.type.optional_positionals.size if method_type.type.rest_positionals
|
178
178
|
when :kwargs
|
179
179
|
if argument_nodes[-3]
|
180
|
-
case argument_nodes
|
180
|
+
case argument_nodes.fetch(-3).type
|
181
181
|
when :pair
|
182
|
-
argname = argument_nodes
|
182
|
+
argname = argument_nodes.fetch(-3).children.first.children.first
|
183
183
|
if method_type.type.required_keywords.key?(argname)
|
184
184
|
positionals + method_type.type.required_keywords.keys.index(argname).to_i
|
185
185
|
elsif method_type.type.optional_keywords.key?(argname)
|
@@ -192,7 +192,7 @@ module Steep
|
|
192
192
|
end
|
193
193
|
end
|
194
194
|
else
|
195
|
-
pos = (node.children[2...] || raise).index { |c| c.location == argument_nodes
|
195
|
+
pos = (node.children[2...] || raise).index { |c| c.location == argument_nodes.fetch(-2).location }.to_i
|
196
196
|
[pos, positionals - 1].min
|
197
197
|
end
|
198
198
|
end
|
@@ -48,17 +48,18 @@ module Steep
|
|
48
48
|
end
|
49
49
|
|
50
50
|
class LoadedStatus
|
51
|
-
attr_reader :files, :builder
|
51
|
+
attr_reader :files, :builder, :implicitly_returns_nil
|
52
52
|
|
53
|
-
def initialize(files:, builder:)
|
53
|
+
def initialize(files:, builder:, implicitly_returns_nil:)
|
54
54
|
@files = files
|
55
55
|
@builder = builder
|
56
|
+
@implicitly_returns_nil = implicitly_returns_nil
|
56
57
|
end
|
57
58
|
|
58
59
|
def subtyping
|
59
60
|
@subtyping ||= begin
|
60
61
|
factory = AST::Types::Factory.new(builder: builder)
|
61
|
-
interface_builder = Interface::Builder.new(factory)
|
62
|
+
interface_builder = Interface::Builder.new(factory, implicitly_returns_nil: implicitly_returns_nil)
|
62
63
|
Subtyping::Check.new(builder: interface_builder)
|
63
64
|
end
|
64
65
|
end
|
@@ -77,14 +78,17 @@ module Steep
|
|
77
78
|
|
78
79
|
FileStatus = _ = Struct.new(:path, :content, :signature, keyword_init: true)
|
79
80
|
|
80
|
-
|
81
|
+
attr_reader :implicitly_returns_nil
|
82
|
+
|
83
|
+
def initialize(env:, implicitly_returns_nil:)
|
81
84
|
builder = RBS::DefinitionBuilder.new(env: env)
|
82
|
-
@status = LoadedStatus.new(builder: builder, files: {})
|
85
|
+
@status = LoadedStatus.new(builder: builder, files: {}, implicitly_returns_nil: implicitly_returns_nil)
|
86
|
+
@implicitly_returns_nil = implicitly_returns_nil
|
83
87
|
end
|
84
88
|
|
85
|
-
def self.load_from(loader)
|
89
|
+
def self.load_from(loader, implicitly_returns_nil:)
|
86
90
|
env = RBS::Environment.from_loader(loader).resolve_type_names
|
87
|
-
new(env: env)
|
91
|
+
new(env: env, implicitly_returns_nil: implicitly_returns_nil)
|
88
92
|
end
|
89
93
|
|
90
94
|
def env_rbs_paths
|
@@ -222,7 +226,7 @@ module Steep
|
|
222
226
|
)
|
223
227
|
when RBS::DefinitionBuilder::AncestorBuilder
|
224
228
|
builder2 = update_builder(ancestor_builder: result, paths: paths)
|
225
|
-
LoadedStatus.new(builder: builder2, files: files)
|
229
|
+
LoadedStatus.new(builder: builder2, files: files, implicitly_returns_nil: implicitly_returns_nil)
|
226
230
|
end
|
227
231
|
end
|
228
232
|
end
|
@@ -82,7 +82,7 @@ module Steep
|
|
82
82
|
@source_files = {}
|
83
83
|
@signature_services = project.targets.each.with_object({}) do |target, hash| #$ Hash[Symbol, SignatureService]
|
84
84
|
loader = Project::Target.construct_env_loader(options: target.options, project: project)
|
85
|
-
hash[target.name] = SignatureService.load_from(loader)
|
85
|
+
hash[target.name] = SignatureService.load_from(loader, implicitly_returns_nil: target.implicitly_returns_nil)
|
86
86
|
end
|
87
87
|
@signature_validation_diagnostics = project.targets.each.with_object({}) do |target, hash| #$ Hash[Symbol, Hash[Pathname, Array[Diagnostic::Signature::Base]]]
|
88
88
|
hash[target.name] = {}
|
@@ -94,7 +94,7 @@ module Steep
|
|
94
94
|
signature_diagnostics = {}
|
95
95
|
|
96
96
|
project.targets.each do |target|
|
97
|
-
service = signature_services
|
97
|
+
service = signature_services.fetch(target.name)
|
98
98
|
|
99
99
|
service.each_rbs_path do |path|
|
100
100
|
signature_diagnostics[path] ||= []
|
@@ -105,13 +105,13 @@ module Steep
|
|
105
105
|
service.status.diagnostics.group_by {|diag| diag.location&.buffer&.name&.to_s }.each do |path_string, diagnostics|
|
106
106
|
if path_string
|
107
107
|
path = Pathname(path_string)
|
108
|
-
signature_diagnostics
|
108
|
+
signature_diagnostics.fetch(path).push(*diagnostics)
|
109
109
|
end
|
110
110
|
end
|
111
111
|
when SignatureService::LoadedStatus
|
112
112
|
validation_diagnostics = signature_validation_diagnostics[target.name] || {}
|
113
113
|
validation_diagnostics.each do |path, diagnostics|
|
114
|
-
signature_diagnostics
|
114
|
+
signature_diagnostics.fetch(path).push(*diagnostics)
|
115
115
|
end
|
116
116
|
end
|
117
117
|
end
|
@@ -154,7 +154,7 @@ module Steep
|
|
154
154
|
def validate_signature(path:, target:)
|
155
155
|
Steep.logger.tagged "#validate_signature(path=#{path})" do
|
156
156
|
Steep.measure "validation" do
|
157
|
-
service = signature_services
|
157
|
+
service = signature_services.fetch(target.name)
|
158
158
|
|
159
159
|
raise "#{path} is not library nor signature of #{target.name}" unless target.possible_signature_file?(path) || service.env_rbs_paths.include?(path)
|
160
160
|
|
@@ -221,7 +221,7 @@ module Steep
|
|
221
221
|
end
|
222
222
|
end
|
223
223
|
|
224
|
-
signature_validation_diagnostics
|
224
|
+
signature_validation_diagnostics.fetch(target.name)[path] = diagnostics
|
225
225
|
end
|
226
226
|
end
|
227
227
|
end
|
@@ -231,11 +231,11 @@ module Steep
|
|
231
231
|
|
232
232
|
Steep.logger.tagged "#typecheck_source(path=#{path})" do
|
233
233
|
Steep.measure "typecheck" do
|
234
|
-
signature_service = signature_services
|
234
|
+
signature_service = signature_services.fetch(target.name)
|
235
235
|
subtyping = signature_service.current_subtyping
|
236
236
|
|
237
237
|
if subtyping
|
238
|
-
text = source_files
|
238
|
+
text = source_files.fetch(path).content
|
239
239
|
file = type_check_file(target: target, subtyping: subtyping, path: path, text: text) { signature_service.latest_constant_resolver }
|
240
240
|
source_files[path] = file
|
241
241
|
|
@@ -287,7 +287,7 @@ module Steep
|
|
287
287
|
SourceFile.with_typing(path: path, content: text, node: source.node, typing: typing, ignores: ignores)
|
288
288
|
end
|
289
289
|
rescue AnnotationParser::SyntaxError => exn
|
290
|
-
error = Diagnostic::Ruby::
|
290
|
+
error = Diagnostic::Ruby::AnnotationSyntaxError.new(message: exn.message, location: exn.location)
|
291
291
|
SourceFile.with_syntax_error(path: path, content: text, error: error)
|
292
292
|
rescue ::Parser::SyntaxError => exn
|
293
293
|
error = Diagnostic::Ruby::SyntaxError.new(message: exn.message, location: (_ = exn).diagnostic.location)
|
@@ -130,7 +130,7 @@ module Steep
|
|
130
130
|
]
|
131
131
|
when RBS::Types::Alias
|
132
132
|
type_name = env.normalize_type_name?(type.name) or return
|
133
|
-
entry = env.type_alias_decls
|
133
|
+
entry = env.type_alias_decls.fetch(type_name)
|
134
134
|
|
135
135
|
[
|
136
136
|
type_name,
|
@@ -485,7 +485,7 @@ module Steep
|
|
485
485
|
location =
|
486
486
|
case ancestor.source
|
487
487
|
when :super
|
488
|
-
primary_decl = env.class_decls
|
488
|
+
primary_decl = env.class_decls.fetch(name).primary.decl
|
489
489
|
primary_decl.is_a?(RBS::AST::Declarations::Class) or raise
|
490
490
|
if super_class = primary_decl.super_class
|
491
491
|
super_class.location
|
@@ -594,7 +594,7 @@ module Steep
|
|
594
594
|
end
|
595
595
|
end
|
596
596
|
|
597
|
-
def validate_one_alias(name, entry = env.type_alias_decls
|
597
|
+
def validate_one_alias(name, entry = env.type_alias_decls.fetch(name))
|
598
598
|
*, inner_most_outer_module = entry.outer
|
599
599
|
if inner_most_outer_module
|
600
600
|
class_type = AST::Types::Name::Singleton.new(name: inner_most_outer_module.name)
|
data/lib/steep/source.rb
CHANGED
@@ -88,7 +88,7 @@ module Steep
|
|
88
88
|
|
89
89
|
annotations.each do |annot|
|
90
90
|
map[node] ||= []
|
91
|
-
map
|
91
|
+
map.fetch(node) << annot
|
92
92
|
end
|
93
93
|
|
94
94
|
ignores = comments.filter_map do |comment|
|
@@ -269,7 +269,7 @@ module Steep
|
|
269
269
|
|
270
270
|
associated_annotations.each do |annot|
|
271
271
|
mapping[node] ||= []
|
272
|
-
mapping
|
272
|
+
mapping.fetch(node) << annot
|
273
273
|
end
|
274
274
|
|
275
275
|
annotations.replace(other_annotations)
|
@@ -379,7 +379,7 @@ module Steep
|
|
379
379
|
position = buffer.loc_to_pos([line, column])
|
380
380
|
|
381
381
|
if heredoc_nodes = find_heredoc_nodes(line, column, position)
|
382
|
-
Source.each_child_node(heredoc_nodes
|
382
|
+
Source.each_child_node(heredoc_nodes.fetch(0)) do |child|
|
383
383
|
if nodes = find_nodes_loc(child, position, heredoc_nodes)
|
384
384
|
return nodes
|
385
385
|
end
|
@@ -442,7 +442,7 @@ module Steep
|
|
442
442
|
|
443
443
|
annotations.each do |annot|
|
444
444
|
mapping[node_] ||= []
|
445
|
-
mapping
|
445
|
+
mapping.fetch(node_) << annot
|
446
446
|
end
|
447
447
|
|
448
448
|
Source.new(buffer: buffer, path: path, node: node_, mapping: mapping, comments: comments, ignores: ignores)
|
@@ -515,7 +515,7 @@ module Steep
|
|
515
515
|
types: relation.sub_type.types
|
516
516
|
)
|
517
517
|
|
518
|
-
check_type(Relation.new(sub_type: tuple_element_type, super_type: super_type.args
|
518
|
+
check_type(Relation.new(sub_type: tuple_element_type, super_type: super_type.args.fetch(0)))
|
519
519
|
end
|
520
520
|
|
521
521
|
when relation.sub_type.is_a?(AST::Types::Tuple)
|
@@ -1057,10 +1057,10 @@ module Steep
|
|
1057
1057
|
|
1058
1058
|
sup_flat_kws.each do |name, _|
|
1059
1059
|
if sub_flat_kws.key?(name)
|
1060
|
-
pairs << [sub_flat_kws
|
1060
|
+
pairs << [sub_flat_kws.fetch(name), sup_flat_kws.fetch(name)]
|
1061
1061
|
else
|
1062
1062
|
if sub_params.rest_keywords
|
1063
|
-
pairs << [sub_params.rest_keywords, sup_flat_kws
|
1063
|
+
pairs << [sub_params.rest_keywords, sup_flat_kws.fetch(name)]
|
1064
1064
|
else
|
1065
1065
|
return failure
|
1066
1066
|
end
|
@@ -102,7 +102,7 @@ module Steep
|
|
102
102
|
end
|
103
103
|
|
104
104
|
def add(var, sub_type: nil, super_type: nil, skip: false)
|
105
|
-
subs, supers, skips = dictionary
|
105
|
+
subs, supers, skips = dictionary.fetch(var)
|
106
106
|
|
107
107
|
if sub_type.is_a?(AST::Types::Logic::Base)
|
108
108
|
sub_type = AST::Builtin.bool_type
|
@@ -204,7 +204,7 @@ module Steep
|
|
204
204
|
if skip
|
205
205
|
upper_bound = upper_bound_types(var)
|
206
206
|
else
|
207
|
-
_, upper_bound, _ = dictionary
|
207
|
+
_, upper_bound, _ = dictionary.fetch(var)
|
208
208
|
end
|
209
209
|
|
210
210
|
case upper_bound.size
|
@@ -320,12 +320,12 @@ module Steep
|
|
320
320
|
end
|
321
321
|
|
322
322
|
def lower_bound_types(var_name)
|
323
|
-
lower, _, _ = dictionary
|
323
|
+
lower, _, _ = dictionary.fetch(var_name)
|
324
324
|
lower
|
325
325
|
end
|
326
326
|
|
327
327
|
def upper_bound_types(var_name)
|
328
|
-
_, upper, skips = dictionary
|
328
|
+
_, upper, skips = dictionary.fetch(var_name)
|
329
329
|
|
330
330
|
case
|
331
331
|
when upper.empty?
|