steep 0.37.0 → 0.38.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: f3d9186b6988081611f8bf060700ad97eb408ab605ab11ab32b717b9a0e9b8b9
4
- data.tar.gz: 6f308f7bd551472237d5857614b765468782290733514793b2dfe35a3ac232cf
3
+ metadata.gz: 1662ab3cd8c9b1630d38939e491bd9db3b46701a5ab6f09061e4470c95fbbae8
4
+ data.tar.gz: 9fea79ba28f595b1a51812708c0b3a98170110f0367a0baa287623232fe64156
5
5
  SHA512:
6
- metadata.gz: 1fee308a7783a6e54c974c71c78189492c0f557528bccb0da530927cfdb4e4a16f4ff6cd2ec9f8c3292dd9839bb1637f68fd3aff9da0fef6783e3f4b5d838984
7
- data.tar.gz: 7cd72caf879d339e5fec0bed219957befd40d5dc2466b345435f4b523c8028a9264404b1d9c695c11ca638b8e6bbeb1d1ad8f600367cd87bf9b3c4fade99eeaa
6
+ metadata.gz: 2f42e7e12ff24d1d4acbebc7693b1bb7f1417f4d44f0cc2b2590990a50a1c20ee690d23a316414113e9a65601971cd3bf19b13babc9e09a64cfcebae1fe8c4ec
7
+ data.tar.gz: 6aa3693092fa2811fe0663c4266ed3cf9ccd2b79d7e0e8e6c3c79e3c3a29b1d19954ac0127ed0c62a1619dac2555c67ae987f3a4386001cbdf6a73a76e405829
@@ -2,6 +2,11 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 0.38.0 (2020-12-10)
6
+
7
+ * Improve `break`/`next` typing ([#271](https://github.com/soutaro/steep/pull/271))
8
+ * Add LSP `workspace/symbol` feature ([#267](https://github.com/soutaro/steep/pull/267))
9
+
5
10
  ## 0.37.0 (2020-12-06)
6
11
 
7
12
  * Update to RBS 0.20.0 with _singleton attribute_ syntax and _proc types with blocks_. ([#264](https://github.com/soutaro/steep/pull/264))
@@ -76,6 +76,10 @@ require "steep/type_inference/logic_type_interpreter"
76
76
  require "steep/type_inference/method_call"
77
77
  require "steep/ast/types"
78
78
 
79
+ require "steep/index/rbs_index"
80
+ require "steep/index/signature_symbol_provider"
81
+ require "steep/index/source_index"
82
+
79
83
  require "steep/server/utils"
80
84
  require "steep/server/base_worker"
81
85
  require "steep/server/code_worker"
@@ -195,6 +195,25 @@ module Steep
195
195
  end
196
196
  end
197
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
+
198
217
  class BreakTypeMismatch < Base
199
218
  attr_reader :expected
200
219
  attr_reader :actual
@@ -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
@@ -0,0 +1,154 @@
1
+ module Steep
2
+ module Index
3
+ class SignatureSymbolProvider
4
+ LSP = LanguageServer::Protocol
5
+ SymbolInformation = Struct.new(:name, :kind, :container_name, :location, keyword_init: true)
6
+
7
+ attr_reader :indexes
8
+
9
+ def initialize()
10
+ @indexes = []
11
+ end
12
+
13
+ def self.test_type_name(query, type_name)
14
+ case
15
+ when query == ""
16
+ true
17
+ else
18
+ type_name.to_s.upcase.include?(query.upcase)
19
+ end
20
+ end
21
+
22
+ class <<self
23
+ alias test_const_name test_type_name
24
+ alias test_global_name test_type_name
25
+ end
26
+
27
+ def self.test_method_name(query, method_name)
28
+ case
29
+ when query == ""
30
+ true
31
+ else
32
+ method_name.to_s.upcase.include?(query.upcase)
33
+ end
34
+ end
35
+
36
+ def query_symbol(query)
37
+ symbols = []
38
+
39
+ indexes.each do |index|
40
+ index.each_entry do |entry|
41
+ case entry
42
+ when RBSIndex::TypeEntry
43
+ next unless SignatureSymbolProvider.test_type_name(query, entry.type_name)
44
+
45
+ container_name = entry.type_name.namespace.relative!.to_s.delete_suffix("::")
46
+ name = entry.type_name.name.to_s
47
+
48
+ entry.declarations.each do |decl|
49
+ case decl
50
+ when RBS::AST::Declarations::Class
51
+ symbols << SymbolInformation.new(
52
+ name: name,
53
+ location: decl.location,
54
+ kind: LSP::Constant::SymbolKind::CLASS,
55
+ container_name: container_name
56
+ )
57
+ when RBS::AST::Declarations::Module
58
+ symbols << SymbolInformation.new(
59
+ name: name,
60
+ location: decl.location,
61
+ kind: LSP::Constant::SymbolKind::MODULE,
62
+ container_name: container_name
63
+ )
64
+ when RBS::AST::Declarations::Interface
65
+ symbols << SymbolInformation.new(
66
+ name: name,
67
+ location: decl.location,
68
+ kind: LSP::Constant::SymbolKind::INTERFACE,
69
+ container_name: container_name
70
+ )
71
+ when RBS::AST::Declarations::Alias
72
+ symbols << SymbolInformation.new(
73
+ name: name,
74
+ location: decl.location,
75
+ kind: LSP::Constant::SymbolKind::ENUM,
76
+ container_name: container_name
77
+ )
78
+ end
79
+ end
80
+ when RBSIndex::MethodEntry
81
+ next unless SignatureSymbolProvider.test_method_name(query, entry.method_name)
82
+
83
+ name = case entry.method_name
84
+ when InstanceMethodName
85
+ "##{entry.method_name.method_name}"
86
+ when SingletonMethodName
87
+ ".#{entry.method_name.method_name}"
88
+ end
89
+ container_name = entry.method_name.type_name.relative!.to_s
90
+
91
+ entry.declarations.each do |decl|
92
+ case decl
93
+ when RBS::AST::Members::MethodDefinition
94
+ symbols << SymbolInformation.new(
95
+ name: name,
96
+ location: decl.location,
97
+ kind: LSP::Constant::SymbolKind::METHOD,
98
+ container_name: container_name
99
+ )
100
+ when RBS::AST::Members::Alias
101
+ symbols << SymbolInformation.new(
102
+ name: name,
103
+ location: decl.location,
104
+ kind: LSP::Constant::SymbolKind::METHOD,
105
+ container_name: container_name
106
+ )
107
+ when RBS::AST::Members::AttrAccessor, RBS::AST::Members::AttrReader, RBS::AST::Members::AttrWriter
108
+ symbols << SymbolInformation.new(
109
+ name: name,
110
+ location: decl.location,
111
+ kind: LSP::Constant::SymbolKind::PROPERTY,
112
+ container_name: container_name
113
+ )
114
+
115
+ if decl.ivar_name
116
+ symbols << SymbolInformation.new(
117
+ name: decl.ivar_name.to_s,
118
+ location: decl.location,
119
+ kind: LSP::Constant::SymbolKind::FIELD,
120
+ container_name: container_name
121
+ )
122
+ end
123
+ end
124
+ end
125
+ when RBSIndex::ConstantEntry
126
+ next unless SignatureSymbolProvider.test_const_name(query, entry.const_name)
127
+
128
+ entry.declarations.each do |decl|
129
+ symbols << SymbolInformation.new(
130
+ name: entry.const_name.name.to_s,
131
+ location: decl.location,
132
+ kind: LSP::Constant::SymbolKind::CONSTANT,
133
+ container_name: entry.const_name.namespace.relative!.to_s.delete_suffix("::")
134
+ )
135
+ end
136
+ when RBSIndex::GlobalEntry
137
+ next unless SignatureSymbolProvider.test_global_name(query, entry.global_name)
138
+
139
+ entry.declarations.each do |decl|
140
+ symbols << SymbolInformation.new(
141
+ name: decl.name.to_s,
142
+ location: decl.location,
143
+ kind: LSP::Constant::SymbolKind::VARIABLE
144
+ )
145
+ end
146
+ end
147
+ end
148
+ end
149
+
150
+ symbols.uniq {|symbol| [symbol.name, symbol.location] }.sort_by {|symbol| symbol.name.to_s }
151
+ end
152
+ end
153
+ end
154
+ end
@@ -0,0 +1,100 @@
1
+ module Steep
2
+ module Index
3
+ class SourceIndex
4
+ class ConstantEntry
5
+ attr_reader :name
6
+
7
+ attr_reader :definitions
8
+ attr_reader :references
9
+
10
+ def initialize(name:)
11
+ @name = name
12
+
13
+ @definitions = Set[].compare_by_identity
14
+ @references = Set[].compare_by_identity
15
+ end
16
+
17
+ def add_definition(node)
18
+ case node.type
19
+ when :casgn, :class, :module
20
+ @definitions << node
21
+ else
22
+ raise "Unexpected constant definition: #{node.type}"
23
+ end
24
+
25
+ self
26
+ end
27
+
28
+ def add_reference(node)
29
+ case node.type
30
+ when :const
31
+ @references << node
32
+ else
33
+ raise "Unexpected constant reference: #{node.type}"
34
+ end
35
+
36
+ self
37
+ end
38
+
39
+ def merge!(other)
40
+ definitions.merge(other.definitions)
41
+ references.merge(other.references)
42
+ self
43
+ end
44
+ end
45
+
46
+ attr_reader :source
47
+ attr_reader :constant_index
48
+
49
+ attr_reader :parent
50
+ attr_reader :count
51
+ attr_reader :parent_count
52
+
53
+ def initialize(source:, parent: nil)
54
+ @source = source
55
+ @parent = parent
56
+ @parent_count = parent&.count
57
+
58
+ @count = @parent_count || 0
59
+
60
+ @constant_index = {}
61
+ end
62
+
63
+ def new_child
64
+ SourceIndex.new(source: source, parent: self)
65
+ end
66
+
67
+ def merge!(child)
68
+ raise unless child.parent == self
69
+ raise unless child.parent_count == count
70
+
71
+ constant_index.merge!(child.constant_index) do |_, entry, child_entry|
72
+ entry.merge!(child_entry)
73
+ end
74
+
75
+ @count = child.count + 1
76
+ end
77
+
78
+ def add_definition(constant:, definition:)
79
+ @count += 1
80
+ entry(constant: constant).add_definition(definition)
81
+ self
82
+ end
83
+
84
+ def add_reference(constant:, ref:)
85
+ @count += 1
86
+ entry(constant: constant).add_reference(ref)
87
+ self
88
+ end
89
+
90
+ def entry(constant:)
91
+ case
92
+ when constant
93
+ constant_index[constant] ||= ConstantEntry.new(name: constant)
94
+ else
95
+ raise
96
+ end
97
+ end
98
+ end
99
+ end
100
+ end
@@ -111,7 +111,8 @@ module Steep
111
111
  hover_provider: true,
112
112
  completion_provider: LSP::Interface::CompletionOptions.new(
113
113
  trigger_characters: [".", "@"]
114
- )
114
+ ),
115
+ workspace_symbol_provider: true
115
116
  )
116
117
  )
117
118
  }
@@ -143,6 +144,9 @@ module Steep
143
144
  when "textDocument/open"
144
145
  # Ignores open notification
145
146
 
147
+ when "workspace/symbol"
148
+ signature_worker << message
149
+
146
150
  when "shutdown"
147
151
  queue << { id: id, result: nil }
148
152
  @shutdown_request_id = id
@@ -24,7 +24,12 @@ module Steep
24
24
  def enqueue_target(target:, timestamp:)
25
25
  Steep.logger.debug "queueing target #{target.name}@#{timestamp}"
26
26
  last_target_validated_at[target] = timestamp
27
- queue << [target, timestamp]
27
+ queue << [:validate, [target, timestamp]]
28
+ end
29
+
30
+ def enqueue_symbol(id:, query:)
31
+ Steep.logger.debug "queueing symbol #{query} (#{id})"
32
+ queue << [:symbol, [id, query]]
28
33
  end
29
34
 
30
35
  def handle_request(request)
@@ -37,6 +42,8 @@ module Steep
37
42
  when "textDocument/didChange"
38
43
  update_source(request)
39
44
  validate_signature_if_required(request)
45
+ when "workspace/symbol"
46
+ enqueue_symbol(query: request[:params][:query], id: request[:id])
40
47
  end
41
48
  end
42
49
 
@@ -138,13 +145,63 @@ module Steep
138
145
  end
139
146
  end
140
147
 
148
+ def handle_workspace_symbol(query:, id:)
149
+ provider = Index::SignatureSymbolProvider.new()
150
+
151
+ project.targets.each do |target|
152
+ case target.status
153
+ when Project::Target::TypeCheckStatus
154
+ index = Index::RBSIndex.new()
155
+
156
+ builder = Index::RBSIndex::Builder.new(index: index)
157
+ builder.env(target.status.environment)
158
+
159
+ provider.indexes << index
160
+ end
161
+ end
162
+
163
+ symbols = provider.query_symbol(query)
164
+
165
+ result = symbols.map do |symbol|
166
+ {
167
+ name: symbol.name.to_s,
168
+ kind: symbol.kind,
169
+ deprecated: false,
170
+ containerName: symbol.container_name.to_s,
171
+ location: {
172
+ uri: URI.parse(project.absolute_path(symbol.location.buffer.name).to_s),
173
+ range: {
174
+ start: LSP::Interface::Position.new(
175
+ line: symbol.location.start_line - 1,
176
+ character: symbol.location.start_column,
177
+ ),
178
+ end: LSP::Interface::Position.new(
179
+ line: symbol.location.end_line - 1,
180
+ character: symbol.location.end_column
181
+ )
182
+ }
183
+ }
184
+ }
185
+ end
186
+
187
+ writer.write(id: id, result: result)
188
+ end
189
+
141
190
  def handle_job(job)
142
- target, timestamp = job
191
+ action, data = job
192
+
193
+ case action
194
+ when :validate
195
+ target, timestamp = data
143
196
 
144
- if active_job?(target, timestamp)
145
- validate_signature(target, timestamp: timestamp)
146
- else
147
- Steep.logger.info "Skipping signature validation: #{target.name}, queued timestamp=#{timestamp}, latest timestamp=#{last_target_validated_at[target]}"
197
+ if active_job?(target, timestamp)
198
+ validate_signature(target, timestamp: timestamp)
199
+ else
200
+ Steep.logger.info "Skipping signature validation: #{target.name}, queued timestamp=#{timestamp}, latest timestamp=#{last_target_validated_at[target]}"
201
+ end
202
+ when :symbol
203
+ id, query = data
204
+ handle_workspace_symbol(query: query, id: id)
148
205
  end
149
206
  end
150
207
  end
@@ -1012,22 +1012,30 @@ module Steep
1012
1012
  value = node.children[0]
1013
1013
 
1014
1014
  if break_context
1015
- case
1016
- when value && break_context.break_type
1017
- check(value, break_context.break_type) do |break_type, actual_type, result|
1018
- typing.add_error Errors::BreakTypeMismatch.new(node: node,
1019
- expected: break_type,
1020
- actual: actual_type,
1021
- result: result)
1015
+ if break_type = break_context.break_type
1016
+ if value
1017
+ check(value, break_type) do |break_type, actual_type, result|
1018
+ typing.add_error Errors::BreakTypeMismatch.new(node: node,
1019
+ expected: break_type,
1020
+ actual: actual_type,
1021
+ result: result)
1022
+ end
1023
+ else
1024
+ check_relation(sub_type: AST::Builtin.nil_type, super_type: break_type).else do |result|
1025
+ typing.add_error Errors::BreakTypeMismatch.new(node: node,
1026
+ expected: break_type,
1027
+ actual: AST::Builtin.nil_type,
1028
+ result: result)
1029
+ end
1022
1030
  end
1023
- when !value
1024
- # ok
1025
1031
  else
1026
- synthesize(value) if value
1027
- typing.add_error Errors::UnexpectedJumpValue.new(node: node)
1032
+ if value
1033
+ synthesize(value)
1034
+ typing.add_error Errors::UnexpectedJumpValue.new(node: node)
1035
+ end
1028
1036
  end
1029
1037
  else
1030
- synthesize(value)
1038
+ synthesize(value) if value
1031
1039
  typing.add_error Errors::UnexpectedJump.new(node: node)
1032
1040
  end
1033
1041
 
@@ -1037,22 +1045,32 @@ module Steep
1037
1045
  value = node.children[0]
1038
1046
 
1039
1047
  if break_context
1040
- case
1041
- when value && break_context.next_type
1042
- check(value, break_context.next_type) do |break_type, actual_type, result|
1043
- typing.add_error Errors::BreakTypeMismatch.new(node: node,
1044
- expected: break_type,
1045
- actual: actual_type,
1046
- result: result)
1048
+ if next_type = break_context.next_type
1049
+ next_type = deep_expand_alias(next_type)
1050
+
1051
+ if value
1052
+ _, constr = check(value, next_type) do |break_type, actual_type, result|
1053
+ typing.add_error Errors::BreakTypeMismatch.new(node: node,
1054
+ expected: break_type,
1055
+ actual: actual_type,
1056
+ result: result)
1057
+ end
1058
+ else
1059
+ check_relation(sub_type: AST::Builtin.nil_type, super_type: next_type).else do |result|
1060
+ typing.add_error Errors::BreakTypeMismatch.new(node: node,
1061
+ expected: next_type,
1062
+ actual: AST::Builtin.nil_type,
1063
+ result: result)
1064
+ end
1047
1065
  end
1048
- when !value
1049
- # ok
1050
1066
  else
1051
- synthesize(value) if value
1052
- typing.add_error Errors::UnexpectedJumpValue.new(node: node)
1067
+ if value
1068
+ synthesize(value)
1069
+ typing.add_error Errors::UnexpectedJumpValue.new(node: node)
1070
+ end
1053
1071
  end
1054
1072
  else
1055
- synthesize(value)
1073
+ synthesize(value) if value
1056
1074
  typing.add_error Errors::UnexpectedJump.new(node: node)
1057
1075
  end
1058
1076
 
@@ -1250,13 +1268,32 @@ module Steep
1250
1268
  constr = self
1251
1269
 
1252
1270
  name, sup, _ = node.children
1253
- _, constr = constr.synthesize(name)
1271
+ if name.type == :const
1272
+ # skip the last constant reference
1273
+ if const_parent = name.children[0]
1274
+ _, constr = constr.synthesize(const_parent)
1275
+ end
1276
+ else
1277
+ _, constr = constr.synthesize(name)
1278
+ end
1254
1279
  _, constr = constr.synthesize(sup) if sup
1255
1280
 
1256
1281
  constr.for_class(node).tap do |constructor|
1282
+ if module_type = constructor.module_context&.module_type
1283
+ _, constructor = constructor.add_typing(name, type: module_type)
1284
+ else
1285
+ _, constructor = constructor.fallback_to_any(name)
1286
+ end
1287
+
1288
+ constructor.typing.source_index.add_definition(
1289
+ constant: constructor.module_context.class_name,
1290
+ definition: node
1291
+ )
1292
+
1257
1293
  constructor.typing.add_context_for_node(node, context: constructor.context)
1258
1294
  constructor.typing.add_context_for_body(node, context: constructor.context)
1259
1295
 
1296
+ constructor.synthesize(node.children[1]) if node.children[1]
1260
1297
  constructor.synthesize(node.children[2]) if node.children[2]
1261
1298
 
1262
1299
  if constructor.module_context&.implement_name && !namespace_module?(node)
@@ -1275,6 +1312,11 @@ module Steep
1275
1312
  _, constr = constr.synthesize(name)
1276
1313
 
1277
1314
  for_module(node).yield_self do |constructor|
1315
+ constructor.typing.source_index.add_definition(
1316
+ constant: constructor.module_context.class_name,
1317
+ definition: node
1318
+ )
1319
+
1278
1320
  constructor.typing.add_context_for_node(node, context: constructor.context)
1279
1321
  constructor.typing.add_context_for_body(node, context: constructor.context)
1280
1322
 
@@ -1335,6 +1377,10 @@ module Steep
1335
1377
  const_name = constr.module_name_from_node(node)
1336
1378
 
1337
1379
  if const_name
1380
+ if constant = module_context.const_env.lookup_constant(const_name)
1381
+ typing.source_index.add_reference(constant: constant.name, ref: node)
1382
+ end
1383
+
1338
1384
  type = type_env.get(const: const_name) do
1339
1385
  constr.fallback_to_any(node)
1340
1386
  end
@@ -1352,6 +1398,10 @@ module Steep
1352
1398
  const_name = constr.module_name_from_node(node)
1353
1399
 
1354
1400
  if const_name
1401
+ if constant = module_context.const_env.lookup_constant(const_name)
1402
+ typing.source_index.add_definition(constant: constant.name, definition: node)
1403
+ end
1404
+
1355
1405
  const_type = type_env.get(const: const_name) {}
1356
1406
  value_type, constr = constr.synthesize(node.children.last, hint: const_type)
1357
1407
  type = type_env.assign(const: const_name, type: value_type, self_type: self_type) do |error|
@@ -2376,6 +2426,7 @@ module Steep
2376
2426
  block_constr = for_block(
2377
2427
  block_params: params,
2378
2428
  block_param_hint: params_hint,
2429
+ block_type_hint: return_hint,
2379
2430
  block_annotations: block_annotations,
2380
2431
  node_type_hint: nil
2381
2432
  )
@@ -2390,10 +2441,22 @@ module Steep
2390
2441
  return_type = block_constr.synthesize_block(
2391
2442
  node: node,
2392
2443
  block_body: block_body,
2393
- topdown_hint: true,
2394
2444
  block_type_hint: return_hint
2395
- ) do |error|
2396
- typing.add_error(error)
2445
+ )
2446
+
2447
+ if expected_block_type = block_constr.block_context.body_type
2448
+ check_relation(sub_type: return_type, super_type: expected_block_type).else do |result|
2449
+ block_constr.typing.add_error(
2450
+ Errors::BlockBodyTypeMismatch.new(
2451
+ node: block_body,
2452
+ expected: expected_block_type,
2453
+ actual: return_type,
2454
+ result: result
2455
+ )
2456
+ )
2457
+
2458
+ return_type = expected_block_type
2459
+ end
2397
2460
  end
2398
2461
  else
2399
2462
  return_type = AST::Builtin.any_type
@@ -2473,9 +2536,7 @@ module Steep
2473
2536
  block_params: TypeInference::BlockParams.from_node(block_params, annotations: block_annotations),
2474
2537
  block_annotations: block_annotations,
2475
2538
  block_body: block_body
2476
- ) do |error|
2477
- constr.typing.add_error(error)
2478
- end
2539
+ )
2479
2540
  end
