yoda-language-server 0.9.0 → 0.10.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.
Files changed (90) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +5 -0
  3. data/client/vscode/package-lock.json +6 -6
  4. data/client/vscode/src/check-versions.ts +5 -11
  5. data/client/vscode/src/install-tools.ts +1 -1
  6. data/lib/yoda/cli/analyze_deps.rb +46 -25
  7. data/lib/yoda/id_mask.rb +84 -0
  8. data/lib/yoda/model/descriptions/require_path_description.rb +45 -0
  9. data/lib/yoda/model/descriptions.rb +1 -0
  10. data/lib/yoda/model/node_signatures/node.rb +9 -1
  11. data/lib/yoda/model/values/literal_value.rb +3 -0
  12. data/lib/yoda/parsing/location.rb +9 -0
  13. data/lib/yoda/services/loadable_path_resolver.rb +33 -0
  14. data/lib/yoda/services.rb +1 -0
  15. data/lib/yoda/store/actions/read_project_files.rb +9 -7
  16. data/lib/yoda/store/adapters/gdbm_adapter/namespace_accessor.rb +1 -1
  17. data/lib/yoda/store/adapters/memory_adapter.rb +1 -1
  18. data/lib/yoda/store/objects/libraries_status.rb +1 -1
  19. data/lib/yoda/store/objects/library/core.rb +8 -0
  20. data/lib/yoda/store/objects/library/gem.rb +14 -3
  21. data/lib/yoda/store/objects/library/path_resolvable.rb +29 -0
  22. data/lib/yoda/store/objects/library/std.rb +9 -0
  23. data/lib/yoda/store/objects/library.rb +1 -0
  24. data/lib/yoda/store/objects/patch.rb +1 -1
  25. data/lib/yoda/store/objects/patch_set.rb +2 -2
  26. data/lib/yoda/store/project/dependency.rb +22 -4
  27. data/lib/yoda/store/project/file_finder.rb +20 -0
  28. data/lib/yoda/store/project.rb +2 -0
  29. data/lib/yoda/store/registry/cache.rb +2 -2
  30. data/lib/yoda/store/registry/composer.rb +9 -7
  31. data/lib/yoda/store/registry/index.rb +14 -10
  32. data/lib/yoda/store/registry/library_registry.rb +1 -1
  33. data/lib/yoda/store/registry.rb +1 -1
  34. data/lib/yoda/typing/constant_resolver/code_query.rb +25 -0
  35. data/lib/yoda/typing/constant_resolver/query.rb +12 -1
  36. data/lib/yoda/typing/constant_resolver.rb +13 -8
  37. data/lib/yoda/typing/inferencer/load_resolver.rb +37 -0
  38. data/lib/yoda/typing/inferencer/tracer.rb +32 -0
  39. data/lib/yoda/typing/inferencer.rb +3 -2
  40. data/lib/yoda/typing/node_info.rb +5 -0
  41. data/lib/yoda/typing/tree/{defined.rb → ask_defined.rb} +3 -2
  42. data/lib/yoda/typing/tree/base.rb +65 -20
  43. data/lib/yoda/typing/tree/begin.rb +5 -5
  44. data/lib/yoda/typing/tree/block_call.rb +26 -0
  45. data/lib/yoda/typing/tree/case.rb +8 -19
  46. data/lib/yoda/typing/tree/class_tree.rb +10 -18
  47. data/lib/yoda/typing/tree/conditional_loop.rb +15 -0
  48. data/lib/yoda/typing/tree/constant.rb +19 -0
  49. data/lib/yoda/typing/tree/constant_assignment.rb +2 -2
  50. data/lib/yoda/typing/tree/ensure.rb +17 -0
  51. data/lib/yoda/typing/tree/for.rb +7 -0
  52. data/lib/yoda/typing/tree/hash_tree.rb +32 -0
  53. data/lib/yoda/typing/tree/if.rb +10 -5
  54. data/lib/yoda/typing/tree/interpolation_text.rb +21 -0
  55. data/lib/yoda/typing/tree/literal.rb +8 -36
  56. data/lib/yoda/typing/tree/literal_inferable.rb +48 -0
  57. data/lib/yoda/typing/tree/local_exit.rb +15 -0
  58. data/lib/yoda/typing/tree/logical_assignment.rb +5 -5
  59. data/lib/yoda/typing/tree/logical_operator.rb +6 -5
  60. data/lib/yoda/typing/tree/method_def.rb +41 -0
  61. data/lib/yoda/typing/tree/method_inferable.rb +51 -0
  62. data/lib/yoda/typing/tree/module_tree.rb +7 -20
  63. data/lib/yoda/typing/tree/multiple_assignment.rb +6 -10
  64. data/lib/yoda/typing/tree/namespace_inferable.rb +20 -0
  65. data/lib/yoda/typing/tree/rescue.rb +18 -0
  66. data/lib/yoda/typing/tree/rescue_clause.rb +42 -0
  67. data/lib/yoda/typing/tree/self.rb +2 -1
  68. data/lib/yoda/typing/tree/send.rb +8 -60
  69. data/lib/yoda/typing/tree/send_inferable.rb +89 -0
  70. data/lib/yoda/typing/tree/singleton_class_tree.rb +24 -0
  71. data/lib/yoda/typing/tree/singleton_method_def.rb +41 -0
  72. data/lib/yoda/typing/tree/super.rb +9 -2
  73. data/lib/yoda/typing/tree/variable.rb +5 -10
  74. data/lib/yoda/typing/tree/variable_assignment.rb +11 -8
  75. data/lib/yoda/typing/tree/yield.rb +9 -2
  76. data/lib/yoda/typing/tree.rb +55 -22
  77. data/lib/yoda/typing.rb +1 -0
  78. data/lib/yoda/version.rb +1 -1
  79. data/lib/yoda.rb +1 -0
  80. metadata +25 -13
  81. data/lib/yoda/typing/inferencer/ast_traverser.rb +0 -408
  82. data/lib/yoda/typing/tree/block.rb +0 -12
  83. data/lib/yoda/typing/tree/const.rb +0 -12
  84. data/lib/yoda/typing/tree/escape.rb +0 -12
  85. data/lib/yoda/typing/tree/hash_body.rb +0 -36
  86. data/lib/yoda/typing/tree/literal_with_interpolation.rb +0 -21
  87. data/lib/yoda/typing/tree/method.rb +0 -43
  88. data/lib/yoda/typing/tree/rescue_body.rb +0 -12
  89. data/lib/yoda/typing/tree/singleton_method.rb +0 -47
  90. data/lib/yoda/typing/tree/while.rb +0 -12
