yoda-language-server 0.4.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 (171) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +78 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +85 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/client/atom/main.js +27 -0
  13. data/client/vscode/.gitignore +4 -0
  14. data/client/vscode/.vscode/launch.json +28 -0
  15. data/client/vscode/.vscode/settings.json +9 -0
  16. data/client/vscode/.vscode/tasks.json +20 -0
  17. data/client/vscode/.vscodeignore +8 -0
  18. data/client/vscode/CHANGELOG.md +7 -0
  19. data/client/vscode/README.md +65 -0
  20. data/client/vscode/package-lock.json +2688 -0
  21. data/client/vscode/package.json +39 -0
  22. data/client/vscode/src/extension.ts +42 -0
  23. data/client/vscode/src/test/extension.test.ts +22 -0
  24. data/client/vscode/src/test/index.ts +22 -0
  25. data/client/vscode/tsconfig.json +16 -0
  26. data/client/vscode/vsc-extension-quickstart.md +33 -0
  27. data/exe/yoda +27 -0
  28. data/lib/yoda.rb +11 -0
  29. data/lib/yoda/evaluation.rb +9 -0
  30. data/lib/yoda/evaluation/code_completion.rb +65 -0
  31. data/lib/yoda/evaluation/code_completion/base_provider.rb +57 -0
  32. data/lib/yoda/evaluation/code_completion/const_provider.rb +90 -0
  33. data/lib/yoda/evaluation/code_completion/method_provider.rb +82 -0
  34. data/lib/yoda/evaluation/code_completion/variable_provider.rb +18 -0
  35. data/lib/yoda/evaluation/comment_completion.rb +70 -0
  36. data/lib/yoda/evaluation/comment_completion/base_provider.rb +64 -0
  37. data/lib/yoda/evaluation/comment_completion/param_provider.rb +18 -0
  38. data/lib/yoda/evaluation/comment_completion/tag_provider.rb +41 -0
  39. data/lib/yoda/evaluation/comment_completion/type_provider.rb +58 -0
  40. data/lib/yoda/evaluation/current_node_explain.rb +70 -0
  41. data/lib/yoda/evaluation/evaluator.rb +103 -0
  42. data/lib/yoda/evaluation/signature_discovery.rb +83 -0
  43. data/lib/yoda/model.rb +12 -0
  44. data/lib/yoda/model/completion_item.rb +56 -0
  45. data/lib/yoda/model/descriptions.rb +10 -0
  46. data/lib/yoda/model/descriptions/base.rb +26 -0
  47. data/lib/yoda/model/descriptions/function_description.rb +40 -0
  48. data/lib/yoda/model/descriptions/value_description.rb +33 -0
  49. data/lib/yoda/model/descriptions/word_description.rb +32 -0
  50. data/lib/yoda/model/function_signatures.rb +13 -0
  51. data/lib/yoda/model/function_signatures/base.rb +68 -0
  52. data/lib/yoda/model/function_signatures/constructor.rb +70 -0
  53. data/lib/yoda/model/function_signatures/formatter.rb +82 -0
  54. data/lib/yoda/model/function_signatures/method.rb +67 -0
  55. data/lib/yoda/model/function_signatures/overload.rb +79 -0
  56. data/lib/yoda/model/function_signatures/parameter_list.rb +108 -0
  57. data/lib/yoda/model/function_signatures/type_builder.rb +101 -0
  58. data/lib/yoda/model/node_signature.rb +28 -0
  59. data/lib/yoda/model/path.rb +96 -0
  60. data/lib/yoda/model/scoped_path.rb +44 -0
  61. data/lib/yoda/model/types.rb +84 -0
  62. data/lib/yoda/model/types/any_type.rb +32 -0
  63. data/lib/yoda/model/types/base.rb +37 -0
  64. data/lib/yoda/model/types/duck_type.rb +41 -0
  65. data/lib/yoda/model/types/function_type.rb +174 -0
  66. data/lib/yoda/model/types/generic_type.rb +66 -0
  67. data/lib/yoda/model/types/instance_type.rb +42 -0
  68. data/lib/yoda/model/types/module_type.rb +42 -0
  69. data/lib/yoda/model/types/sequence_type.rb +53 -0
  70. data/lib/yoda/model/types/union_type.rb +56 -0
  71. data/lib/yoda/model/types/unknown_type.rb +40 -0
  72. data/lib/yoda/model/types/value_type.rb +58 -0
  73. data/lib/yoda/model/values.rb +9 -0
  74. data/lib/yoda/model/values/base.rb +32 -0
  75. data/lib/yoda/model/values/instance_value.rb +65 -0
  76. data/lib/yoda/model/values/module_value.rb +72 -0
  77. data/lib/yoda/parsing.rb +15 -0
  78. data/lib/yoda/parsing/ast_traversable.rb +18 -0
  79. data/lib/yoda/parsing/comment_tokenizer.rb +59 -0
  80. data/lib/yoda/parsing/location.rb +101 -0
  81. data/lib/yoda/parsing/node_objects.rb +10 -0
  82. data/lib/yoda/parsing/node_objects/const_node.rb +52 -0
  83. data/lib/yoda/parsing/node_objects/method_definition.rb +46 -0
  84. data/lib/yoda/parsing/node_objects/namespace.rb +104 -0
  85. data/lib/yoda/parsing/node_objects/send_node.rb +72 -0
  86. data/lib/yoda/parsing/parser.rb +27 -0
  87. data/lib/yoda/parsing/query.rb +11 -0
  88. data/lib/yoda/parsing/query/current_comment_query.rb +80 -0
  89. data/lib/yoda/parsing/query/current_comment_token_query.rb +153 -0
  90. data/lib/yoda/parsing/query/current_commenting_node_query.rb +68 -0
  91. data/lib/yoda/parsing/query/current_location_node_query.rb +51 -0
  92. data/lib/yoda/parsing/query/current_node_comment_query.rb +40 -0
  93. data/lib/yoda/parsing/range.rb +41 -0
  94. data/lib/yoda/parsing/scopes.rb +15 -0
  95. data/lib/yoda/parsing/scopes/base.rb +78 -0
  96. data/lib/yoda/parsing/scopes/builder.rb +60 -0
  97. data/lib/yoda/parsing/scopes/class_definition.rb +47 -0
  98. data/lib/yoda/parsing/scopes/meta_class_definition.rb +44 -0
  99. data/lib/yoda/parsing/scopes/meta_method_definition.rb +70 -0
  100. data/lib/yoda/parsing/scopes/method_definition.rb +69 -0
  101. data/lib/yoda/parsing/scopes/module_definition.rb +36 -0
  102. data/lib/yoda/parsing/scopes/root.rb +25 -0
  103. data/lib/yoda/parsing/source_analyzer.rb +59 -0
  104. data/lib/yoda/parsing/source_cutter.rb +231 -0
  105. data/lib/yoda/parsing/type_parser.rb +141 -0
  106. data/lib/yoda/runner.rb +6 -0
  107. data/lib/yoda/runner/infer.rb +50 -0
  108. data/lib/yoda/runner/setup.rb +26 -0
  109. data/lib/yoda/server.rb +191 -0
  110. data/lib/yoda/server/client_info.rb +98 -0
  111. data/lib/yoda/server/completion_provider.rb +78 -0
  112. data/lib/yoda/server/definition_provider.rb +36 -0
  113. data/lib/yoda/server/deserializer.rb +27 -0
  114. data/lib/yoda/server/hover_provider.rb +38 -0
  115. data/lib/yoda/server/signature_provider.rb +46 -0
  116. data/lib/yoda/store.rb +13 -0
  117. data/lib/yoda/store/actions.rb +10 -0
  118. data/lib/yoda/store/actions/import_core_library.rb +30 -0
  119. data/lib/yoda/store/actions/import_gems.rb +91 -0
  120. data/lib/yoda/store/actions/read_file.rb +36 -0
  121. data/lib/yoda/store/actions/read_project_files.rb +29 -0
  122. data/lib/yoda/store/adapters.rb +14 -0
  123. data/lib/yoda/store/adapters/base.rb +58 -0
  124. data/lib/yoda/store/adapters/leveldb_adapter.rb +80 -0
  125. data/lib/yoda/store/adapters/lmdb_adapter.rb +113 -0
  126. data/lib/yoda/store/objects.rb +46 -0
  127. data/lib/yoda/store/objects/addressable.rb +25 -0
  128. data/lib/yoda/store/objects/base.rb +116 -0
  129. data/lib/yoda/store/objects/class_object.rb +51 -0
  130. data/lib/yoda/store/objects/merger.rb +94 -0
  131. data/lib/yoda/store/objects/meta_class_object.rb +41 -0
  132. data/lib/yoda/store/objects/method_object.rb +94 -0
  133. data/lib/yoda/store/objects/module_object.rb +11 -0
  134. data/lib/yoda/store/objects/namespace_object.rb +67 -0
  135. data/lib/yoda/store/objects/overload.rb +51 -0
  136. data/lib/yoda/store/objects/patch.rb +46 -0
  137. data/lib/yoda/store/objects/patch_set.rb +80 -0
  138. data/lib/yoda/store/objects/tag.rb +62 -0
  139. data/lib/yoda/store/objects/value_object.rb +45 -0
  140. data/lib/yoda/store/project.rb +159 -0
  141. data/lib/yoda/store/query.rb +12 -0
  142. data/lib/yoda/store/query/associators.rb +10 -0
  143. data/lib/yoda/store/query/associators/associate_ancestors.rb +103 -0
  144. data/lib/yoda/store/query/associators/associate_methods.rb +38 -0
  145. data/lib/yoda/store/query/base.rb +16 -0
  146. data/lib/yoda/store/query/find_constant.rb +150 -0
  147. data/lib/yoda/store/query/find_meta_class.rb +18 -0
  148. data/lib/yoda/store/query/find_method.rb +74 -0
  149. data/lib/yoda/store/query/find_signature.rb +43 -0
  150. data/lib/yoda/store/registry.rb +67 -0
  151. data/lib/yoda/store/yard_importer.rb +260 -0
  152. data/lib/yoda/typing.rb +10 -0
  153. data/lib/yoda/typing/context.rb +96 -0
  154. data/lib/yoda/typing/environment.rb +35 -0
  155. data/lib/yoda/typing/evaluator.rb +256 -0
  156. data/lib/yoda/typing/lexical_scope.rb +26 -0
  157. data/lib/yoda/typing/relation.rb +15 -0
  158. data/lib/yoda/typing/traces.rb +9 -0
  159. data/lib/yoda/typing/traces/base.rb +26 -0
  160. data/lib/yoda/typing/traces/normal.rb +22 -0
  161. data/lib/yoda/typing/traces/send.rb +26 -0
  162. data/lib/yoda/version.rb +3 -0
  163. data/lib/yoda/yard_extensions.rb +11 -0
  164. data/lib/yoda/yard_extensions/sig_directive.rb +40 -0
  165. data/lib/yoda/yard_extensions/type_tag.rb +10 -0
  166. data/package.json +76 -0
  167. data/scripts/benchmark.rb +6 -0
  168. data/scripts/build_core_index.sh +16 -0
  169. data/yarn.lock +13 -0
  170. data/yoda-language-server.gemspec +40 -0
  171. metadata +424 -0
