steep 0.50.0 → 0.51.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +7 -1
- data/Gemfile +1 -0
- data/Gemfile.lock +8 -5
- data/lib/steep/ast/annotation/collection.rb +10 -8
- data/lib/steep/ast/types/factory.rb +5 -5
- data/lib/steep/cli.rb +8 -0
- data/lib/steep/diagnostic/deprecated/unknown_constant_assigned.rb +28 -0
- data/lib/steep/diagnostic/ruby.rb +21 -15
- data/lib/steep/index/source_index.rb +18 -1
- data/lib/steep/module_helper.rb +4 -7
- data/lib/steep/server/interaction_worker.rb +45 -2
- data/lib/steep/server/master.rb +1 -1
- data/lib/steep/services/completion_provider.rb +109 -1
- data/lib/steep/services/goto_service.rb +4 -6
- data/lib/steep/services/hover_content.rb +52 -4
- data/lib/steep/services/type_check_service.rb +6 -3
- data/lib/steep/source.rb +19 -13
- data/lib/steep/type_construction.rb +166 -148
- data/lib/steep/type_inference/constant_env.rb +33 -15
- data/lib/steep/type_inference/context.rb +6 -7
- data/lib/steep/type_inference/type_env.rb +16 -54
- data/lib/steep/version.rb +1 -1
- data/smoke/const/test_expectations.yml +24 -19
- data/smoke/diagnostics/test_expectations.yml +80 -10
- data/smoke/integer/test_expectations.yml +24 -4
- data/smoke/method/test_expectations.yml +30 -0
- data/smoke/regression/test_expectations.yml +24 -0
- data/smoke/yield/test_expectations.yml +20 -0
- data/steep.gemspec +1 -1
- metadata +5 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 502d495f9b623c5d90a041a1e0bb7854be76251a8ac0f3567c1c91911eb641ee
|
4
|
+
data.tar.gz: 7845d6d26f38ceae87407d507f3f67b8d35bae18ecdd5f4ee9fdb841d434a4ad
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: e2e61987da5ef5d78381affeb2f4fbb8b84dd2a6fede0baa60c68f54a3464e3cb7eea0e2822f22a66d62f1de3b9f8b223cd6399dceb927397a3dab0bed3fea5d
|
7
|
+
data.tar.gz: ee91ba6b1a4d8f35ec1fbc157efd2fb54f27b11e398af09a7ef3d4f403ae0ae2fab3258404316c6ded646f688b61ff38b47a514fec83cd9fe1b4fcf136fdc441
|
data/CHANGELOG.md
CHANGED
@@ -2,7 +2,13 @@
|
|
2
2
|
|
3
3
|
## master
|
4
4
|
|
5
|
-
|
5
|
+
## 0.51.0 (2022-04-01)
|
6
|
+
|
7
|
+
* Completion for constant ([\#524](https://github.com/soutaro/steep/pull/524))
|
8
|
+
* Better hover/completion message ([\#525](https://github.com/soutaro/steep/pull/525))
|
9
|
+
* Show available commands when using `--help` ([\#523](https://github.com/soutaro/steep/pull/523))
|
10
|
+
|
11
|
+
## 0.50.0 (2022-03-22)
|
6
12
|
|
7
13
|
* CLI option for override steep command at spawn worker ([\#511](https://github.com/soutaro/steep/pull/511))
|
8
14
|
* LSP related improvements for Sublime LSP ([\#513](https://github.com/soutaro/steep/pull/513))
|
data/Gemfile
CHANGED
data/Gemfile.lock
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
steep (0.
|
4
|
+
steep (0.51.0)
|
5
5
|
activesupport (>= 5.1)
|
6
6
|
language_server-protocol (>= 3.15, < 4.0)
|
7
7
|
listen (~> 3.0)
|
8
8
|
parallel (>= 1.0.0)
|
9
9
|
parser (>= 3.0)
|
10
10
|
rainbow (>= 2.2.2, < 4.0)
|
11
|
-
rbs (>= 2.
|
11
|
+
rbs (>= 2.3.0)
|
12
12
|
terminal-table (>= 2, < 4)
|
13
13
|
|
14
14
|
PATH
|
@@ -30,7 +30,7 @@ GEM
|
|
30
30
|
minitest (>= 5.1)
|
31
31
|
tzinfo (~> 2.0)
|
32
32
|
ast (2.4.2)
|
33
|
-
concurrent-ruby (1.1.
|
33
|
+
concurrent-ruby (1.1.10)
|
34
34
|
ffi (1.15.5)
|
35
35
|
i18n (1.10.0)
|
36
36
|
concurrent-ruby (~> 1.0)
|
@@ -41,7 +41,9 @@ GEM
|
|
41
41
|
minitest (5.15.0)
|
42
42
|
minitest-hooks (1.5.0)
|
43
43
|
minitest (> 5.3)
|
44
|
-
|
44
|
+
minitest-slow_test (0.2.0)
|
45
|
+
minitest (>= 5.0)
|
46
|
+
parallel (1.22.1)
|
45
47
|
parser (3.1.1.0)
|
46
48
|
ast (~> 2.4.1)
|
47
49
|
rainbow (3.1.1)
|
@@ -49,7 +51,7 @@ GEM
|
|
49
51
|
rb-fsevent (0.11.1)
|
50
52
|
rb-inotify (0.10.1)
|
51
53
|
ffi (~> 1.0)
|
52
|
-
rbs (2.
|
54
|
+
rbs (2.3.0)
|
53
55
|
stackprof (0.2.19)
|
54
56
|
terminal-table (3.0.2)
|
55
57
|
unicode-display_width (>= 1.1.1, < 3)
|
@@ -63,6 +65,7 @@ PLATFORMS
|
|
63
65
|
DEPENDENCIES
|
64
66
|
minitest (~> 5.15)
|
65
67
|
minitest-hooks
|
68
|
+
minitest-slow_test
|
66
69
|
rake
|
67
70
|
stackprof
|
68
71
|
steep!
|
@@ -4,7 +4,7 @@ module Steep
|
|
4
4
|
class Collection
|
5
5
|
attr_reader :annotations
|
6
6
|
attr_reader :factory
|
7
|
-
attr_reader :
|
7
|
+
attr_reader :context
|
8
8
|
|
9
9
|
attr_reader :var_type_annotations
|
10
10
|
attr_reader :const_type_annotations
|
@@ -19,10 +19,10 @@ module Steep
|
|
19
19
|
attr_reader :dynamic_annotations
|
20
20
|
attr_reader :break_type_annotation
|
21
21
|
|
22
|
-
def initialize(annotations:, factory:,
|
22
|
+
def initialize(annotations:, factory:, context:)
|
23
23
|
@annotations = annotations
|
24
24
|
@factory = factory
|
25
|
-
@
|
25
|
+
@context = context
|
26
26
|
|
27
27
|
@var_type_annotations = {}
|
28
28
|
@method_type_annotations = {}
|
@@ -64,7 +64,7 @@ module Steep
|
|
64
64
|
|
65
65
|
def absolute_type(type)
|
66
66
|
if type
|
67
|
-
factory.absolute_type(type,
|
67
|
+
factory.absolute_type(type, context: context)
|
68
68
|
end
|
69
69
|
end
|
70
70
|
|
@@ -140,7 +140,7 @@ module Steep
|
|
140
140
|
end
|
141
141
|
|
142
142
|
def merge_block_annotations(annotations)
|
143
|
-
if annotations.
|
143
|
+
if annotations.context != context || annotations.factory != factory
|
144
144
|
raise "Cannot merge another annotation: self=#{self}, other=#{annotations}"
|
145
145
|
end
|
146
146
|
|
@@ -148,9 +148,11 @@ module Steep
|
|
148
148
|
annotation.is_a?(BlockType) || annotation.is_a?(BreakType)
|
149
149
|
end
|
150
150
|
|
151
|
-
self.class.new(
|
152
|
-
|
153
|
-
|
151
|
+
self.class.new(
|
152
|
+
annotations: retained_annotations + annotations.annotations,
|
153
|
+
factory: factory,
|
154
|
+
context: context
|
155
|
+
)
|
154
156
|
end
|
155
157
|
|
156
158
|
def any?(&block)
|
@@ -18,7 +18,7 @@ module Steep
|
|
18
18
|
end
|
19
19
|
|
20
20
|
def type_name_resolver
|
21
|
-
@type_name_resolver ||= RBS::TypeNameResolver.
|
21
|
+
@type_name_resolver ||= RBS::Resolver::TypeNameResolver.new(definition_builder.env)
|
22
22
|
end
|
23
23
|
|
24
24
|
def type_opt(type)
|
@@ -810,15 +810,15 @@ module Steep
|
|
810
810
|
@env ||= definition_builder.env
|
811
811
|
end
|
812
812
|
|
813
|
-
def absolute_type(type,
|
813
|
+
def absolute_type(type, context:)
|
814
814
|
absolute_type = type_1(type).map_type_name do |name|
|
815
|
-
absolute_type_name(name,
|
815
|
+
absolute_type_name(name, context: context) || name.absolute!
|
816
816
|
end
|
817
817
|
type(absolute_type)
|
818
818
|
end
|
819
819
|
|
820
|
-
def absolute_type_name(type_name,
|
821
|
-
type_name_resolver.resolve(type_name, context:
|
820
|
+
def absolute_type_name(type_name, context:)
|
821
|
+
type_name_resolver.resolve(type_name, context: context)
|
822
822
|
end
|
823
823
|
|
824
824
|
def instance_type(type_name, args: nil, location: nil)
|
data/lib/steep/cli.rb
CHANGED
@@ -23,6 +23,14 @@ module Steep
|
|
23
23
|
|
24
24
|
def process_global_options
|
25
25
|
OptionParser.new do |opts|
|
26
|
+
opts.banner = <<~USAGE
|
27
|
+
Usage: steep [options]
|
28
|
+
|
29
|
+
available commands: #{CLI.available_commands.join(', ')}
|
30
|
+
|
31
|
+
Options:
|
32
|
+
USAGE
|
33
|
+
|
26
34
|
opts.on("--version") do
|
27
35
|
process_version
|
28
36
|
exit 0
|
@@ -0,0 +1,28 @@
|
|
1
|
+
Steep.logger.error "Diagnostic `Ruby::UnknownConstantAssigned` is deprecated. Use `Ruby::UnknownConstant` instead."
|
2
|
+
|
3
|
+
module Steep
|
4
|
+
module Diagnostic
|
5
|
+
module Ruby
|
6
|
+
class UnknownConstantAssigned < Base
|
7
|
+
attr_reader :context
|
8
|
+
attr_reader :name
|
9
|
+
|
10
|
+
def initialize(node:, context:, name:)
|
11
|
+
const = node.children[0]
|
12
|
+
loc = if const
|
13
|
+
const.loc.expression.join(node.loc.name)
|
14
|
+
else
|
15
|
+
node.loc.name
|
16
|
+
end
|
17
|
+
super(node: node, location: loc)
|
18
|
+
@context = context
|
19
|
+
@name = name
|
20
|
+
end
|
21
|
+
|
22
|
+
def header_line
|
23
|
+
"Cannot find the declaration of constant `#{name}`"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -551,27 +551,33 @@ module Steep
|
|
551
551
|
end
|
552
552
|
end
|
553
553
|
|
554
|
-
class
|
555
|
-
attr_reader :context
|
554
|
+
class UnknownConstant < Base
|
556
555
|
attr_reader :name
|
556
|
+
attr_reader :kind
|
557
557
|
|
558
|
-
def initialize(node:,
|
559
|
-
|
560
|
-
loc = if const
|
561
|
-
const.loc.expression.join(node.loc.name)
|
562
|
-
else
|
563
|
-
node.loc.name
|
564
|
-
end
|
565
|
-
super(node: node, location: loc)
|
566
|
-
@context = context
|
558
|
+
def initialize(node:, name:)
|
559
|
+
super(node: node, location: node.loc.name)
|
567
560
|
@name = name
|
561
|
+
@kind = :constant
|
562
|
+
end
|
563
|
+
|
564
|
+
def class!
|
565
|
+
@kind = :class
|
566
|
+
self
|
567
|
+
end
|
568
|
+
|
569
|
+
def module!
|
570
|
+
@kind = :module
|
571
|
+
self
|
568
572
|
end
|
569
573
|
|
570
574
|
def header_line
|
571
|
-
"Cannot find the declaration of
|
575
|
+
"Cannot find the declaration of #{kind}: `#{name}`"
|
572
576
|
end
|
573
577
|
end
|
574
578
|
|
579
|
+
autoload :UnknownConstantAssigned, "steep/diagnostic/deprecated/unknown_constant_assigned"
|
580
|
+
|
575
581
|
class FallbackAny < Base
|
576
582
|
def initialize(node:)
|
577
583
|
super(node: node)
|
@@ -744,7 +750,7 @@ module Steep
|
|
744
750
|
ImplicitBreakValueMismatch => :warning,
|
745
751
|
FallbackAny => :information,
|
746
752
|
ElseOnExhaustiveCase => :warning,
|
747
|
-
|
753
|
+
UnknownConstant => :warning,
|
748
754
|
MethodDefinitionMissing => :information
|
749
755
|
}
|
750
756
|
).freeze
|
@@ -757,7 +763,7 @@ module Steep
|
|
757
763
|
ImplicitBreakValueMismatch => nil,
|
758
764
|
FallbackAny => nil,
|
759
765
|
ElseOnExhaustiveCase => nil,
|
760
|
-
|
766
|
+
UnknownConstant => nil,
|
761
767
|
MethodDefinitionMissing => nil
|
762
768
|
}
|
763
769
|
).freeze
|
@@ -770,7 +776,7 @@ module Steep
|
|
770
776
|
ImplicitBreakValueMismatch => nil,
|
771
777
|
FallbackAny => nil,
|
772
778
|
ElseOnExhaustiveCase => nil,
|
773
|
-
|
779
|
+
UnknownConstant => nil,
|
774
780
|
MethodDefinitionMissing => nil,
|
775
781
|
UnexpectedJump => nil
|
776
782
|
}
|
@@ -16,7 +16,7 @@ module Steep
|
|
16
16
|
|
17
17
|
def add_definition(node)
|
18
18
|
case node.type
|
19
|
-
when :casgn, :
|
19
|
+
when :casgn, :const
|
20
20
|
@definitions << node
|
21
21
|
else
|
22
22
|
raise "Unexpected constant definition: #{node.type}"
|
@@ -145,6 +145,23 @@ module Steep
|
|
145
145
|
raise
|
146
146
|
end
|
147
147
|
end
|
148
|
+
|
149
|
+
def reference(constant_node: nil)
|
150
|
+
case
|
151
|
+
when constant_node
|
152
|
+
constant_index.each do |name, entry|
|
153
|
+
if entry.references.include?(constant_node)
|
154
|
+
return name
|
155
|
+
end
|
156
|
+
|
157
|
+
if entry.definitions.include?(constant_node)
|
158
|
+
return name
|
159
|
+
end
|
160
|
+
end
|
161
|
+
|
162
|
+
nil
|
163
|
+
end
|
164
|
+
end
|
148
165
|
end
|
149
166
|
end
|
150
167
|
end
|
data/lib/steep/module_helper.rb
CHANGED
@@ -1,12 +1,9 @@
|
|
1
1
|
module Steep
|
2
2
|
module ModuleHelper
|
3
|
-
def module_name_from_node(
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
name = node.children[1]
|
8
|
-
RBS::TypeName.new(name: name, namespace: namespace)
|
9
|
-
end
|
3
|
+
def module_name_from_node(parent_node, constant_name)
|
4
|
+
namespace = namespace_from_node(parent_node) or return
|
5
|
+
name = constant_name
|
6
|
+
RBS::TypeName.new(name: name, namespace: namespace)
|
10
7
|
end
|
11
8
|
|
12
9
|
def namespace_from_node(node)
|
@@ -175,6 +175,21 @@ HOVER
|
|
175
175
|
end
|
176
176
|
|
177
177
|
string
|
178
|
+
when Services::HoverContent::ConstantContent
|
179
|
+
ss = []
|
180
|
+
if content.class_or_module?
|
181
|
+
ss << ["```rbs", retrieve_decl_information(content.decl.primary.decl), "```"].join("\n")
|
182
|
+
end
|
183
|
+
|
184
|
+
if content.constant?
|
185
|
+
ss << ["```rbs", "#{content.full_name}: #{content.type}", "```"].join("\n")
|
186
|
+
end
|
187
|
+
|
188
|
+
if s = content.comment_string
|
189
|
+
ss << s
|
190
|
+
end
|
191
|
+
|
192
|
+
ss.join("\n\n----\n\n")
|
178
193
|
when Services::HoverContent::TypeContent
|
179
194
|
"`#{content.type}`"
|
180
195
|
end
|
@@ -327,7 +342,16 @@ HOVER
|
|
327
342
|
if comment
|
328
343
|
LSP::Interface::MarkupContent.new(
|
329
344
|
kind: LSP::Constant::MarkupKind::MARKDOWN,
|
330
|
-
value: comment.string
|
345
|
+
value: comment.string.gsub(/<!--(?~-->)-->/, "")
|
346
|
+
)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
def format_comments(comments)
|
351
|
+
unless comments.empty?
|
352
|
+
LSP::Interface::MarkupContent.new(
|
353
|
+
kind: LSP::Constant::MarkupKind::MARKDOWN,
|
354
|
+
value: comments.map(&:string).join("\n----\n").gsub(/<!--(?~-->)-->/, "")
|
331
355
|
)
|
332
356
|
end
|
333
357
|
end
|
@@ -408,6 +432,25 @@ HOVER
|
|
408
432
|
new_text: item.identifier
|
409
433
|
)
|
410
434
|
)
|
435
|
+
when Services::CompletionProvider::ConstantItem
|
436
|
+
case
|
437
|
+
when item.class? || item.module?
|
438
|
+
kind = LanguageServer::Protocol::Constant::CompletionItemKind::CLASS
|
439
|
+
detail = item.full_name.to_s
|
440
|
+
else
|
441
|
+
kind = LanguageServer::Protocol::Constant::CompletionItemKind::CONSTANT
|
442
|
+
detail = item.type.to_s
|
443
|
+
end
|
444
|
+
LanguageServer::Protocol::Interface::CompletionItem.new(
|
445
|
+
label: item.identifier,
|
446
|
+
kind: kind,
|
447
|
+
detail: detail,
|
448
|
+
documentation: format_comments(item.comments),
|
449
|
+
text_edit: LanguageServer::Protocol::Interface::TextEdit.new(
|
450
|
+
range: range,
|
451
|
+
new_text: item.identifier
|
452
|
+
)
|
453
|
+
)
|
411
454
|
when Services::CompletionProvider::MethodNameItem
|
412
455
|
method_type_snippet = method_type_to_snippet(item.method_type)
|
413
456
|
LanguageServer::Protocol::Interface::CompletionItem.new(
|
@@ -418,7 +461,7 @@ HOVER
|
|
418
461
|
new_text: "#{item.identifier}#{method_type_snippet}",
|
419
462
|
range: range
|
420
463
|
),
|
421
|
-
documentation: item.comment
|
464
|
+
documentation: format_comment(item.comment),
|
422
465
|
insert_text_format: LanguageServer::Protocol::Constant::InsertTextFormat::SNIPPET,
|
423
466
|
sort_text: item.inherited? ? 'z' : 'a' # Ensure language server puts non-inherited methods before inherited methods
|
424
467
|
)
|
data/lib/steep/server/master.rb
CHANGED
@@ -501,7 +501,7 @@ module Steep
|
|
501
501
|
partialResult: true
|
502
502
|
},
|
503
503
|
completion_provider: LSP::Interface::CompletionOptions.new(
|
504
|
-
trigger_characters: [".", "@"],
|
504
|
+
trigger_characters: [".", "@", ":"],
|
505
505
|
work_done_progress: true
|
506
506
|
),
|
507
507
|
workspace_symbol_provider: true,
|
@@ -10,6 +10,30 @@ module Steep
|
|
10
10
|
|
11
11
|
InstanceVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
12
12
|
LocalVariableItem = Struct.new(:identifier, :range, :type, keyword_init: true)
|
13
|
+
ConstantItem = Struct.new(:env, :identifier, :range, :type, :full_name, keyword_init: true) do
|
14
|
+
def class?
|
15
|
+
if decl = env.class_decls[full_name]
|
16
|
+
decl.primary.decl.is_a?(RBS::AST::Declarations::Class)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def module?
|
21
|
+
if decl = env.class_decls[full_name]
|
22
|
+
decl.primary.decl.is_a?(RBS::AST::Declarations::Module)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def comments
|
27
|
+
case
|
28
|
+
when decl = env.class_decls[full_name]
|
29
|
+
decl.decls.filter_map {|d| d.decl.comment }
|
30
|
+
when comment = env.constant_decls[full_name]&.decl&.comment
|
31
|
+
[comment]
|
32
|
+
else
|
33
|
+
[]
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
13
37
|
MethodNameItem = Struct.new(:identifier, :range, :receiver_type, :method_type, :method_decls, keyword_init: true) do
|
14
38
|
def comment
|
15
39
|
case method_decls.size
|
@@ -61,6 +85,10 @@ module Steep
|
|
61
85
|
end
|
62
86
|
end
|
63
87
|
|
88
|
+
def env
|
89
|
+
subtyping.factory.env
|
90
|
+
end
|
91
|
+
|
64
92
|
def run(line:, column:)
|
65
93
|
source_text = self.source_text.dup
|
66
94
|
index = index_for(source_text, line:line, column: column)
|
@@ -92,6 +120,15 @@ module Steep
|
|
92
120
|
source_text[index-1] = " "
|
93
121
|
type_check!(source_text, line: line, column: column)
|
94
122
|
items_for_atmark(position: position)
|
123
|
+
when ":"
|
124
|
+
if source_text[index-2] == ":"
|
125
|
+
source_text[index-1] = " "
|
126
|
+
source_text[index-2] = " "
|
127
|
+
type_check!(source_text, line: line, column: column)
|
128
|
+
items_for_colon2(position: position)
|
129
|
+
else
|
130
|
+
[]
|
131
|
+
end
|
95
132
|
else
|
96
133
|
[]
|
97
134
|
end
|
@@ -170,8 +207,25 @@ module Steep
|
|
170
207
|
prefix: prefix,
|
171
208
|
position: position,
|
172
209
|
items: items)
|
210
|
+
constant_items_for_context(context, prefix: prefix, position: position, items: items)
|
173
211
|
|
174
|
-
when node.type == :
|
212
|
+
when node.type == :const && node.children[0] && at_end?(position, of: node.loc)
|
213
|
+
# Foo::Ba ← (const)
|
214
|
+
parent_node = node.children[0]
|
215
|
+
parent_type = typing.type_of(node: parent_node)
|
216
|
+
|
217
|
+
if parent_type
|
218
|
+
prefix = node.children[1].to_s
|
219
|
+
|
220
|
+
method_items_for_receiver_type(parent_type,
|
221
|
+
include_private: false,
|
222
|
+
prefix: prefix,
|
223
|
+
position: position,
|
224
|
+
items: items)
|
225
|
+
constant_items_for_context(context, parent: parent_node, prefix: prefix, position: position, items: items)
|
226
|
+
end
|
227
|
+
|
228
|
+
when node.type == :send && at_end?(position, of: node.loc.dot) && node.loc.dot.source == "."
|
175
229
|
# foo.← ba
|
176
230
|
receiver_type = case (type = typing.type_of(node: node.children[0]))
|
177
231
|
when AST::Types::Self
|
@@ -186,6 +240,10 @@ module Steep
|
|
186
240
|
position: position,
|
187
241
|
items: items)
|
188
242
|
|
243
|
+
when node.type == :send && at_end?(position, of: node.loc.dot) && node.loc.dot.source == "::"
|
244
|
+
# foo::← ba
|
245
|
+
items.push(*items_for_colon2(position: position))
|
246
|
+
|
189
247
|
when node.type == :ivar && at_end?(position, of: node.loc)
|
190
248
|
# @fo ←
|
191
249
|
instance_variable_items_for_context(context, position: position, prefix: node.children[0].to_s, items: items)
|
@@ -198,6 +256,7 @@ module Steep
|
|
198
256
|
items: items)
|
199
257
|
local_variable_items_for_context(context, position: position, prefix: "", items: items)
|
200
258
|
instance_variable_items_for_context(context, position: position, prefix: "", items: items)
|
259
|
+
constant_items_for_context(context, position: position, prefix: "", items: items)
|
201
260
|
end
|
202
261
|
|
203
262
|
items
|
@@ -236,6 +295,31 @@ module Steep
|
|
236
295
|
end
|
237
296
|
end
|
238
297
|
|
298
|
+
def items_for_colon2(position:)
|
299
|
+
# :: ←
|
300
|
+
shift_pos = position-2
|
301
|
+
node, *_ = source.find_nodes(line: shift_pos.line, column: shift_pos.column)
|
302
|
+
node ||= source.node
|
303
|
+
|
304
|
+
items = []
|
305
|
+
case node&.type
|
306
|
+
when :const
|
307
|
+
# Constant:: ←
|
308
|
+
context = typing.context_at(line: position.line, column: position.column)
|
309
|
+
constant_items_for_context(context, parent: node, position: position, items: items, prefix: "")
|
310
|
+
when nil
|
311
|
+
# :: ←
|
312
|
+
context = typing.context_at(line: position.line, column: position.column)
|
313
|
+
constant_items_for_context(context, parent: nil, position: position, items: items, prefix: "")
|
314
|
+
end
|
315
|
+
|
316
|
+
if node
|
317
|
+
items.push(*items_for_dot(position: position - 1))
|
318
|
+
end
|
319
|
+
|
320
|
+
items
|
321
|
+
end
|
322
|
+
|
239
323
|
def items_for_atmark(position:)
|
240
324
|
# @ ←
|
241
325
|
shift_pos = position-1
|
@@ -290,6 +374,30 @@ module Steep
|
|
290
374
|
end
|
291
375
|
end
|
292
376
|
|
377
|
+
def constant_items_for_context(context, parent: nil, position:, prefix:, items:)
|
378
|
+
range = range_for(position, prefix: prefix)
|
379
|
+
|
380
|
+
if parent
|
381
|
+
case parent.type
|
382
|
+
when :const
|
383
|
+
const_name = typing.source_index.reference(constant_node: parent)
|
384
|
+
consts = context.module_context.const_env.children(const_name)
|
385
|
+
end
|
386
|
+
else
|
387
|
+
consts = context.module_context.const_env.constants
|
388
|
+
end
|
389
|
+
|
390
|
+
if consts
|
391
|
+
consts.each do |name, tuple|
|
392
|
+
type, full_name, _ = tuple
|
393
|
+
|
394
|
+
if name.to_s.start_with?(prefix)
|
395
|
+
items << ConstantItem.new(env: env, identifier: name, range: range, type: type, full_name: full_name)
|
396
|
+
end
|
397
|
+
end
|
398
|
+
end
|
399
|
+
end
|
400
|
+
|
293
401
|
def instance_variable_items_for_context(context, position:, prefix:, items:)
|
294
402
|
range = range_for(position, prefix: prefix)
|
295
403
|
context.type_env.ivar_types.map do |name, type|
|
@@ -116,10 +116,8 @@ module Steep
|
|
116
116
|
case node.type
|
117
117
|
when :const, :casgn
|
118
118
|
if test_ast_location(node.location.name, line: line, column: column)
|
119
|
-
if
|
120
|
-
|
121
|
-
const = const_env.lookup_constant(module_name_from_node(node))
|
122
|
-
queries << ConstantQuery.new(name: const.name, from: :ruby)
|
119
|
+
if name = typing.source_index.reference(constant_node: node)
|
120
|
+
queries << ConstantQuery.new(name: name, from: :ruby)
|
123
121
|
end
|
124
122
|
end
|
125
123
|
when :def, :defs
|
@@ -247,8 +245,8 @@ module Steep
|
|
247
245
|
entry = typing.source_index.entry(constant: name)
|
248
246
|
entry.definitions.each do |node|
|
249
247
|
case node.type
|
250
|
-
when :
|
251
|
-
locations << node.
|
248
|
+
when :const
|
249
|
+
locations << node.location.expression
|
252
250
|
when :casgn
|
253
251
|
parent = node.children[0]
|
254
252
|
location =
|