@@ -2,26 +2,15 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class Case < Base
5
- # @return [[Store::Types::Base, Environment]]
6
- def infer_case_node
7
- # TODO
8
- Types::Union.new([*when_body_nodes, else_node].map { |node| infer(node) })
9
- end
10
-
11
- def children
12
- @children ||= [subject, *when_branches, else_branch]
13
- end
14
-
15
- def subject
16
- @subject ||= build_child(node.children.first)
17
- end
18
-
19
- def when_branches
20
- @when_branches ||= node.children.slice(1, -2).map(&method(:build_child))
21
- end
5
+ # @!method node
6
+ # @return [AST::CaseNode]
22
7
 
23
- def else_branch
24
- @else_branch ||= build_child(node.children.last)
8
+ # @return [Type::Type]
9
+ def infer_type
10
+ subject_node, *when_nodes, else_node = node.children
11
+ infer_child(subject_node)
12
+ when_body_nodes = when_nodes.map { |node| node.children.last }
13
+ generator.union_type(*[*when_body_nodes, else_node].compact.map { |node| infer_child(node) })
25
14
  end
26
15
  end
27
16
  end
@@ -1,29 +1,21 @@
1
+ require 'yoda/typing/tree/namespace_inferable'
2
+
1
3
  module Yoda
2
4
  module Typing
