holistic-ruby 0.1.1 → 0.1.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/holistic/extensions/events.rb +9 -1
- data/lib/holistic/extensions/ruby/stdlib.rb +27 -13
- data/lib/holistic/language_server/requests/text_document/completion.rb +9 -7
- data/lib/holistic/language_server/requests/text_document/did_close.rb +1 -3
- data/lib/holistic/ruby/autocompletion/suggest.rb +32 -2
- data/lib/holistic/ruby/parser/constant_resolution.rb +54 -3
- data/lib/holistic/ruby/parser/live_editing/process_file_changed.rb +6 -3
- data/lib/holistic/ruby/parser/nesting_syntax.rb +1 -0
- data/lib/holistic/ruby/parser/program_visitor.rb +40 -24
- data/lib/holistic/ruby/parser.rb +8 -0
- data/lib/holistic/ruby/scope/kind.rb +6 -5
- data/lib/holistic/ruby/scope/record.rb +10 -6
- data/lib/holistic/ruby/type_inference/solve.rb +15 -4
- data/lib/holistic/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: abe4144d1f581c6151784152792604f799c0140d62c28f445f377f6039c40457
|
4
|
+
data.tar.gz: 6593b92046a8087f75c171280ae66401ff0bb1eb0f6dba9fa496df127bb39ee8
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: eb1f43eaa7f78c334da3f8d8f2fc782bfa662b94f8a5a6b5a8a24ab271cae26d62703bd722860dbecf637d9aae5d4595d1424257406d9d349f0d90a95ab702d4
|
7
|
+
data.tar.gz: f42ed13efc65779f8ef175c7127d03cf68bebd5df990a1744d714100efe639cad104b55592507d4737ecfa4d48e75d6b69da194a033f056740a16fde8bf3d65d
|
data/README.md
CHANGED
@@ -32,4 +32,4 @@
|
|
32
32
|
|
33
33
|
## Why is it a toy language server?
|
34
34
|
|
35
|
-
I use `holistic-ruby` on a daily basis in a
|
35
|
+
I use `holistic-ruby` on a daily basis while working in a fairly large Ruby codebase. It seems stable and speedy. But... I built it for myself and I'm the only one using it :smile:
|
@@ -5,6 +5,14 @@ class Holistic::Extensions::Events
|
|
5
5
|
resolve_method_call_known_scope: {
|
6
6
|
params: [:reference, :referenced_scope, :method_call_clue],
|
7
7
|
output: ::Holistic::Ruby::Scope::Record
|
8
|
+
},
|
9
|
+
class_scope_registered: {
|
10
|
+
params: [:class_scope, :location],
|
11
|
+
output: nil
|
12
|
+
},
|
13
|
+
lambda_scope_registered: {
|
14
|
+
params: [:lambda_scope, :location],
|
15
|
+
output: nil
|
8
16
|
}
|
9
17
|
}.freeze
|
10
18
|
|
@@ -30,7 +38,7 @@ class Holistic::Extensions::Events
|
|
30
38
|
|
31
39
|
result = @listeners[event].lazy.filter_map { |callback| callback.call(params) }.first
|
32
40
|
|
33
|
-
raise UnexpectedOutput, result if result.present? && !result.is_a?(expected_output)
|
41
|
+
raise UnexpectedOutput, result if expected_output.present? && result.present? && !result.is_a?(expected_output)
|
34
42
|
|
35
43
|
result
|
36
44
|
end
|
@@ -16,28 +16,42 @@ module Holistic::Extensions::Ruby
|
|
16
16
|
nil
|
17
17
|
end
|
18
18
|
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
19
|
+
RegisterClassConstructor = ->(application, params) do
|
20
|
+
class_scope, location = params[:class_scope], params[:location]
|
21
|
+
|
22
|
+
has_overridden_new_method = class_scope.children.find { _1.class_method? && _1.name == "new" }
|
23
|
+
|
24
|
+
unless has_overridden_new_method
|
25
|
+
::Holistic::Ruby::Scope::Register.call(
|
26
|
+
repository: application.scopes,
|
27
|
+
parent: class_scope,
|
28
|
+
kind: ::Holistic::Ruby::Scope::Kind::CLASS_METHOD,
|
29
|
+
name: "new",
|
30
|
+
location:
|
31
|
+
)
|
32
|
+
end
|
25
33
|
end
|
26
34
|
|
27
|
-
LAMBDA_METHODS = ["call", "curry"]
|
35
|
+
LAMBDA_METHODS = ["call", "curry"].freeze
|
28
36
|
|
29
|
-
|
30
|
-
|
37
|
+
RegisterLambdaMethods = ->(application, params) do
|
38
|
+
lambda_scope, location = params[:lambda_scope], params[:location]
|
31
39
|
|
32
|
-
|
33
|
-
|
40
|
+
LAMBDA_METHODS.each do |method_name|
|
41
|
+
::Holistic::Ruby::Scope::Register.call(
|
42
|
+
repository: application.scopes,
|
43
|
+
parent: lambda_scope,
|
44
|
+
kind: ::Holistic::Ruby::Scope::Kind::CLASS_METHOD,
|
45
|
+
name: method_name,
|
46
|
+
location:
|
47
|
+
)
|
34
48
|
end
|
35
49
|
end
|
36
50
|
|
37
51
|
def register(application)
|
38
52
|
application.extensions.bind(:resolve_method_call_known_scope, &ResolveClassConstructor.curry[application])
|
39
|
-
application.extensions.bind(:
|
40
|
-
application.extensions.bind(:
|
53
|
+
application.extensions.bind(:class_scope_registered, &RegisterClassConstructor.curry[application])
|
54
|
+
application.extensions.bind(:lambda_scope_registered, &RegisterLambdaMethods.curry[application])
|
41
55
|
end
|
42
56
|
end
|
43
57
|
end
|
@@ -19,10 +19,11 @@ module Holistic::LanguageServer
|
|
19
19
|
end
|
20
20
|
|
21
21
|
code = document.expand_code(cursor)
|
22
|
-
|
23
|
-
|
22
|
+
|
24
23
|
return request.respond_with(nil) if code.blank?
|
25
24
|
|
25
|
+
scope = request.application.scopes.find_inner_most_scope_by_cursor(cursor) || request.application.root_scope
|
26
|
+
|
26
27
|
suggestions = ::Holistic::Ruby::Autocompletion::Suggest.call(code:, scope:)
|
27
28
|
|
28
29
|
respond_with_suggestions(request, suggestions)
|
@@ -40,11 +41,12 @@ module Holistic::LanguageServer
|
|
40
41
|
|
41
42
|
module CompletionKind
|
42
43
|
FROM_SCOPE_TO_COMPLETION = {
|
43
|
-
::Holistic::Ruby::Scope::Kind::CLASS
|
44
|
-
::Holistic::Ruby::Scope::Kind::LAMBDA
|
45
|
-
::Holistic::Ruby::Scope::Kind::
|
46
|
-
::Holistic::Ruby::Scope::Kind::
|
47
|
-
::Holistic::Ruby::Scope::Kind::
|
44
|
+
::Holistic::Ruby::Scope::Kind::CLASS => Protocol::COMPLETION_ITEM_KIND_CLASS,
|
45
|
+
::Holistic::Ruby::Scope::Kind::LAMBDA => Protocol::COMPLETION_ITEM_KIND_FUNCTION,
|
46
|
+
::Holistic::Ruby::Scope::Kind::CLASS_METHOD => Protocol::COMPLETION_ITEM_KIND_METHOD,
|
47
|
+
::Holistic::Ruby::Scope::Kind::INSTANCE_METHOD => Protocol::COMPLETION_ITEM_KIND_METHOD,
|
48
|
+
::Holistic::Ruby::Scope::Kind::MODULE => Protocol::COMPLETION_ITEM_KIND_MODULE,
|
49
|
+
::Holistic::Ruby::Scope::Kind::ROOT => Protocol::COMPLETION_ITEM_KIND_MODULE
|
48
50
|
}.freeze
|
49
51
|
|
50
52
|
DEFAULT = Protocol::COMPLETION_ITEM_KIND_MODULE
|
@@ -7,9 +7,7 @@ module Holistic::LanguageServer
|
|
7
7
|
def call(request)
|
8
8
|
path = Format::FileUri.extract_path(request.message.param("textDocument", "uri"))
|
9
9
|
|
10
|
-
|
11
|
-
|
12
|
-
if unsaved_document.present?
|
10
|
+
request.application.unsaved_documents.find(path)&.then do |unsaved_document|
|
13
11
|
request.application.unsaved_documents.delete(path)
|
14
12
|
|
15
13
|
if unsaved_document.has_unsaved_changes?
|
@@ -13,12 +13,42 @@ module Holistic::Ruby::Autocompletion
|
|
13
13
|
lookup_scope = lookup_scope.parent until lookup_scope.root?
|
14
14
|
end
|
15
15
|
|
16
|
-
|
16
|
+
if code.include?(".")
|
17
|
+
suggest_methods_from_scope(code:, scope: lookup_scope)
|
18
|
+
else
|
19
|
+
suggest_namespaces_from_scope(code:, scope: lookup_scope)
|
20
|
+
end
|
17
21
|
end
|
18
22
|
|
19
23
|
private
|
20
24
|
|
21
|
-
NonMethods = ->(scope) { !scope
|
25
|
+
NonMethods = ->(scope) { !Methods[scope] }
|
26
|
+
Methods = ->(scope) { scope.instance_method? || scope.class_method? }
|
27
|
+
|
28
|
+
# Payment. <--
|
29
|
+
# Payment::Notifications. <--
|
30
|
+
# current_user.a
|
31
|
+
def suggest_methods_from_scope(code:, scope:)
|
32
|
+
suggestions = []
|
33
|
+
|
34
|
+
partial_namespaces = code.split(/(::|\.)/).compact_blank
|
35
|
+
method_to_autocomplete = partial_namespaces.pop.then { _1 == "." ? "" : _1 }
|
36
|
+
namespaces_to_resolve = partial_namespaces.reject { _1 == "::" || _1 == "." }
|
37
|
+
|
38
|
+
namespaces_to_resolve.each do |namespace_name|
|
39
|
+
scope = resolve_scope(name: namespace_name, from_scope: scope)
|
40
|
+
|
41
|
+
return suggestions if scope.nil?
|
42
|
+
end
|
43
|
+
|
44
|
+
scope.children.filter(&:class_method?).each do |method_scope|
|
45
|
+
if method_scope.name.start_with?(method_to_autocomplete)
|
46
|
+
suggestions << Suggestion.new(code: method_scope.name, kind: method_scope.kind)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
suggestions
|
51
|
+
end
|
22
52
|
|
23
53
|
def suggest_namespaces_from_scope(code:, scope:)
|
24
54
|
suggestions = []
|
@@ -2,12 +2,18 @@
|
|
2
2
|
|
3
3
|
module Holistic::Ruby::Parser
|
4
4
|
class ConstantResolution
|
5
|
-
|
5
|
+
module MethodRegistrationMode
|
6
|
+
INSTANCE_METHODS = :instance_methods
|
7
|
+
CLASS_METHODS = :class_methods
|
8
|
+
end
|
9
|
+
|
10
|
+
attr_reader :scope_repository, :scope, :method_registration_mode
|
6
11
|
|
7
12
|
def initialize(scope_repository:, root_scope:)
|
8
13
|
@scope_repository = scope_repository
|
9
14
|
@scope = root_scope
|
10
15
|
@constant_resolution_possibilities = ["::"]
|
16
|
+
@method_registration_mode = MethodRegistrationMode::INSTANCE_METHODS
|
11
17
|
end
|
12
18
|
|
13
19
|
def current
|
@@ -28,12 +34,17 @@ module Holistic::Ruby::Parser
|
|
28
34
|
)
|
29
35
|
end
|
30
36
|
|
37
|
+
registered_module_scope = @scope
|
38
|
+
|
31
39
|
@constant_resolution_possibilities.unshift(@scope.fully_qualified_name)
|
32
40
|
|
33
41
|
block.call
|
34
42
|
|
35
|
-
|
43
|
+
change_method_registration_mode_to_instance_methods!
|
36
44
|
@constant_resolution_possibilities.shift
|
45
|
+
@scope = starting_scope
|
46
|
+
|
47
|
+
registered_module_scope
|
37
48
|
end
|
38
49
|
|
39
50
|
def register_child_class(nesting:, location:, &block)
|
@@ -50,12 +61,52 @@ module Holistic::Ruby::Parser
|
|
50
61
|
)
|
51
62
|
end
|
52
63
|
|
64
|
+
registered_class_scope = @scope
|
65
|
+
|
53
66
|
@constant_resolution_possibilities.unshift(@scope.fully_qualified_name)
|
54
67
|
|
55
68
|
block.call
|
56
69
|
|
57
|
-
|
70
|
+
change_method_registration_mode_to_instance_methods!
|
58
71
|
@constant_resolution_possibilities.shift
|
72
|
+
@scope = starting_scope
|
73
|
+
|
74
|
+
registered_class_scope
|
75
|
+
end
|
76
|
+
|
77
|
+
def register_child_method(nesting:, location:, kind:, &block)
|
78
|
+
starting_scope = @scope
|
79
|
+
|
80
|
+
nesting.each do |name|
|
81
|
+
@scope =
|
82
|
+
::Holistic::Ruby::Scope::Register.call(
|
83
|
+
repository: @scope_repository,
|
84
|
+
parent: @scope,
|
85
|
+
kind:,
|
86
|
+
name:,
|
87
|
+
location:
|
88
|
+
)
|
89
|
+
end
|
90
|
+
|
91
|
+
registered_method_scope = @scope
|
92
|
+
|
93
|
+
block.call
|
94
|
+
|
95
|
+
@scope = starting_scope
|
96
|
+
|
97
|
+
registered_method_scope
|
98
|
+
end
|
99
|
+
|
100
|
+
def method_registration_class_methods?
|
101
|
+
method_registration_mode == MethodRegistrationMode::CLASS_METHODS
|
102
|
+
end
|
103
|
+
|
104
|
+
def change_method_registration_mode_to_class_methods!
|
105
|
+
@method_registration_mode = MethodRegistrationMode::CLASS_METHODS
|
106
|
+
end
|
107
|
+
|
108
|
+
def change_method_registration_mode_to_instance_methods!
|
109
|
+
@method_registration_mode = MethodRegistrationMode::INSTANCE_METHODS
|
59
110
|
end
|
60
111
|
end
|
61
112
|
end
|
@@ -5,7 +5,10 @@ module Holistic::Ruby::Parser
|
|
5
5
|
extend self
|
6
6
|
|
7
7
|
def call(application:, file:)
|
8
|
-
|
8
|
+
# TODO: do not build the AST twice
|
9
|
+
return unless HasValidSyntax[file:]
|
10
|
+
|
11
|
+
references_to_recalculate = identify_references_to_recalculate(application:, file:)
|
9
12
|
|
10
13
|
unregister_scopes_in_file(application:, file:)
|
11
14
|
unregsiter_references_in_file(application:, file:)
|
@@ -17,9 +20,9 @@ module Holistic::Ruby::Parser
|
|
17
20
|
|
18
21
|
private
|
19
22
|
|
20
|
-
def
|
23
|
+
def identify_references_to_recalculate(application:, file:)
|
21
24
|
# we need to reject references declared in the same because they're already going to be
|
22
|
-
#
|
25
|
+
# reparsed. If we don't do that, we'll end up with duplicated reference records.
|
23
26
|
|
24
27
|
application.references
|
25
28
|
.list_references_to_scopes_in_file(scopes: application.scopes, file_path: file.path)
|
@@ -14,6 +14,7 @@ module Holistic::Ruby::Parser
|
|
14
14
|
when ::SyntaxTree::Const then nesting_syntax << node.value
|
15
15
|
when ::SyntaxTree::VCall then append.(node.child_nodes.first)
|
16
16
|
when ::SyntaxTree::Ident then nesting_syntax << node.value
|
17
|
+
when ::SyntaxTree::Kw then nesting_syntax << node.value
|
17
18
|
when ::SyntaxTree::IVar then nesting_syntax << node.value
|
18
19
|
when ::SyntaxTree::Period then nesting_syntax << "."
|
19
20
|
when ::SyntaxTree::Paren then append.(node.child_nodes[1]) # node.child_nodes[0] is ::SyntaxTree::LParen
|
@@ -34,32 +34,43 @@ module Holistic::Ruby::Parser
|
|
34
34
|
nesting = NestingSyntax.build(declaration_node)
|
35
35
|
location = build_scope_location(declaration_node:, body_node:)
|
36
36
|
|
37
|
-
@constant_resolution.register_child_class(nesting:, location:) do
|
37
|
+
class_scope = @constant_resolution.register_child_class(nesting:, location:) do
|
38
38
|
visit(body_node)
|
39
39
|
end
|
40
|
+
|
41
|
+
@application.extensions.dispatch(:class_scope_registered, { class_scope:, location: })
|
42
|
+
end
|
43
|
+
|
44
|
+
def visit_command(node)
|
45
|
+
command_name_node, args_node = node.child_nodes
|
46
|
+
|
47
|
+
if command_name_node.value == "extend"
|
48
|
+
is_extending_self = args_node.child_nodes.size == 1 && NestingSyntax.build(args_node.child_nodes.first).to_s == "self"
|
49
|
+
|
50
|
+
@constant_resolution.change_method_registration_mode_to_class_methods! if is_extending_self
|
51
|
+
end
|
52
|
+
|
53
|
+
visit(args_node)
|
40
54
|
end
|
41
55
|
|
42
56
|
def visit_def(node)
|
43
57
|
instance_node, period_node, method_name_node, _params, body_node = node.child_nodes
|
44
58
|
|
45
|
-
|
46
|
-
if instance_node.present? && period_node.present?
|
47
|
-
instance_node.child_nodes.first.value + period_node.value + method_name_node.value
|
48
|
-
else
|
49
|
-
method_name_node.value
|
50
|
-
end
|
51
|
-
|
59
|
+
nesting = NestingSyntax.new(method_name_node.value)
|
52
60
|
location = build_scope_location(declaration_node: method_name_node, body_node:)
|
53
61
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
62
|
+
kind =
|
63
|
+
if instance_node.present? && instance_node.child_nodes.first.value == "self"
|
64
|
+
::Holistic::Ruby::Scope::Kind::CLASS_METHOD
|
65
|
+
elsif @constant_resolution.method_registration_class_methods?
|
66
|
+
::Holistic::Ruby::Scope::Kind::CLASS_METHOD
|
67
|
+
else
|
68
|
+
::Holistic::Ruby::Scope::Kind::INSTANCE_METHOD
|
69
|
+
end
|
61
70
|
|
62
|
-
|
71
|
+
@constant_resolution.register_child_method(nesting:, location:, kind:) do
|
72
|
+
visit(body_node)
|
73
|
+
end
|
63
74
|
end
|
64
75
|
|
65
76
|
def visit_vcall(node)
|
@@ -128,22 +139,27 @@ module Holistic::Ruby::Parser
|
|
128
139
|
nesting = NestingSyntax.build(assign_node)
|
129
140
|
location = build_scope_location(declaration_node: assign_node, body_node: block_node)
|
130
141
|
|
131
|
-
@constant_resolution.register_child_class(nesting:, location:) do
|
142
|
+
class_scope = @constant_resolution.register_child_class(nesting:, location:) do
|
132
143
|
visit(block_node)
|
133
144
|
end
|
134
145
|
|
146
|
+
@application.extensions.dispatch(:class_scope_registered, { class_scope:, location: })
|
147
|
+
|
135
148
|
return
|
136
149
|
end
|
137
150
|
|
138
151
|
location = build_scope_location(declaration_node: assign_node, body_node:)
|
139
152
|
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
153
|
+
lambda_scope =
|
154
|
+
::Holistic::Ruby::Scope::Register.call(
|
155
|
+
repository: @application.scopes,
|
156
|
+
parent: @constant_resolution.scope,
|
157
|
+
kind: ::Holistic::Ruby::Scope::Kind::LAMBDA,
|
158
|
+
name: assign_node.child_nodes.first.value,
|
159
|
+
location:
|
160
|
+
)
|
161
|
+
|
162
|
+
@application.extensions.dispatch(:lambda_scope_registered, { lambda_scope:, location: })
|
147
163
|
|
148
164
|
visit(body_node)
|
149
165
|
end
|
data/lib/holistic/ruby/parser.rb
CHANGED
@@ -1,6 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Holistic::Ruby::Parser
|
4
|
+
HasValidSyntax = ->(file:) do
|
5
|
+
::SyntaxTree.parse(file.read)
|
6
|
+
|
7
|
+
true
|
8
|
+
rescue ::SyntaxTree::Parser::ParseError
|
9
|
+
false
|
10
|
+
end
|
11
|
+
|
4
12
|
ParseFile = ->(application:, file:) do
|
5
13
|
program = ::SyntaxTree.parse(file.read)
|
6
14
|
|
@@ -2,10 +2,11 @@
|
|
2
2
|
|
3
3
|
module Holistic::Ruby::Scope
|
4
4
|
module Kind
|
5
|
-
ROOT
|
6
|
-
MODULE
|
7
|
-
CLASS
|
8
|
-
|
9
|
-
|
5
|
+
ROOT = :root
|
6
|
+
MODULE = :module
|
7
|
+
CLASS = :class
|
8
|
+
INSTANCE_METHOD = :instance_method
|
9
|
+
CLASS_METHOD = :class_method
|
10
|
+
LAMBDA = :lambda
|
10
11
|
end
|
11
12
|
end
|
@@ -16,10 +16,10 @@ module Holistic::Ruby::Scope
|
|
16
16
|
return "" if root?
|
17
17
|
|
18
18
|
separator =
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
19
|
+
case kind
|
20
|
+
when Kind::INSTANCE_METHOD then "#"
|
21
|
+
when Kind::CLASS_METHOD then "."
|
22
|
+
else "::"
|
23
23
|
end
|
24
24
|
|
25
25
|
"#{parent.fully_qualified_name}#{separator}#{name}"
|
@@ -41,8 +41,12 @@ module Holistic::Ruby::Scope
|
|
41
41
|
kind == Kind::MODULE
|
42
42
|
end
|
43
43
|
|
44
|
-
def
|
45
|
-
kind == Kind::
|
44
|
+
def instance_method?
|
45
|
+
kind == Kind::INSTANCE_METHOD
|
46
|
+
end
|
47
|
+
|
48
|
+
def class_method?
|
49
|
+
kind == Kind::CLASS_METHOD
|
46
50
|
end
|
47
51
|
|
48
52
|
def descendant?(other)
|
@@ -37,7 +37,12 @@ module Holistic::Ruby::TypeInference
|
|
37
37
|
end
|
38
38
|
|
39
39
|
SolveMethodCallInCurrentScope = ->(application:, reference:, method_call_clue:) do
|
40
|
-
referenced_method =
|
40
|
+
referenced_method =
|
41
|
+
if reference.scope.class_method?
|
42
|
+
resolve_class_method(application:, scope: reference.scope.parent, method_name: method_call_clue.method_name)
|
43
|
+
elsif reference.scope.instance_method? && reference.scope.parent.present?
|
44
|
+
resolve_instance_method(application:, scope: reference.scope.parent, method_name: method_call_clue.method_name)
|
45
|
+
end
|
41
46
|
|
42
47
|
return if referenced_method.nil?
|
43
48
|
|
@@ -53,8 +58,8 @@ module Holistic::Ruby::TypeInference
|
|
53
58
|
|
54
59
|
return if referenced_scope.nil?
|
55
60
|
|
56
|
-
referenced_method =
|
57
|
-
referenced_method ||= application
|
61
|
+
referenced_method = application.extensions.dispatch(:resolve_method_call_known_scope, { reference:, referenced_scope:, method_call_clue: })
|
62
|
+
referenced_method ||= resolve_class_method(application:, scope: referenced_scope, method_name: method_call_clue.method_name)
|
58
63
|
|
59
64
|
Conclusion.done(referenced_method.fully_qualified_name) if referenced_method.present?
|
60
65
|
end
|
@@ -101,10 +106,16 @@ module Holistic::Ruby::TypeInference
|
|
101
106
|
nil
|
102
107
|
end
|
103
108
|
|
104
|
-
def
|
109
|
+
def resolve_instance_method(application:, scope:, method_name:)
|
105
110
|
method_fully_qualified_name = "#{scope.fully_qualified_name}##{method_name}"
|
106
111
|
|
107
112
|
application.scopes.find_by_fully_qualified_name(method_fully_qualified_name)
|
108
113
|
end
|
114
|
+
|
115
|
+
def resolve_class_method(application:, scope:, method_name:)
|
116
|
+
method_fully_qualified_name = "#{scope.fully_qualified_name}.#{method_name}"
|
117
|
+
|
118
|
+
application.scopes.find_by_fully_qualified_name(method_fully_qualified_name)
|
119
|
+
end
|
109
120
|
end
|
110
121
|
end
|
data/lib/holistic/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: holistic-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.4
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Luiz Vasconcellos
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2023-08-
|
11
|
+
date: 2023-08-20 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: syntax_tree
|