2480
2541
  end
2481
2542
 
@@ -2850,6 +2911,7 @@ module Steep
2850
2911
  block_constr = constr.for_block(
2851
2912
  block_params: block_params_,
2852
2913
  block_param_hint: method_type.block.type.params,
2914
+ block_type_hint: method_type.block.type.return_type,
2853
2915
  block_annotations: block_annotations,
2854
2916
  node_type_hint: method_type.type.return_type
2855
2917
  )
@@ -2888,12 +2950,9 @@ module Steep
2888
2950
  if block_body
2889
2951
  block_body_type = block_constr.synthesize_block(
2890
2952
  node: node,
2891
- block_type_hint: method_type.block.type.return_type,
2892
2953
  block_body: block_body,
2893
- topdown_hint: topdown_hint
2894
- ) do |error|
2895
- errors << error
2896
- end
2954
+ block_type_hint: method_type.block.type.return_type
2955
+ )
2897
2956
  else
2898
2957
  block_body_type = AST::Builtin.nil_type
2899
2958
  end
@@ -2940,6 +2999,7 @@ module Steep
2940
2999
  end
2941
3000
 
2942
3001
  block_constr.typing.save!
3002
+
2943
3003
  rescue Subtyping::Constraints::UnsatisfiableConstraint => exn