3
5
  module Tree
4
6
  class ClassTree < Base
5
- def type
6
- infer_namespace_node(node)
7
- end
7
+ include NamespaceInferable
8
8
 
9
- # @param node [::AST::Node]
10
- # @return [Types::Base]
11
- def infer_namespace_node(node)
12
- case node.type
13
- when :module
14
- name_node, block_node = node.children
15
- when :class
16
- name_node, _, block_node = node.children
17
- end
18
- constant_resolver = ConstantResolver.new(context: context, node: name_node)
19
- type = constant_resolver.resolve_constant_type
20
- block_context = NamespaceContext.new(objects: [constant_resolver.constant], parent: context, registry: context.registry, receiver: type)
9
+ # @!method node
10
+ # @return [AST::ClassNode]
21
11
 
22
- if block_node
23
- derive(context: block_context).infer(block_node)
12
+ # @return [Types::Base]
13
+ def infer_type
14
+ if super_class_node = node.super_class
15
+ infer_child(super_class_node)
24
16
  end
25
17
 
26
- type
18
+ infer_namespace
27
19
  end
28
20
  end
29
21
  end
@@ -0,0 +1,15 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class ConditionalLoop < Base
5
+ # @!method node
6
+ # @return [AST::ConditionalLoopNode]
7
+
8
+ def infer_type
9
+ # TODO
10
+ infer_child(node.body)
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,19 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class Constant < Base
5
+ # @!method node
6
+ # @return [AST::ConstantNode]
7
+
8
+ def infer_type
9
+ query = context.constant_resolver.build_query_for_node(node, tracer: tracer)
10
+ if (base_query = query.base).is_a?(ConstantResolver::CodeQuery)
11
+ base_query.result_type = infer_child(base_query.node)
12
+ end
13
+
14
+ context.constant_resolver.resolve(query)
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -2,9 +2,9 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class ConstantAssignment < Base
5
- def process
5
+ def infer_type
6
6
  # TODO
7
- infer(node.children.last)
7
+ infer_child(node.content)
8
8
  end
9
9
  end
10
10
  end
@@ -0,0 +1,17 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class Ensure < Base
5
+ # @!method node
6
+ # @return [AST::EnsureNode]
7
+
8
+ # @return [Types::Type]
9
+ def infer_type
10
+ type = infer_child(node.body)
11
+ infer_child(node.ensure_body)
12
+ type
13
+ end
14
+ end
15
+ end
16
+ end
17
+ end
@@ -2,6 +2,13 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class For < Base
5
+ # @!method node
6
+ # @return [AST::ForNode]
7
+
8
+ def infer_type
9
+ # TODO
10
+ infer_child(node.body)
11
+ end
5
12
  end
6
13
  end
7
14
  end
@@ -0,0 +1,32 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class HashTree < Base
5
+ # @!method node
6
+ # @return [AST::HashNode]
7
+
8
+ # @return [Types::Type]
9
+ def infer_type
10
+ hash = node.contents.each_with_object({}) do |node, memo|
11
+ case node.type
12
+ when :pair
13
+ case node.key.type
14
+ when :sym
15
+ memo[node.key.value.to_sym] = infer_child(node.value)
16
+ when :str
17
+ memo[node.key.value.to_s] = infer_child(node.value)
18
+ else
19
+ # TODO: Support other key types.
20
+ end
21
+ when :kwsplat
22
+ infer_child(node.content)
23
+ # TODO: merge infered result
24
+ end
25
+ end
26
+
27
+ generator.record_type(hash)
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -2,14 +2,19 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class If < Base
5
- def type
6
- infer_branch_nodes(node.children.slice(1..2).compact)
5
+ # @!method node
6
+ # @return [AST::IfNode]
7
+
8
+ # @return [Types::Type]
9
+ def infer_type
10
+ infer_branch_nodes(node.children.first, node.children.slice(1..2).compact)
7
11
  end
8
12
 