@@ -0,0 +1,10 @@
1
+ module Yoda
2
+ module Typing
3
+ require 'yoda/typing/context'
4
+ require 'yoda/typing/environment'
5
+ require 'yoda/typing/evaluator'
6
+ require 'yoda/typing/relation'
7
+ require 'yoda/typing/traces'
8
+ require 'yoda/typing/lexical_scope'
9
+ end
10
+ end
@@ -0,0 +1,96 @@
1
+ require 'set'
2
+
3
+ module Yoda
4
+ module Typing
5
+ class Context
6
+ # @return [Store::Registry]
7
+ attr_reader :registry
8
+
9
+ # @return [Store::Objects::Base]
10
+ attr_reader :caller_object
11
+
12
+ # @return [LexicalScope]
13
+ attr_reader :lexical_scope
14
+
15
+ # @return [Environment]
16
+ attr_reader :env
17
+
18
+ # @return [TraceStore]
19
+ attr_reader :trace_store
20
+
21
+ # @param registry [Store::Registry]
22
+ # @param caller_object [Store::Objects::Base] represents who is the evaluator of the code.
23
+ # @param lexical_scope [Array<Path>] represents where the code presents.
24
+ def initialize(registry:, caller_object:, lexical_scope:, env: Environment.new, parent: nil, trace_store: TraceStore.new)
25
+ fail ArgumentError, registry unless registry.is_a?(Store::Registry)
26
+ fail ArgumentError, caller_object unless caller_object.is_a?(Store::Objects::Base)
27
+ fail ArgumentError, lexical_scope unless lexical_scope.is_a?(LexicalScope)
28
+
29
+ @registry = registry
30
+ @caller_object = caller_object
31
+ @lexical_scope = lexical_scope
32
+ @env = env
33
+ @trace_store = trace_store
34
+ end
35
+
36
+ # @param registry [Store::Registry]
37
+ # @param caller_object [Store::Objects::Base] represents who is the evaluator of the code.
38
+ # @param lexical_scope [Array<Path>] represents where the code presents.
39
+ # @return [self]
40
+ def derive(caller_object: self.caller_object, lexical_scope: self.lexical_scope)
41
+ self.class.new(registry: registry, caller_object: caller_object, lexical_scope: lexical_scope, parent: self, trace_store: trace_store)
42
+ end
43
+
44
+ # @param node [::AST::Node]
45
+ # @return [Trace::Base, nil]
46
+ def find_trace(node)
47
+ trace_store.find_trace(node)
48
+ end
49
+
50
+ # @param node [::AST::Node]
51
+ # @param trace [Trace::Base]
52
+ def bind_trace(node, trace)
53
+ trace_store.bind_trace(node, trace)
54
+ end
55
+
56
+ class TraceStore
57
+ def initialize
58
+ @traces = {}
59
+ end
60
+
61
+ # @param node [::AST::Node]
62
+ # @return [Trace::Base, nil]
63
+ def find_trace(node)
64
+ @traces[node.is_a?(::Parser::AST::Node) ? ParserNodeWrapper.new(node) : node]
65
+ end
66
+
67
+ # @param node [::AST::Node]
68
+ # @param trace [Trace::Base]
69
+ def bind_trace(node, trace)
70
+ @traces[node.is_a?(::Parser::AST::Node) ? ParserNodeWrapper.new(node) : node] = trace
71
+ end
72
+
73
+ class ParserNodeWrapper
74
+ # @return [::Parser::AST::Node]
75
+ attr_reader :node
76
+
77
+ # @param node [::Parser::AST::Node]
78
+ def initialize(node)
79
+ @node = node
80
+ end
81
+
82
+ # @param another [Object]
83
+ def eql?(another)
84
+ another.is_a?(ParserNodeWrapper) &&
85
+ node == another.node &&
86
+ node.location == another.node.location
87
+ end
88
+
89
+ def hash
90
+ [node, node.location].hash
91
+ end
92
+ end
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,35 @@
1
+ require 'set'
2
+
3
+ module Yoda
4
+ module Typing
5
+ class Environment
6
+ def initialize
7
+ @binds = {}
8
+ end
9
+
10
+ # @param key [String, Symbol]
11
+ def resolve(key)
12
+ @binds[key.to_sym]
13
+ end
14
+
15
+ # @param key [String, Symbol]
16
+ # @param type [Symbol, Model::Types::Base]
17
+ def bind(key, type)
18
+ key = key.to_sym
19
+ type = (type.is_a?(Symbol) && resolve(type)) || type
20
+ @binds.transform_values! { |value| value == key ? type : value }
21
+ @binds[key] = type
22
+ self
23
+ end
24
+
25
+ # @param signature [Model::FunctionSignatures::Base]
26
+ # @return [self]
27
+ def bind_method_parameters(signature)
28
+ parameter_names = signature.parameters.parameter_names
29
+ parameter_names.each do |name|
30
+ bind(name.gsub(/:\Z/, ''), signature.parameter_type_of(name))
31
+ end
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,256 @@
1
+ module Yoda
2
+ module Typing
3
+ # Evaluator interpret codes abstractly and assumes types of terms.
4
+ class Evaluator
5
+ # @return [Context]
6
+ attr_reader :context
7
+
8
+ # @param context [Context]
9
+ def initialize(context)
10
+ @context = context
11
+ end
12
+
13
+ # @param node [::AST::Node]
14
+ # @return [Model::Types::Base]
15
+ def process(node)
16
+ evaluate(node).tap { |type| bind_trace(node, Traces::Normal.new(context, type)) unless find_trace(node) }
17
+ end
18
+
19
+ # @param node [::AST::Node]
20
+ # @param trace [Trace::Base]
21
+ def bind_trace(node, trace)
22
+ context.bind_trace(node, trace)
23
+ end
24
+
25
+ # @param node [::AST::Node]
26
+ # @return [Trace::Base, nil]
27
+ def find_trace(node)
28
+ context.find_trace(node)
29
+ end
30
+
31
+ private
32
+
33
+ # @param node [::AST::Node]
34
+ # @return [Model::Types::Base]
35
+ def evaluate(node)
36
+ case node.type
37
+ when :lvasgn, :ivasgn, :cvasgn, :gvasgn
38
+ evaluate_bind(node.children[0], process(node.children[1]))
39
+ when :casgn
40
+ # TODO
41
+ process(node.children.last)
42
+ when :masgn
43
+ # TODO
44
+ process(node.children.last)
45
+ when :op_asgn, :or_asgn, :and_asgn
46
+ # TODO
47
+ process(node.children.last)
48
+ when :and, :or, :not
49
+ # TODO
50
+ node.children.reduce(unknown_type) { |_type, node| process(node) }
51
+ when :if
52
+ evaluate_branch_nodes(node.children.slice(1..2).compact)
53
+ when :while, :until, :while_post, :until_post
54
+ # TODO
55
+ process(node.children[1])
56
+ when :for
57
+ # TODO
58
+ process(node.children[2])
59
+ when :case
60
+ evaluate_case_node(node)
61
+ when :super, :zsuper, :yield
62
+ # TODO
63
+ type_for_sexp_type(node.type)
64
+ when :return, :break, :next
65
+ # TODO
66
+ node.children[0] ? process(node.children[0]) : Model::Types::ValueType.new('nil')
67
+ when :resbody
68
+ # TODO
69
+ process(node.children[2])
70
+ when :csend, :send
71
+ evaluate_send_node(node)
72
+ when :block
73
+ evaluate_block_node(node)
74
+ when :const
75
+ const_node = Parsing::NodeObjects::ConstNode.new(node)
76
+ if const = context.lexical_scope.find_constant(context.registry, const_node.to_s)
77
+ Model::Types::ModuleType.new(const.path)
78
+ else
79
+ unknown_type
80
+ end
81
+ when :lvar, :cvar, :ivar, :gvar
82
+ env.resolve(node.children.first) || unknown_type
83
+ when :begin, :kwbegin, :block
84
+ node.children.reduce(unknown_type) { |_type, node| process(node) }
85
+ when :dstr, :dsym, :xstr
86
+ node.children.map { |node| process(node) }
87
+ type_for_sexp_type(node.type)
88
+ when :def
89
+ evaluate_method_definition(node)
90
+ when :defs
91
+ evaluate_smethod_definition(node)
92
+ when :hash
93
+ evaluate_hash_node(node)
94
+ else
95
+ type_for_sexp_type(node.type)
96
+ end
97
+ end
98
+
99
+ # @param node [Array<::AST::Node>]
100
+ # @return [Model::Types::Base]
101
+ def evaluate_branch_nodes(nodes)
102
+ Model::Types::UnionType.new(nodes.map { |node| process(node) })
103
+ end
104
+
105
+ # @param node [::AST::Node]
106
+ # @param env [Environment]
107
+ # @return [Model::Types::Base]
108
+ def evaluate_send_node(node)
109
+ receiver_node, method_name_sym, *argument_nodes = node.children
110
+ if receiver_node
111
+ receiver_type = process(receiver_node)
112
+ receiver_candidates = receiver_type.resolve(context.registry)
113
+ else
114
+ receiver_type = type_of_class(context.caller_object)
115
+ receiver_candidates = [context.caller_object]
116
+ end
117
+
118
+ _type = argument_nodes.reduce([unknown_type]) { |(_type), node| process(node) }
119
+ method_candidates = receiver_candidates.map { |receiver| Store::Query::FindSignature.new(context.registry).select(receiver, method_name_sym.to_s) }.flatten
120
+ return_type = Model::Types::UnionType.new(method_candidates.map(&:type).map(&:return_type)).map do |type|
121
+ type.is_a?(Model::Types::ValueType) && type.value == 'self' ? receiver_type : type
122
+ end
123
+ trace = Traces::Send.new(context, method_candidates, return_type)
124
+ bind_trace(node, trace)
125
+ trace.type
126
+ end
127
+
128
+ # @param node [Array<::AST::Node>]
129
+ # @return [Model::Types::Base]
130
+ def evaluate_hash_node(node)
131
+ node.children.each do |node|
132
+ case node.type
133
+ when :pair
134
+ node.children.each(&method(:process))
135
+ when :kwsplat
136
+ node.children.each(&method(:process))
137
+ end
138
+ end
139
+ Model::Types::InstanceType.new('::Hash')
140
+ end
141
+
142
+ # @param node [::AST::Node]
143
+ # @param env [Environment]
144
+ # @return [[Model::Types::Baseironment]]
145
+ def evaluate_block_node(node)
146
+ send_node, arguments_node, body_node = node.children
147
+ # TODO
148
+ _type = process(body_node)
149
+ process(send_node)
150
+ end
151
+
152
+ # @param node [::AST::Node]
153
+ # @param env [Environment]
154
+ # @return [[Model::Types::Baseironment]]
155
+ def evaluate_case_node(node)
156
+ # TODO
157
+ subject_node, *when_nodes, else_node = node.children
158
+ _when_types = when_nodes.map { |node| node.children.last && process(node.children.last) }.compact
159
+ process(else_node)
160
+ end
161
+
162
+ # @param node [::AST::Node]
163
+ # @param type [Model::Types::Base]
164
+ # @param env [Environment]
165
+ # @return [Model::Types::Base]
166
+ def evaluate_bind(symbol, type)
167
+ env.bind(symbol, type)
168
+ type
169
+ end
170
+
171
+ # @param sexp_type [::Symbol, nil]
172
+ def type_for_sexp_type(sexp_type)
173
+ case sexp_type
174
+ when :dstr, :str, :xstr, :string
175
+ Model::Types::InstanceType.new('::String')
176
+ when :dsym, :sym
177
+ Model::Types::InstanceType.new('::Symbol')
178
+ when :array, :splat
179
+ Model::Types::InstanceType.new('::Array')
180
+ when :irange, :erange
181
+ Model::Types::InstanceType.new('::Range')
182
+ when :regexp
183
+ Model::Types::InstanceType.new('::RegExp')
184
+ when :defined
185
+ boolean_type
186
+ when :self
187
+ type_of_class(context.caller_object)
188
+ when :true, :false, :nil
189
+ Model::Types::ValueType.new(sexp_type.to_s)
190
+ when :int, :float, :complex, :rational
191
+ Model::Types::InstanceType.new('::Numeric')
192
+ else
193
+ Model::Types::UnknownType.new(sexp_type)
194
+ end
195
+ end
196
+
197
+ # @param node [::AST::Node]
198
+ # @return [Model::Types::Base]
199
+ def evaluate_method_definition(node)
200
+ new_caller_object = context.lexical_scope.namespace
201
+ method_object = Store::Query::FindSignature.new(context.registry).select(new_caller_object, node.children[-3].to_s).first
202
+ new_context = context.derive(caller_object: new_caller_object)
203
+ new_context.env.bind_method_parameters(method_object)
204
+ self.class.new(new_context).process(node.children[-1])
205
+ end
206
+
207
+ # @param node [::AST::Node]
208
+ # @return [Model::Types::Base]
209
+ def evaluate_smethod_definition(node)
210
+ type = process(node.children[-4])
211
+ new_caller_object = type.resolve(context.registry).first
212
+ method_object = Store::Query::FindSignature.new(context.registry).select(new_caller_object, node.children[-3].to_s).first
213
+ new_context = context.derive(caller_object: new_caller_object)
214
+ if method_object
215
+ new_context.env.bind_method_parameters(method_object)
216
+ end
217
+ self.class.new(new_context).process(node.children[-1])
218
+ end
219
+
220
+ # @param object [Store::Objects::Base]
221
+ # @return [Model::Types::Base]
222
+ def type_of_class(object)
223
+ case object
224
+ when Store::Objects::ClassObject, Store::Objects::ModuleObject
225
+ Model::Types::InstanceType.new(object.path)
226
+ when Store::Objects::MetaClassObject
227
+ Model::Types::ModuleType.new(object.path)
228
+ else
229
+ Model::Types::UnknownType.new
230
+ end
231
+ end
232
+
233
+ def boolean_type
234
+ Model::Types::UnionType.new(Model::Types::ValueType.new('true'), Model::Types::ValueType.new('false'))
235
+ end
236
+
237
+ def unknown_type
238
+ Model::Types::UnknownType.new
239
+ end
240
+
241
+ # @return [Environment]
242
+ def env
243
+ context.env
244
+ end
245
+
246
+ # @param node [Array<::AST::Node>]
247
+ # @param env [Environment]
248
+ # @return [Array<Model::Values::Base>]
249
+ def process_to_instanciate(node)
250
+ type = evaluate(node)
251
+ bind_trace(node, Traces::Normal.new(context, type)) unless find_trace(node)
252
+ trace.values
253
+ end
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,26 @@
1
+ module Yoda
2
+ module Typing
3
+ class LexicalScope
4
+ # @return [Store::Objects::Base]
5
+ attr_reader :namespace
6
+
7
+ # @return [Array<Path>]
8
+ attr_reader :ancestor_paths
9
+
10
+ # @param namespace [Store::Objects::Base]
11
+ # @param ancestor_names [Array<Path>]
12
+ def initialize(namespace, ancestor_paths)
13
+ @namespace = namespace
14
+ @ancestor_paths = ancestor_paths
15
+ end
16
+
17
+ # @param registry [Store::Registry]
18
+ # @param constant_name [String]
19
+ # @return [Store::Objects::Base, nil]
20
+ def find_constant(registry, constant_name)
21
+ scoped_path = Model::ScopedPath.new(ancestor_paths, constant_name)
22
+ Store::Query::FindConstant.new(registry).find(scoped_path)
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,15 @@
1
+ module Yoda
2
+ module Typing
3
+ class Relation
4
+ attr_reader :left, :right, :op
5
+ # @param left [Symbol, Model::Types::Base]
6
+ # @param right [Symbol, Model::Types::Base]
7
+ # @param op [Symbol]
8
+ def initialize(left, right, op = :eq)
9
+ @left = left
10
+ @right = right
11
+ @op = op
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,9 @@
1
+ module Yoda
2
+ module Typing
3
+ module Traces
4
+ require 'yoda/typing/traces/base'
5
+ require 'yoda/typing/traces/normal'
6
+ require 'yoda/typing/traces/send'
7
+ end
8
+ end
9
+ end