2944
3004
  errors << Errors::UnsatisfiableConstraint.new(
2945
3005
  node: node,
@@ -3069,6 +3129,7 @@ module Steep
3069
3129
  block_constr = for_block(
3070
3130
  block_params: block_params,
3071
3131
  block_param_hint: nil,
3132
+ block_type_hint: nil,
3072
3133
  block_annotations: block_annotations,
3073
3134
  node_type_hint: nil
3074
3135
  )
@@ -3079,10 +3140,23 @@ module Steep
3079
3140
  _, block_constr = block_constr.synthesize(param.node, hint: param.type)
3080
3141
  end
3081
3142
 
3082
- block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body, topdown_hint: false, &block)
3143
+ block_type = block_constr.synthesize_block(node: node, block_type_hint: nil, block_body: block_body)
3144
+
3145
+ if expected_block_type = block_constr.block_context.body_type
3146
+ block_constr.check_relation(sub_type: block_type, super_type: expected_block_type).else do |result|
3147
+ block_constr.typing.add_error(
3148
+ Errors::BlockBodyTypeMismatch.new(
3149
+ node: node,
3150
+ expected: expected_block_type,
3151
+ actual: block_type,
3152
+ result: result
3153
+ )
3154
+ )
3155
+ end
3156
+ end
3083
3157
  end