9
- # @param node [Array<::AST::Node>]
13
+ # @param branch_nodes [Array<::AST::Node>]
10
14
  # @return [Types::Base]
11
- def infer_branch_nodes(nodes)
12
- Types::Union.new(nodes.map { |node| infer(node) })
15
+ def infer_branch_nodes(condition_node, branch_nodes)
16
+ infer_child(condition_node)
17
+ generator.union_type(*branch_nodes.map { |node| infer_child(node) })
13
18
  end
14
19
  end
15
20
  end
@@ -0,0 +1,21 @@
1
+ require 'yoda/typing/tree/literal_inferable'
2
+
3
+ module Yoda
4
+ module Typing
5
+ module Tree
6
+ class InterpolationText < Base
7
+ include LiteralInferable
8
+
9
+ # @!method node
10
+ # @return [AST::InterpolationTextNode]
11
+
12
+ # @return [Types::Type]
13
+ def infer_type
14
+ node.children.each { |node| infer_child(node) }
15
+
16
+ infer_literal(node)
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,44 +1,16 @@
1
+ require 'yoda/typing/tree/literal_inferable'
2
+
1
3
  module Yoda
2
4
  module Typing
3
5
  module Tree
4
6
  class Literal < Base
5
- def type
6
- type_for_literal_sexp(node.type)
7
- end
7
+ include LiteralInferable
8
+
9
+ # @!method node
10
+ # @return [AST::LiteralNode, AST::Node]
8
11
 
9
- # @param sexp_type [::Symbol, nil]
10
- # @return [Types::Base]
11
- def type_for_literal_sexp(sexp_type)
12
- case sexp_type
13
- when :dstr, :str, :xstr, :string
14
- generator.string_type
15
- when :dsym, :sym
16
- generator.symbol_type
17
- when :array, :splat
18
- generator.array_type
19
- when :hash
20
- generator.hash_type
21
- when :irange, :erange
22
- generator.range_type
23
- when :regexp
24
- generator.regexp_type
25
- when :true
26
- generator.true_type
27
- when :false
28
- generator.false_type
29
- when :nil
30
- generator.nil_type
31
- when :int
32
- generator.integer_type
33
- when :float
34
- generator.float_type
35
- when :complex
36
- generator.numeric_type
37
- when :rational
38
- generator.numeric_type
39
- else
40
- generator.any_type
41
- end
12
+ def infer_type
13
+ infer_literal(node)
42
14
  end
43
15
  end
44
16
  end
@@ -0,0 +1,48 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ module LiteralInferable
5
+ # @param node [AST::Vnode]
6
+ # @return [Types::Base]
7
+ def infer_literal(node)
8
+ case node.type
9
+ when :dstr, :xstr
10
+ generator.string_type
11
+ when :str, :string
12
+ generator.string_type(node.value.to_s)
13
+ when :dsym
14
+ generator.symbol_type
15
+ when :sym
16
+ generator.symbol_type(node.value.to_sym)
17
+ when :array, :splat
18
+ generator.array_type
19
+ when :hash
20
+ generator.hash_type
21
+ when :irange, :erange
22
+ generator.range_type
23
+ when :regexp
24
+ generator.regexp_type
25
+ when :true
26
+ generator.true_type
27
+ when :false
28
+ generator.false_type
29
+ when :nil
30
+ generator.nil_type
31
+ when :int
32
+ generator.integer_type(node.value.to_i)
33
+ when :float
34
+ generator.float_type
35
+ when :complex
36
+ generator.numeric_type
37
+ when :rational
38
+ generator.numeric_type
39
+ when :empty
40
+ generator.nil_type
41
+ else
42
+ generator.any_type
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,15 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class LocalExit < Base
5
+ # @!method node
6
+ # @return [AST::SpecialCallNode]
7
+
8
+ def infer_type
9
+ # TODO
10
+ node.arguments[0] ? infer_child(node.arguments[0]) : generator.nil_type
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -2,13 +2,13 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class LogicalAssignment < Base
5
- def children
6
- @children = node.children.map(&method(:build_child))
7
- end
5
+ # @!method node
6
+ # @return [AST::AssignmentNode]
8
7
 
