steep 0.37.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 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