steep 0.52.2 → 1.0.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (46) hide show
  1. checksums.yaml +4 -4
  2. data/.github/workflows/ruby-windows.yml +34 -0
  3. data/.github/workflows/ruby.yml +2 -2
  4. data/CHANGELOG.md +47 -0
  5. data/Gemfile +1 -1
  6. data/Gemfile.lock +8 -8
  7. data/lib/steep/ast/builtin.rb +2 -2
  8. data/lib/steep/ast/types/factory.rb +108 -5
  9. data/lib/steep/ast/types/proc.rb +2 -0
  10. data/lib/steep/cli.rb +3 -1
  11. data/lib/steep/diagnostic/ruby.rb +1 -1
  12. data/lib/steep/drivers/check.rb +3 -3
  13. data/lib/steep/path_helper.rb +22 -0
  14. data/lib/steep/project.rb +3 -15
  15. data/lib/steep/server/base_worker.rb +1 -0
  16. data/lib/steep/server/change_buffer.rb +1 -1
  17. data/lib/steep/server/interaction_worker.rb +3 -5
  18. data/lib/steep/server/lsp_formatter.rb +12 -0
  19. data/lib/steep/server/master.rb +61 -45
  20. data/lib/steep/server/type_check_worker.rb +10 -25
  21. data/lib/steep/services/completion_provider.rb +3 -3
  22. data/lib/steep/services/goto_service.rb +2 -4
  23. data/lib/steep/services/hover_provider/rbs.rb +1 -1
  24. data/lib/steep/services/stats_calculator.rb +0 -1
  25. data/lib/steep/services/type_check_service.rb +3 -0
  26. data/lib/steep/signature/validator.rb +6 -1
  27. data/lib/steep/source.rb +3 -3
  28. data/lib/steep/subtyping/check.rb +0 -3
  29. data/lib/steep/type_construction.rb +140 -29
  30. data/lib/steep/type_inference/logic_type_interpreter.rb +6 -4
  31. data/lib/steep/type_inference/method_call.rb +4 -1
  32. data/lib/steep/type_inference/method_params.rb +1 -0
  33. data/lib/steep/type_inference/send_args.rb +1 -2
  34. data/lib/steep/type_inference/type_env.rb +6 -0
  35. data/lib/steep/version.rb +1 -1
  36. data/lib/steep.rb +3 -2
  37. data/smoke/compact/Steepfile +6 -0
  38. data/smoke/compact/a.rb +2 -0
  39. data/smoke/compact/a.rbs +5 -0
  40. data/smoke/compact/b.rb +2 -0
  41. data/smoke/compact/test_expectations.yml +18 -0
  42. data/smoke/regression/lambda.rb +3 -0
  43. data/smoke/regression/test_expectations.yml +12 -0
  44. data/steep.gemspec +1 -1
  45. metadata +12 -5
  46. data/lib/steep/subtyping/variable_occurrence.rb +0 -51
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3c9d5eb873780b31a2431d2e6c4efdc558fbb3a4a42c08cbe2580bb191db5bc8
4
- data.tar.gz: dee794e9cb098309b9875396ed1dc9904a4c6882aeadb27c83c26604ebcbc87d
3
+ metadata.gz: 8317c379e5b7e85cca4a22c9133248a77a112e7687c3cf553ddb90f96ab31236
4
+ data.tar.gz: cd9c06372e29c009b4af99a5f0c252dcdbdcc9d2905cbd601cffb7210f809c93
5
5
  SHA512:
6
- metadata.gz: ba05f88c28a78414ffcd41744558bdea978b72621f422571cb1450b7b0d56fb77c2b65329064226863db2517d4769a6f54e7c47ce92eef59d97f0403bb9e9425
7
- data.tar.gz: 6e260b48940214b7c0910bf2678c587b469e163e70265f197ef8fd17a1703a68fd9488c77c3d1f8254939c074281717593e49812875fb705615189cd3ec4cdf0
6
+ metadata.gz: 7b0cfaee1dac3cdc8a69d9ef50714615647c1049783d6406d6ee3246c11a5cb2b5e4287f42a896d13e9ed6411e092acf15406199a0f6f0e3bad412f0ae12e250
7
+ data.tar.gz: a8b8192a8e6217eff958d30ac12c9aa1cbf9608626c892c9ae9585e33c9241d5a75e760060271e15f60f9869ceab41e9ff2fab38920db9692aa4f1ec296d1257
@@ -0,0 +1,34 @@
1
+ name: Run test on Windows
2
+
3
+ on:
4
+ push:
5
+ branches:
6
+ - master
7
+ pull_request: {}
8
+
9
+ jobs:
10
+ test:
11
+ strategy:
12
+ matrix:
13
+ ruby_version:
14
+ - "2.7"
15
+ - "3.0"
16
+ - "3.1"
17
+ task:
18
+ - test
19
+ # - test:output Ignored because the order of diagnostics changes somehow
20
+ - build
21
+ runs-on: windows-latest
22
+ steps:
23
+ - uses: actions/checkout@v3
24
+ - uses: ruby/setup-ruby@v1
25
+ with:
26
+ ruby-version: ${{ matrix.ruby_version }}
27
+ - name: Run test
28
+ run: |
29
+ git config --global --add safe.directory /__w/steep/steep
30
+ ruby -v
31
+ gem install bundler
32
+ bundle install --jobs 4 --retry 3
33
+ bin/setup
34
+ bundle exec rake ${{matrix.task}}
@@ -1,4 +1,4 @@
1
- name: Ruby
1
+ name: Run test on container
2
2
 
3
3
  on:
4
4
  push:
@@ -8,7 +8,6 @@ on:
8
8
 
9
9
  jobs:
10
10
  test:
11
- runs-on: "ubuntu-latest"
12
11
  strategy:
13
12
  matrix:
14
13
  container_tag:
@@ -20,6 +19,7 @@ jobs:
20
19
  - test
21
20
  - test:output
22
21
  - build
22
+ runs-on: ubuntu-latest
23
23
  container:
24
24
  image: rubylang/ruby:${{ matrix.container_tag }}
25
25
  steps:
data/CHANGELOG.md CHANGED
@@ -2,6 +2,53 @@
2
2
 
3
3
  ## master
4
4
 