9
- def type
8
+ # @return [Types::Type]
9
+ def infer_type
10
10
  # TODO
11
- infer(node.children.last)
11
+ infer_child(node.content)
12
12
  end
13
13
  end
14
14
  end
@@ -2,12 +2,13 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class LogicalOperator < Base
5
- def children
6
- @children = node.children.map(&method(:build_child))
7
- end
5
+ # @!method node
6
+ # @return [AST::LeftOperatorNode, AST::CenterOperatorNode]
8
7
 
9
- def type
10
- Types::Union.new(node.children.map { |node| infer(node) })
8
+ # @return [Types::Type]
9
+ def infer_type
10
+ # TODO
11
+ generator.union_type(*node.children.map { |node| infer_child(node) })
11
12
  end
12
13
  end
13
14
  end
@@ -0,0 +1,41 @@
1
+ require 'yoda/typing/tree/method_inferable'
2
+
3
+ module Yoda
4
+ module Typing
5
+ module Tree
6
+ class MethodDef < Base
7
+ include MethodInferable
8
+
9
+ # @!method node
10
+ # @return [AST::DefNode]
11
+
12
+ # @return [Types::Base]
13
+ def infer_type
14
+ infer_method_type(receiver_type: self_type)
15
+ end
16
+
17
+ # @return [Symbol]
18
+ def node_name
19
+ node.name
20
+ end
21
+
22
+ # @return [AST::ParametersNode]
23
+ def parameters_node
24
+ node.parameters
25
+ end
26
+
27
+ # @return [Types::Type]
28
+ def body_node
29
+ node.body
30
+ end
31
+
32
+ # @return [Types::Type]
33
+ def self_type
34
+ @self_type ||= begin
35
+ context.method_receiver
36
+ end
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,51 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ module MethodInferable
5
+ # @param receiver_type [Types::Type]
6
+ # @return [Types::Type]
7
+ def infer_method_type(receiver_type:)
8
+ value_resolve_context = generator.value_resolve_context(self_type: receiver_type)
9
+
10
+ method_candidates = receiver_type.value.select_method(node_name.to_s, visibility: %i(private protected public))
11
+ method_types = method_candidates.map(&:rbs_type).map { |type| value_resolve_context.wrap(type) }
12
+
13
+ # TODO: Support overloads
14
+ method_bind = method_types.reduce({}) do |all_bind, method_type|
15
+ bind = Inferencer::ParameterBinder.new(parameters_node.parameter).bind(type: method_type, generator: generator)
16
+ all_bind.merge(bind.to_h) { |_key, v1, v2| generator.union_type(v1, v2) }
17
+ end
18
+
19
+ Logger.trace("method_candidates: [#{method_candidates.join(', ')}]")
20
+ Logger.trace("bind arguments: #{method_bind.map { |key, value| [key, value.to_s] }.to_h }")
21
+
22
+ bind_method_definition(node: node, method_candidates: method_candidates)
23
+
24
+ method_context = context.derive_method_context(receiver_type: receiver_type, binds: method_bind)
25
+
26
+ infer_child(body_node, context: method_context)
27
+
28
+ generator.symbol_type(node_name.to_sym)
29
+ end
30
+
31
+ # @abstract
32
+ # @return [Symbol, string]
33
+ def node_name
34
+ fail NotImplementedError
35
+ end
36
+
37
+ # @abstract
38
+ # @return [AST::ParametersNode]
39
+ def parameters_node
40
+ fail NotImplementedError
41
+ end
42
+
43
+ # @abstract
44
+ # @return [AST::ParametersNode]
45
+ def body_node
46
+ fail NotImplementedError
47
+ end
48
+ end
49
+ end
50
+ end
51
+ end
@@ -1,29 +1,16 @@
1
+ require 'yoda/typing/tree/namespace_inferable'
2
+
1
3
  module Yoda
2
4
  module Typing