3084
3158
 
3085
- def for_block(block_params:, block_param_hint:, block_annotations:, node_type_hint:)
3159
+ def for_block(block_params:, block_param_hint:, block_type_hint:, block_annotations:, node_type_hint:)
3086
3160
  block_param_pairs = block_param_hint && block_params.zip(block_param_hint)
3087
3161
 
3088
3162
  param_types_hash = {}
@@ -3114,7 +3188,7 @@ module Steep
3114
3188
  end
3115
3189
 
3116
3190
  block_context = TypeInference::Context::BlockContext.new(
3117
- body_type: block_annotations.block_type
3191
+ body_type: block_annotations.block_type || block_type_hint || AST::Builtin.any_type
3118
3192
  )
3119
3193
  break_context = TypeInference::Context::BreakContext.new(
3120
3194
  break_type: break_type,
@@ -3139,20 +3213,9 @@ module Steep
3139
3213
  )
3140
3214
  end
3141
3215
 
3142
- def synthesize_block(node:, block_type_hint:, block_body:, topdown_hint:)
3216
+ def synthesize_block(node:, block_type_hint:, block_body:)
3143
3217
  if block_body
3144
- body_type, _, context =
3145
- if (body_type = block_context.body_type)
3146
- check(block_body, body_type) do |expected, actual, result|
3147
- error = Errors::BlockTypeMismatch.new(node: block_body,
3148
- expected: expected,
3149
- actual: actual,
3150
- result: result)
3151
- yield(error) if block_given?
3152
- end
3153
- else
3154
- synthesize(block_body, hint: topdown_hint ? block_type_hint : nil)
3155
- end
3218
+ body_type, _, context = synthesize(block_body, hint: block_context.body_type || block_type_hint)
3156
3219
 