5
+ ## 1.0.2 (2022-07-19)
6
+
7
+ This is another patch release for Steep 1.0.
8
+
9
+ ### Type checker
10
+
11
+ * Fix type application validation ([#607](https://github.com/soutaro/steep/pull/607))
12
+
13
+ ## 1.0.1 (2022-06-16)
14
+
15
+ This is the first patch release for Steep 1.0.
16
+ However, this release includes one non-trivial type system update, [\#570](https://github.com/soutaro/steep/pull/570), which adds a special typing rule for `Hash#compact` like `Array#compact`.
17
+ The change will make type checking more permissive and precise, so no new error won't be reported with the fix.
18
+
19
+ ### Type checker
20
+
21
+ * Support shorthand hash for Ruby 3.1 ([\#567](https://github.com/soutaro/steep/pull/567))
22
+ * Fix super and zsuper with block ([\#568](https://github.com/soutaro/steep/pull/568))
23
+ * Apply logic-type evaluation only if the node is `:send` ([\#569](https://github.com/soutaro/steep/pull/569))
24
+ * Add support for `Hash#compact` ([\#570](https://github.com/soutaro/steep/pull/570))
25
+ * Use given `const_env` when making a new `ModuleContext` ([\#575](https://github.com/soutaro/steep/pull/575))
26
+ * Graceful, hopefully, error handling with undefined outer module ([\#576](https://github.com/soutaro/steep/pull/576))
27
+ * Type check anonymous block forwarding ([\#577](https://github.com/soutaro/steep/pull/577))
28
+ * Incompatible default value is a type error ([\#578](https://github.com/soutaro/steep/pull/578))
29
+ * Load `ChildrenLevel` helper in `AST::Types::Proc` ([\#584](https://github.com/soutaro/steep/pull/584))
30
+ * Type check `gvar` and `gvasgn` in methods([\#579](https://github.com/soutaro/steep/pull/579))
31
+ * Avoid `UnexpectedError` when assigning untyped singleton class ([\#586](https://github.com/soutaro/steep/pull/586))
32
+
33
+ ### Tool
34
+
35
+ * Improve Windows support ([\#561](https://github.com/soutaro/steep/pull/561), [\#573](https://github.com/soutaro/steep/pull/573))
36
+ * Test if `.ruby-version` exists before `rvm do` in binstub ([\#558](https://github.com/soutaro/steep/pull/558))
37
+ * Fix typo ([\#564](https://github.com/soutaro/steep/pull/564))
38
+ * Ignore `untitled:` URIs in LSP ([\#580](https://github.com/soutaro/steep/pull/580))
39
+
40
+ ### Miscellaneous
41
+
42
+ * Fix test name ([\#565](https://github.com/soutaro/steep/pull/565), [\#566](https://github.com/soutaro/steep/pull/566), [\#585](https://github.com/soutaro/steep/pull/585))
43
+ * Remove some unused code except tests ([\#587](https://github.com/soutaro/steep/pull/587))
44
+
45
+ ## 1.0.0 (2022-05-20)
46
+
47
+ * Add special typing rule for `Array#compact` ([\#555](https://github.com/soutaro/steep/pull/555))
48
+ * Add custom method type of `#fetch` on tuples and records ([\#554](https://github.com/soutaro/steep/pull/554))
49
+ * Better `masgn` ([\#553](https://github.com/soutaro/steep/pull/553))
50
+ * Fix method parameter type checking ([\#552](https://github.com/soutaro/steep/pull/552))
51
+
5
52
  ## 0.52.2 (2022-05-02)
6
53
 
7
54
  * Handle class declaration with non-const super class ([\#546](https://github.com/soutaro/steep/pull/546))
data/Gemfile CHANGED
@@ -7,7 +7,7 @@ gem "with_steep_types", path: "test/gems/with_steep_types"
7
7
  gem "without_steep_types", path: "test/gems/without_steep_types"
8
8
 
9
9
  gem "rake"
10
- gem "minitest", "~> 5.15"
10
+ gem "minitest", "~> 5.16"
11
11
  gem "minitest-hooks"
12
12
  group :stackprof, optional: true do
13
13
  gem "stackprof"
data/Gemfile.lock CHANGED
@@ -1,12 +1,12 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- steep (0.52.2)
4
+ steep (1.0.2)
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
- parser (>= 3.0)
9
+ parser (>= 3.1)
10
10
  rainbow (>= 2.2.2, < 4.0)
11
11
  rbs (>= 2.3.2)
12
12
  terminal-table (>= 2, < 4)
@@ -24,7 +24,7 @@ PATH
24
24
  GEM
25
25
  remote: https://rubygems.org/
26
26
  specs:
27
- activesupport (7.0.2.4)
27
+ activesupport (7.0.3.1)
28
28
  concurrent-ruby (~> 1.0, >= 1.0.2)
29
29
  i18n (>= 1.6, < 2)
30
30
  minitest (>= 5.1)
@@ -32,13 +32,13 @@ GEM
32
32
  ast (2.4.2)
33
33
  concurrent-ruby (1.1.10)
34
34
  ffi (1.15.5)
35
- i18n (1.10.0)
35
+ i18n (1.12.0)
36
36
  concurrent-ruby (~> 1.0)
37
37
  language_server-protocol (3.16.0.3)
38
38
  listen (3.7.1)
39
39
  rb-fsevent (~> 0.10, >= 0.10.3)
40
40
  rb-inotify (~> 0.9, >= 0.9.10)
41
- minitest (5.15.0)
41
+ minitest (5.16.1)
42
42
  minitest-hooks (1.5.0)
43
43
  minitest (> 5.3)
44
44
  minitest-slow_test (0.2.0)
@@ -51,19 +51,19 @@ GEM
51
51
  rb-fsevent (0.11.1)
52
52
  rb-inotify (0.10.1)
53
53
  ffi (~> 1.0)
54
- rbs (2.3.2)
54
+ rbs (2.6.0)
55
55
  stackprof (0.2.19)
56
56
  terminal-table (3.0.2)
57
57
  unicode-display_width (>= 1.1.1, < 3)
58
58
  tzinfo (2.0.4)
59
59
  concurrent-ruby (~> 1.0)
60
- unicode-display_width (2.1.0)
60
+ unicode-display_width (2.2.0)
61
61
 
62
62
  PLATFORMS
63
63
  ruby
64
64
 
65
65
  DEPENDENCIES
66
- minitest (~> 5.15)
66
+ minitest (~> 5.16)
67
67
  minitest-hooks
68
68
  minitest-slow_test
69
69
  rake
@@ -16,7 +16,7 @@ module Steep
16
16
  args << Builtin.any_type
17
17
  end
18
18
  end
19
- arity == args.size or raise "Mulformed instance type: name=#{module_name}, args=#{args}"
19
+ arity == args.size or raise "Malformed instance type: name=#{module_name}, args=#{args}"
20
20
 
21
21
  Types::Name::Instance.new(name: module_name, args: args)
22
22
  end
@@ -28,7 +28,7 @@ module Steep
28
28
  def instance_type?(type, args: nil)
29
29
  if type.is_a?(Types::Name::Instance)
30
30
  if args
31
- arity == args.size or raise "Mulformed instance type: name=#{module_name}, args=#{args}"
31
+ arity == args.size or raise "Malformed instance type: name=#{module_name}, args=#{args}"
32
32
  type.name == module_name && type.args == args
33
33
  else
34
34
  type.name == module_name && type.args.size == arity
@@ -9,6 +9,12 @@ module Steep
9
9
 
10
10
  attr_reader :type_interface_cache
11
11
 
12
+ def inspect
13
+ s = "#<%s:%#018x " % [self.class, object_id]
14
+ s << "@definition_builder=#<%s:%#018x>" % [definition_builder.class, definition_builder.object_id]
15
+ s + ">"
16
+ end
17
+
12
18
  def initialize(builder:)
13
19
  @definition_builder = builder
14
20
 
@@ -282,8 +288,6 @@ module Steep
282
288
  fvs = self_type.free_variables()
283
289
 
284
290
  type_params = []
285
- alpha_vars = []
286
- alpha_types = []
287
291
 
288
292
  conflicting_names = method_type.type_params.each.with_object([]) do |param, names|
289
293
  names << params.name if fvs.include?(param.name)
@@ -674,6 +678,57 @@ module Steep
674
678
  )
675
679
  end
676
680
 
681
+ array_interface.methods[:fetch] = array_interface.methods[:fetch].yield_self do |fetch|
682
+ Interface::Interface::Entry.new(
683
+ method_types: type.types.flat_map.with_index {|elem_type, index|
684
+ [
685
+ Interface::MethodType.new(
686
+ type_params: [],
687
+ type: Interface::Function.new(
688
+ params: Interface::Function::Params.build(required: [AST::Types::Literal.new(value: index)]),
689
+ return_type: elem_type,
690
+ location: nil
691
+ ),
692
+ block: nil,
693
+ method_decls: Set[]
694
+ ),
695
+ Interface::MethodType.new(
696
+ type_params: [Interface::TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false)],
697
+ type: Interface::Function.new(
698
+ params: Interface::Function::Params.build(
699
+ required: [
700
+ AST::Types::Literal.new(value: index),
701
+ AST::Types::Var.new(name: :T)
702
+ ]
703
+ ),
704
+ return_type: AST::Types::Union.build(types: [elem_type, AST::Types::Var.new(name: :T)]),
705
+ location: nil
706
+ ),
707
+ block: nil,
708
+ method_decls: Set[]
709
+ ),
710
+ Interface::MethodType.new(
711
+ type_params: [Interface::TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false)],
712
+ type: Interface::Function.new(
713
+ params: Interface::Function::Params.build(required: [AST::Types::Literal.new(value: index)]),
714
+ return_type: AST::Types::Union.build(types: [elem_type, AST::Types::Var.new(name: :T)]),
715
+ location: nil
716
+ ),
717
+ block: Interface::Block.new(
718
+ type: Interface::Function.new(
719
+ params: Interface::Function::Params.build(required: [AST::Builtin::Integer.instance_type]),
720
+ return_type: AST::Types::Var.new(name: :T),
721
+ location: nil
722
+ ),
723
+ optional: false
724
+ ),
725
+ method_decls: Set[]
726
+ )
727
+ ]
728
+ } + fetch.method_types
729
+ )
730
+ end
731
+
677
732
  array_interface.methods[:first] = array_interface.methods[:first].yield_self do |first|
678
733
  Interface::Interface::Entry.new(
679
734
  method_types: [
@@ -712,11 +767,11 @@ module Steep
712
767
 
713
768
  when Record
714
769
  yield_self do
715
- key_type = type.elements.keys.map {|value| Literal.new(value: value, location: nil) }.yield_self do |types|
770
+ all_key_type = type.elements.keys.map {|value| Literal.new(value: value, location: nil) }.yield_self do |types|
716
771
  Union.build(types: types, location: nil)
717
772
  end
718
- value_type = Union.build(types: type.elements.values, location: nil)
719
- hash_type = Builtin::Hash.instance_type(key_type, value_type)
773
+ all_value_type = Union.build(types: type.elements.values, location: nil)
774
+ hash_type = Builtin::Hash.instance_type(all_key_type, all_value_type)
720
775
 
721
776
  interface(hash_type, private: private, self_type: self_type).tap do |hash_interface|
722
777
  hash_interface.methods[:[]] = hash_interface.methods[:[]].yield_self do |ref|
@@ -768,6 +823,54 @@ module Steep
768
823
  } + update.method_types
769
824
  )
770
825
  end
826
+
827
+ hash_interface.methods[:fetch] = hash_interface.methods[:fetch].yield_self do |update|
828
+ Interface::Interface::Entry.new(
829
+ method_types: type.elements.flat_map {|key_value, value_type|
830
+ key_type = Literal.new(value: key_value, location: nil)
831
+
832
+ [
833
+ Interface::MethodType.new(
834
+ type_params: [],
835
+ type: Interface::Function.new(
836
+ params: Interface::Function::Params.build(required: [key_type]),
837
+ return_type: value_type,
838
+ location: nil
839
+ ),
840
+ block: nil,
841
+ method_decls: Set[]
842
+ ),
843
+ Interface::MethodType.new(
844
+ type_params: [Interface::TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false)],
845
+ type: Interface::Function.new(
846
+ params: Interface::Function::Params.build(required: [key_type, AST::Types::Var.new(name: :T)]),
847
+ return_type: AST::Types::Union.build(types: [value_type, AST::Types::Var.new(name: :T)]),
848
+ location: nil
849
+ ),
850
+ block: nil,
851
+ method_decls: Set[]
852
+ ),
853
+ Interface::MethodType.new(
854
+ type_params: [Interface::TypeParam.new(name: :T, upper_bound: nil, variance: :invariant, unchecked: false)],
855
+ type: Interface::Function.new(
856
+ params: Interface::Function::Params.build(required: [key_type]),
857
+ return_type: AST::Types::Union.build(types: [value_type, AST::Types::Var.new(name: :T)]),
858
+ location: nil
859
+ ),
860
+ block: Interface::Block.new(
861
+ type: Interface::Function.new(
862
+ params: Interface::Function::Params.build(required: [all_key_type]),
863
+ return_type: AST::Types::Var.new(name: :T),
864
+ location: nil
865
+ ),
866
+ optional: false
867
+ ),
868
+ method_decls: Set[]
869
+ )
870
+ ]
871
+ } + update.method_types
872
+ )
873
+ end
771
874
  end
772
875
  end
773
876
 
@@ -45,6 +45,8 @@ module Steep
45
45
  end
46
46
  end
47
47
 
48
+ include Helper::ChildrenLevel
49
+
48
50
  def level
49
51
  children = type.params.each_type.to_a + [type.return_type]
50
52
  if block
data/lib/steep/cli.rb CHANGED
@@ -271,7 +271,9 @@ if type "rbenv" > /dev/null 2>&1; then
271
271
  STEEP="rbenv exec ${STEEP}"
272
272
  else
273
273
  if type "rvm" > /dev/null 2>&1; then
274
- STEEP="rvm ${ROOT_DIR} do ${STEEP}"
274
+ if [ -e ${ROOT_DIR}/.ruby-version ]; then
275
+ STEEP="rvm ${ROOT_DIR} do ${STEEP}"
276
+ fi
275
277
  fi
276
278
  fi
277
279
 
@@ -296,7 +296,7 @@ module Steep
296
296
  attr_reader :method_type
297
297
 
298
298
  def initialize(node:, method_type:)
299
- super(node: node, location: node.loc.selector)
299
+ super(node: node, location: (node.type == :super || node.type == :zsuper) ? node.loc.keyword : node.loc.selector)
300
300
  @method_type = method_type
301
301
  end
302
302
 
@@ -139,7 +139,7 @@ module Steep
139
139
  missing_count = 0
140
140
 
141
141
  ns = notifications.each.with_object({}) do |notification, hash|
142
- path = project.relative_path(Pathname(URI.parse(notification[:uri]).path))
142
+ path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]))
143
143
  hash[path] = notification[:diagnostics]
144
144
  end
145
145
 
@@ -186,7 +186,7 @@ module Steep
186
186
  end
187
187
 
188
188
  ns = notifications.each.with_object({}) do |notification, hash|
189
- path = project.relative_path(Pathname(URI.parse(notification[:uri]).path))
189
+ path = project.relative_path(Steep::PathHelper.to_pathname(notification[:uri]))
190
190
  hash[path] = notification[:diagnostics]
191
191
  end
192
192
 
@@ -215,7 +215,7 @@ module Steep
215
215
  total = errors.sum {|notification| notification[:diagnostics].size }
216
216
 
217
217
  errors.each do |notification|
218
- path = Pathname(URI.parse(notification[:uri]).path)
218
+ path = Steep::PathHelper.to_pathname(notification[:uri])
219
219
  buffer = RBS::Buffer.new(name: project.relative_path(path), content: path.read)
220
220
  printer = DiagnosticPrinter.new(buffer: buffer, stdout: stdout)
221
221
 
@@ -0,0 +1,22 @@
1
+ module Steep
2
+ module PathHelper
3
+ module_function
4
+
5
+ def to_pathname(uri, dosish: Gem.win_platform?)
6
+ uri = URI.parse(uri)
7
+ if uri.scheme == "file"
8
+ path = uri.path
9
+ path.sub!(%r{^/([a-zA-Z])(:|%3A)//?}i, '\1:/') if dosish
10
+ Pathname(path)
11
+ end
12
+ end
13
+
14
+ def to_uri(path, dosish: Gem.win_platform?)
15
+ str_path = path.to_s
16
+ if dosish
17
+ str_path.insert(0, "/") if str_path[0] != "/"
18
+ end
19
+ URI::File.build(path: str_path)
20
+ end
21
+ end
22
+ end
data/lib/steep/project.rb CHANGED
@@ -16,22 +16,10 @@ module Steep
16
16
  steepfile_path.parent
17
17
  end
18
18
 
19
- def relative_path(orig_path)
20
- path = if Gem.win_platform?
21
- path_str = URI.decode_www_form_component(
22
- orig_path.to_s.delete_prefix("/")
23
- )
24
- unless path_str.start_with?(%r{[a-z]:/}i)
25
- # FIXME: Sometimes drive letter is missing, taking from base_dir
26
- path_str = base_dir.to_s.split("/")[0] + "/" + path_str
27
- end
28
- Pathname.new(
29
- path_str
30
- )
31
- else
32
- orig_path
33
- end
19
+ def relative_path(path)
34
20
  path.relative_path_from(base_dir)
21
+ rescue ArgumentError
22
+ path
35
23
  end
36
24
 
37
25
  def absolute_path(path)
@@ -69,6 +69,7 @@ module Steep
69
69
  end
70
70
  end
71
71
  end
72
+ thread.abort_on_exception = true
72
73
 
73
74
  Steep.logger.tagged "frontend" do
74
75
  begin
@@ -40,7 +40,7 @@ module Steep
40
40
 
41
41
  def collect_changes(request)
42
42
  push_buffer do |changes|
43
- path = project.relative_path(Pathname(URI.parse(request[:params][:textDocument][:uri]).path))
43
+ path = project.relative_path(Steep::PathHelper.to_pathname(request[:params][:textDocument][:uri]))
44
44
  version = request[:params][:textDocument][:version]
45
45
  Steep.logger.info { "Updating source: path=#{path}, version=#{version}..." }
46
46
 
@@ -53,8 +53,7 @@ module Steep
53
53
  when "textDocument/hover"
54
54
  id = request[:id]
55
55
 
56
- uri = URI.parse(request[:params][:textDocument][:uri])
57
- path = project.relative_path(Pathname(uri.path))
56
+ path = project.relative_path(Steep::PathHelper.to_pathname(request[:params][:textDocument][:uri]))
58
57
  line = request[:params][:position][:line]+1
59
58
  column = request[:params][:position][:character]
60
59
 
@@ -64,8 +63,7 @@ module Steep
64
63
  id = request[:id]
65
64
 
66
65
  params = request[:params]
67
- uri = URI.parse(params[:textDocument][:uri])
68
- path = project.relative_path(Pathname(uri.path))
66
+ path = project.relative_path(Steep::PathHelper.to_pathname(params[:textDocument][:uri]))
69
67
  line, column = params[:position].yield_self {|hash| [hash[:line]+1, hash[:character]] }
70
68
  trigger = params.dig(:context, :triggerCharacter)
71
69
 
@@ -144,7 +142,7 @@ module Steep
144
142
  decls = sig_service.files[relative_path].decls
145
143
  locator = RBS::Locator.new(decls: decls)
146
144
 
147
- hd, tail = locator.find2(line: job.line, column: job.column)
145
+ _hd, tail = locator.find2(line: job.line, column: job.column)
148
146
 
149
147
  namespace = []
150
148
  tail.each do |t|
@@ -48,6 +48,18 @@ module Steep
48
48
  call = content.method_call
49
49
  builder.push do |s|
50
50
  case call
51
+ when TypeInference::MethodCall::Special
52
+ mt = call.actual_method_type.with(
53
+ type: call.actual_method_type.type.with(return_type: call.return_type)
54
+ )
55
+ s << <<-EOM
56
+ **💡 Custom typing rule applies**
57
+
58
+ ```rbs
59
+ #{mt.to_s}
60
+ ```
61
+
62
+ EOM
51
63
  when TypeInference::MethodCall::Typed
52
64
  mt = call.actual_method_type.with(
53
65
  type: call.actual_method_type.type.with(return_type: call.return_type)