3
5
  module Tree
4
6
  class ModuleTree < Base
5
- def type
6
- infer_namespace_node(node)
7
- end
8
-
9
- # @param node [::AST::Node]
10
- # @return [Types::Base]
11
- def infer_namespace_node(node)
12
- case node.type
13
- when :module
14
- name_node, block_node = node.children
15
- when :class
16
- name_node, _, block_node = node.children
17
- end
18
- constant_resolver = ConstantResolver.new(context: context, node: name_node)
19
- type = constant_resolver.resolve_constant_type
20
- block_context = NamespaceContext.new(objects: [constant_resolver.constant], parent: context, registry: context.registry, receiver: type)
7
+ include NamespaceInferable
21
8
 
22
- if block_node
23
- derive(context: block_context).infer(block_node)
24
- end
9
+ # @!method node
10
+ # @return [AST::ModuleNode]
25
11
 
26
- type
12
+ def infer_type
13
+ infer_namespace
27
14
  end
28
15
  end
29
16
  end
@@ -2,17 +2,13 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class MultipleAssignment < Base
5
- def process
6
- process_bind(node.children[0], node.children[1])
7
- end
5
+ # @!method node
6
+ # @return [AST::AssignmentNode]
8
7
 
9
- # @param var [Symbol]
10
- # @param body_node [::AST::Node]
11
- # @return [Store::Types::Base]
12
- def process_bind(var, body_node)
13
- body_type = infer(body_node)
14
- context.environment.bind(var, body_type)
15
- body_type
8
+ # @return [Types::Type]
9
+ def infer_type
10
+ # TODO
11
+ infer_child(node.content)
16
12
  end
17
13
  end
18
14
  end
@@ -0,0 +1,20 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ module NamespaceInferable
5
+ # @!method node
6
+ # @return [AST::ModuleNode, AST::ClassNode]
7
+
8
+ # @return [Types::Type]
9
+ def infer_namespace
10
+ namespace_type = infer_child(node.receiver)
11
+
12
+ new_context = context.derive_class_context(class_type: namespace_type)
13
+ infer_child(node.body, context: new_context)
14
+
15
+ namespace_type
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -0,0 +1,18 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class Rescue < Base
5
+ # @!method node
6
+ # @return [AST::RescueNode]
7
+
8
+ # @return [Types::Base]
9
+ def infer_type
10
+ type = infer_child(node.body)
11
+ node.rescue_clauses.each { |rescue_clause| infer_child(rescue_clause) }
12
+ infer_child(node.else_clause)
13
+ type
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
@@ -0,0 +1,42 @@
1
+ module Yoda
2
+ module Typing
3
+ module Tree
4
+ class RescueClause < Base
5
+ # @!method node
6
+ # @return [AST::RescueClauseNode]
7
+
8
+ # @return [Types::Type]
9
+ def infer_type
10
+ binds = {}
11
+
12
+ exception_type = begin
13
+ if node.match_clause
14
+ case node.match_clause.type
15
+ when :array
16
+ generator.union_type(*node.match_clause.contents.map { |content| infer_child(content).instance_type })
17
+ when :empty
18
+ generator.standard_error_type
19
+ else
20
+ # Unexpected
21
+ generator.standard_error_type
22
+ end
23
+ else
24
+ generator.standard_error_type
25
+ end
26
+ end
27
+
28
+
29
+ if node.assignee
30
+ case node.assignee.type
31
+ when :lvasgn
32
+ binds[node.assignee.assignee.name] = exception_type
33
+ end
34
+ end
35
+
36
+ new_context = context.derive_block_context(binds: binds)
37
+ infer_child(node.body, context: new_context)
38
+ end
39
+ end
40
+ end
41
+ end
42
+ end
@@ -2,7 +2,8 @@ module Yoda
2
2
  module Typing
3
3
  module Tree
4
4
  class Self < Base
5
- def type
5
+ # @return [Types::Type]
6
+ def infer_type
6
7
  context.receiver
7
8
  end
8
9
  end