3157
3220
  range = block_body.loc.expression.end_pos..node.loc.end.begin_pos
3158
3221
  typing.add_context(range, context: context)
@@ -3245,7 +3308,7 @@ module Steep
3245
3308
  if module_name.namespace.relative?
3246
3309
  (current_namespace + module_name.namespace).append(module_name.name)
3247
3310
  else
3248
- module_name
3311
+ module_name.to_namespace
3249
3312
  end
3250
3313
  end
3251
3314
 
@@ -15,9 +15,13 @@ module Steep
15
15
  @table = RBS::ConstantTable.new(builder: factory.definition_builder)
16
16
  end
17
17
 
18
+ def lookup_constant(name)
19
+ table.resolve_constant_reference(name, context: context)
20
+ end
21
+
18
22
  def lookup(name)
19
23
  cache[name] ||= begin
20
- constant = table.resolve_constant_reference(name, context: context)
24
+ constant = lookup_constant(name)
21
25
 
22
26
  if constant
23
27
  factory.type(constant.type)
@@ -21,8 +21,9 @@ module Steep
21
21
  attr_reader :contexts
22
22
  attr_reader :root_context
23
23
  attr_reader :method_calls
24
+ attr_reader :source_index
24
25
 
25
- def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil)
26
+ def initialize(source:, root_context:, parent: nil, parent_last_update: parent&.last_update, contexts: nil, source_index: nil)
26
27
  @source = source
27
28
 
28
29
  @parent = parent
@@ -35,6 +36,8 @@ module Steep
35
36
  @root_context = root_context
36
37
  @contexts = contexts || TypeInference::ContextArray.from_source(source: source)
37
38
  @method_calls = {}.compare_by_identity
39
+
40
+ @source_index = source_index || Index::SourceIndex.new(source: source)
38
41
  end
39
42
 
40
43
  def add_error(error)
@@ -195,7 +198,8 @@ module Steep
195
198
  child = self.class.new(source: source,
196
199
  parent: self,
197
200
  root_context: root_context,
198
- contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: nil))
201
+ contexts: TypeInference::ContextArray.new(buffer: contexts.buffer, range: range, context: nil),
202
+ source_index: source_index.new_child)
199
203
  @should_update = true
200
204
 
201
205
  if block_given?
@@ -224,6 +228,8 @@ module Steep
224
228
  errors.each do |error|
225
229
  parent.add_error error
226
230
  end
231
+
232
+ parent.source_index.merge!(source_index)
227
233
  end
228
234
  end
229
235
  end
@@ -1,3 +1,3 @@
1
1
  module Steep
2
- VERSION = "0.37.0"
2
+ VERSION = "0.38.0"
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: steep
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.37.0
4
+ version: 0.38.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Soutaro Matsumoto
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2020-12-06 00:00:00.000000000 Z
11
+ date: 2020-12-10 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: parser
@@ -178,6 +178,9 @@ files:
178
178
  - lib/steep/drivers/watch.rb
179
179
  - lib/steep/drivers/worker.rb
180
180
  - lib/steep/errors.rb
181
+ - lib/steep/index/rbs_index.rb
182
+ - lib/steep/index/signature_symbol_provider.rb
183
+ - lib/steep/index/source_index.rb
181
184
  - lib/steep/interface/block.rb
182
185
  - lib/steep/interface/function.rb
183
186
  - lib/steep/interface/interface.rb