yoda-language-server 0.8.0 → 0.10.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +18 -0
- data/README.md +22 -27
- data/client/vscode/README.md +17 -2
- data/client/vscode/package-lock.json +908 -817
- data/client/vscode/package.json +17 -7
- data/client/vscode/src/check-versions.ts +49 -0
- data/client/vscode/src/config.ts +8 -1
- data/client/vscode/src/extension.ts +4 -3
- data/client/vscode/src/install-tools.ts +56 -16
- data/client/vscode/src/language-server.ts +5 -0
- data/client/vscode/src/test/runTest.ts +1 -1
- data/client/vscode/src/test/suite/hover.test.ts +13 -25
- data/client/vscode/src/test/suite/index.ts +1 -2
- data/client/vscode/src/utils.ts +11 -0
- data/images/hover-method.png +0 -0
- data/images/method-complete.png +0 -0
- data/lib/yoda/cli/analyze_deps.rb +46 -25
- data/lib/yoda/id_mask.rb +84 -0
- data/lib/yoda/instrument.rb +7 -0
- data/lib/yoda/model/descriptions/require_path_description.rb +45 -0
- data/lib/yoda/model/descriptions.rb +1 -0
- data/lib/yoda/model/node_signatures/node.rb +9 -1
- data/lib/yoda/model/values/literal_value.rb +3 -0
- data/lib/yoda/parsing/location.rb +9 -0
- data/lib/yoda/server/concurrent_writer.rb +1 -1
- data/lib/yoda/server/lifecycle_handler.rb +101 -78
- data/lib/yoda/server/notifier.rb +2 -55
- data/lib/yoda/services/loadable_path_resolver.rb +40 -0
- data/lib/yoda/services.rb +1 -0
- data/lib/yoda/store/actions/read_project_files.rb +9 -7
- data/lib/yoda/store/adapters/gdbm_adapter/namespace_accessor.rb +1 -1
- data/lib/yoda/store/adapters/memory_adapter.rb +1 -1
- data/lib/yoda/store/objects/libraries_status.rb +1 -1
- data/lib/yoda/store/objects/library/core.rb +8 -0
- data/lib/yoda/store/objects/library/gem.rb +14 -3
- data/lib/yoda/store/objects/library/path_resolvable.rb +29 -0
- data/lib/yoda/store/objects/library/std.rb +9 -0
- data/lib/yoda/store/objects/library.rb +1 -0
- data/lib/yoda/store/objects/patch.rb +1 -1
- data/lib/yoda/store/objects/patch_set.rb +2 -2
- data/lib/yoda/store/project/dependency.rb +22 -4
- data/lib/yoda/store/project/file_finder.rb +20 -0
- data/lib/yoda/store/project.rb +2 -0
- data/lib/yoda/store/registry/cache.rb +2 -2
- data/lib/yoda/store/registry/composer.rb +9 -7
- data/lib/yoda/store/registry/index.rb +14 -10
- data/lib/yoda/store/registry/library_registry.rb +3 -1
- data/lib/yoda/store/registry.rb +1 -1
- data/lib/yoda/typing/constant_resolver/code_query.rb +25 -0
- data/lib/yoda/typing/constant_resolver/query.rb +12 -1
- data/lib/yoda/typing/constant_resolver.rb +13 -8
- data/lib/yoda/typing/inferencer/load_resolver.rb +37 -0
- data/lib/yoda/typing/inferencer/tracer.rb +32 -0
- data/lib/yoda/typing/inferencer.rb +3 -2
- data/lib/yoda/typing/node_info.rb +5 -0
- data/lib/yoda/typing/tree/{defined.rb → ask_defined.rb} +3 -2
- data/lib/yoda/typing/tree/base.rb +65 -20
- data/lib/yoda/typing/tree/begin.rb +5 -5
- data/lib/yoda/typing/tree/block_call.rb +26 -0
- data/lib/yoda/typing/tree/case.rb +8 -19
- data/lib/yoda/typing/tree/class_tree.rb +10 -18
- data/lib/yoda/typing/tree/conditional_loop.rb +15 -0
- data/lib/yoda/typing/tree/constant.rb +19 -0
- data/lib/yoda/typing/tree/constant_assignment.rb +2 -2
- data/lib/yoda/typing/tree/ensure.rb +17 -0
- data/lib/yoda/typing/tree/for.rb +7 -0
- data/lib/yoda/typing/tree/hash_tree.rb +32 -0
- data/lib/yoda/typing/tree/if.rb +10 -5
- data/lib/yoda/typing/tree/interpolation_text.rb +21 -0
- data/lib/yoda/typing/tree/literal.rb +8 -36
- data/lib/yoda/typing/tree/literal_inferable.rb +48 -0
- data/lib/yoda/typing/tree/local_exit.rb +15 -0
- data/lib/yoda/typing/tree/logical_assignment.rb +5 -5
- data/lib/yoda/typing/tree/logical_operator.rb +6 -5
- data/lib/yoda/typing/tree/method_def.rb +41 -0
- data/lib/yoda/typing/tree/method_inferable.rb +51 -0
- data/lib/yoda/typing/tree/module_tree.rb +7 -20
- data/lib/yoda/typing/tree/multiple_assignment.rb +6 -10
- data/lib/yoda/typing/tree/namespace_inferable.rb +20 -0
- data/lib/yoda/typing/tree/rescue.rb +18 -0
- data/lib/yoda/typing/tree/rescue_clause.rb +42 -0
- data/lib/yoda/typing/tree/self.rb +2 -1
- data/lib/yoda/typing/tree/send.rb +8 -60
- data/lib/yoda/typing/tree/send_inferable.rb +89 -0
- data/lib/yoda/typing/tree/singleton_class_tree.rb +24 -0
- data/lib/yoda/typing/tree/singleton_method_def.rb +41 -0
- data/lib/yoda/typing/tree/super.rb +9 -2
- data/lib/yoda/typing/tree/variable.rb +5 -10
- data/lib/yoda/typing/tree/variable_assignment.rb +11 -8
- data/lib/yoda/typing/tree/yield.rb +9 -2
- data/lib/yoda/typing/tree.rb +55 -22
- data/lib/yoda/typing.rb +1 -0
- data/lib/yoda/version.rb +1 -1
- data/lib/yoda.rb +1 -0
- data/yoda-language-server.gemspec +1 -1
- metadata +35 -18
- data/lib/yoda/typing/inferencer/ast_traverser.rb +0 -408
- data/lib/yoda/typing/tree/block.rb +0 -12
- data/lib/yoda/typing/tree/const.rb +0 -12
- data/lib/yoda/typing/tree/escape.rb +0 -12
- data/lib/yoda/typing/tree/hash_body.rb +0 -36
- data/lib/yoda/typing/tree/literal_with_interpolation.rb +0 -21
- data/lib/yoda/typing/tree/method.rb +0 -43
- data/lib/yoda/typing/tree/rescue_body.rb +0 -12
- data/lib/yoda/typing/tree/singleton_method.rb +0 -47
- data/lib/yoda/typing/tree/while.rb +0 -12
@@ -1,9 +1,12 @@
|
|
1
1
|
require 'concurrent'
|
2
|
+
require 'yoda/server/providers'
|
2
3
|
|
3
4
|
module Yoda
|
4
5
|
class Server
|
5
6
|
# Handle
|
6
7
|
class LifecycleHandler
|
8
|
+
include Providers::ReportableProgress
|
9
|
+
|
7
10
|
# @return [Session, nil]
|
8
11
|
attr_reader :session
|
9
12
|
|
@@ -41,83 +44,92 @@ module Yoda
|
|
41
44
|
|
42
45
|
# @param params [LanguageServer::Protocol::Interface::InitializeParams]
|
43
46
|
def handle_initialize(params)
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
47
|
+
in_progress(params, title: "Initializing Yoda") do |progress_reporter|
|
48
|
+
reporter = InitializationProgressReporter.new(progress_reporter)
|
49
|
+
|
50
|
+
subscriptions = {
|
51
|
+
initialization_progress: reporter.public_method(:notify_initialization_progress),
|
52
|
+
build_library_registry: reporter.public_method(:notify_build_library_registry),
|
53
|
+
}
|
54
|
+
|
55
|
+
Instrument.instance.hear(**subscriptions) do
|
56
|
+
@session = begin
|
57
|
+
if params[:workspace_folders]
|
58
|
+
workspace_folders = params[:workspace_folders].map { |hash| LanguageServer::Protocol::Interface::WorkspaceFolder.new(name: hash[:name], uri: hash[:uri]) }
|
59
|
+
Session.from_workspace_folders(workspace_folders)
|
60
|
+
elsif params[:root_uri]
|
61
|
+
Session.from_root_uri(params[:root_uri])
|
62
|
+
else
|
63
|
+
Session.new(workspaces: [])
|
64
|
+
end
|
53
65
|
end
|
54
|
-
end
|
55
66
|
|
56
|
-
|
67
|
+
send_warnings(@session.setup || [])
|
68
|
+
end
|
69
|
+
end
|
57
70
|
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
),
|
70
|
-
),
|
71
|
-
completion_provider: LanguageServer::Protocol::Interface::CompletionOptions.new(
|
72
|
-
resolve_provider: false,
|
73
|
-
trigger_characters: ['.', '@', '[', ':', '!', '<'],
|
71
|
+
LanguageServer::Protocol::Interface::InitializeResult.new(
|
72
|
+
server_info: {
|
73
|
+
name: "yoda",
|
74
|
+
version: Yoda::VERSION,
|
75
|
+
},
|
76
|
+
capabilities: LanguageServer::Protocol::Interface::ServerCapabilities.new(
|
77
|
+
text_document_sync: LanguageServer::Protocol::Interface::TextDocumentSyncOptions.new(
|
78
|
+
open_close: true,
|
79
|
+
change: LanguageServer::Protocol::Constant::TextDocumentSyncKind::FULL,
|
80
|
+
save: LanguageServer::Protocol::Interface::SaveOptions.new(
|
81
|
+
include_text: true,
|
74
82
|
),
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
83
|
+
),
|
84
|
+
completion_provider: LanguageServer::Protocol::Interface::CompletionOptions.new(
|
85
|
+
resolve_provider: false,
|
86
|
+
trigger_characters: ['.', '@', '[', ':', '!', '<'],
|
87
|
+
),
|
88
|
+
hover_provider: true,
|
89
|
+
definition_provider: true,
|
90
|
+
signature_help_provider: LanguageServer::Protocol::Interface::SignatureHelpOptions.new(
|
91
|
+
trigger_characters: ['(', ','],
|
92
|
+
),
|
93
|
+
workspace_symbol_provider: LanguageServer::Protocol::Interface::WorkspaceSymbolOptions.new(
|
94
|
+
work_done_progress: true,
|
95
|
+
),
|
96
|
+
workspace: {
|
97
|
+
workspaceFolders: LanguageServer::Protocol::Interface::WorkspaceFoldersServerCapabilities.new(
|
98
|
+
supported: true,
|
99
|
+
change_notifications: true,
|
82
100
|
),
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
didCreate: LanguageServer::Protocol::Interface::FileOperationRegistrationOptions.new(
|
90
|
-
filters: [
|
91
|
-
LanguageServer::Protocol::Interface::FileOperationFilter.new(
|
92
|
-
pattern: LanguageServer::Protocol::Interface::FileOperationPattern.new(
|
93
|
-
glob: "**/*",
|
94
|
-
),
|
101
|
+
fileOperations: {
|
102
|
+
didCreate: LanguageServer::Protocol::Interface::FileOperationRegistrationOptions.new(
|
103
|
+
filters: [
|
104
|
+
LanguageServer::Protocol::Interface::FileOperationFilter.new(
|
105
|
+
pattern: LanguageServer::Protocol::Interface::FileOperationPattern.new(
|
106
|
+
glob: "**/*",
|
95
107
|
),
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
108
|
+
),
|
109
|
+
],
|
110
|
+
),
|
111
|
+
didRename: LanguageServer::Protocol::Interface::FileOperationRegistrationOptions.new(
|
112
|
+
filters: [
|
113
|
+
LanguageServer::Protocol::Interface::FileOperationFilter.new(
|
114
|
+
pattern: LanguageServer::Protocol::Interface::FileOperationPattern.new(
|
115
|
+
glob: "**/*",
|
104
116
|
),
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
117
|
+
),
|
118
|
+
],
|
119
|
+
),
|
120
|
+
didDelete: LanguageServer::Protocol::Interface::FileOperationRegistrationOptions.new(
|
121
|
+
filters: [
|
122
|
+
LanguageServer::Protocol::Interface::FileOperationFilter.new(
|
123
|
+
pattern: LanguageServer::Protocol::Interface::FileOperationPattern.new(
|
124
|
+
glob: "**/*",
|
113
125
|
),
|
114
|
-
|
115
|
-
|
116
|
-
|
126
|
+
),
|
127
|
+
],
|
128
|
+
),
|
117
129
|
},
|
118
|
-
|
119
|
-
)
|
120
|
-
|
130
|
+
},
|
131
|
+
),
|
132
|
+
)
|
121
133
|
rescue => e
|
122
134
|
Logger.warn e.full_message
|
123
135
|
LanguageServer::Protocol::Interface::ResponseError.new(
|
@@ -206,18 +218,29 @@ module Yoda
|
|
206
218
|
EOS
|
207
219
|
end
|
208
220
|
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
221
|
+
class InitializationProgressReporter
|
222
|
+
# @return [Providers::ReportableProgress::ProgressReporter]
|
223
|
+
attr_reader :progress_reporter
|
224
|
+
|
225
|
+
# @param progress_reporter [Providers::ReportableProgress::ProgressReporter]
|
226
|
+
def initialize(progress_reporter)
|
227
|
+
@progress_reporter = progress_reporter
|
228
|
+
end
|
229
|
+
|
230
|
+
def notify_initialization_progress(phase: nil, message: nil, index:, length:)
|
231
|
+
if length && length > 0
|
232
|
+
percentage = (index || 0) * 100 / length
|
233
|
+
|
234
|
+
progress_reporter.report(message: message, percentage: percentage)
|
216
235
|
else
|
217
|
-
|
236
|
+
progress_reporter.report(message: message)
|
218
237
|
end
|
219
|
-
|
220
|
-
notifier.event(type: :initialization, phase: phase, message: message)
|
238
|
+
|
239
|
+
progress_reporter.notifier.event(type: :initialization, phase: phase, message: message)
|
240
|
+
end
|
241
|
+
|
242
|
+
def notify_build_library_registry(message: nil, name: nil, version: nil)
|
243
|
+
progress_reporter.report(message: message)
|
221
244
|
end
|
222
245
|
end
|
223
246
|
end
|
data/lib/yoda/server/notifier.rb
CHANGED
@@ -10,19 +10,18 @@ module Yoda
|
|
10
10
|
def busy(type:, id: nil)
|
11
11
|
failed = false
|
12
12
|
event(type: type, phase: :begin, id: id)
|
13
|
-
start_progress(id: id, title: type)
|
14
13
|
yield
|
15
14
|
rescue => e
|
16
15
|
Logger.warn(e.full_message)
|
17
16
|
failed = true
|
17
|
+
event(type: type, phage: :failed, id: id)
|
18
18
|
raise e
|
19
19
|
ensure
|
20
20
|
event(type: type, phase: :end, id: id)
|
21
|
-
failed ? cancel_progress(id: id) : done_progress(id: id)
|
22
21
|
end
|
23
22
|
|
24
23
|
# @param params [Hash]
|
25
|
-
def event(params)
|
24
|
+
def event(**params)
|
26
25
|
write(method: 'telemetry/event', params: params)
|
27
26
|
end
|
28
27
|
|
@@ -121,58 +120,6 @@ module Yoda
|
|
121
120
|
)
|
122
121
|
end
|
123
122
|
|
124
|
-
# @param id [String, Symbol]
|
125
|
-
# @param title [String]
|
126
|
-
# @param calcellable [Boolean]
|
127
|
-
# @param message [String, nil]
|
128
|
-
# @param percentage [Integer]
|
129
|
-
def start_progress(id:, title:, cancellable: false, message: nil, percentage: 0)
|
130
|
-
write(
|
131
|
-
method: 'window/progress/start',
|
132
|
-
params: {
|
133
|
-
id: id,
|
134
|
-
title: title,
|
135
|
-
calcellable: cancellable,
|
136
|
-
message: message,
|
137
|
-
percentage: percentage,
|
138
|
-
}
|
139
|
-
)
|
140
|
-
end
|
141
|
-
|
142
|
-
# @param id [String, Symbol]
|
143
|
-
# @param message [String, nil]
|
144
|
-
# @param percentage [Integer, nil]
|
145
|
-
def report_progress(id:, message: nil, percentage: nil)
|
146
|
-
write(
|
147
|
-
method: 'window/progress/report',
|
148
|
-
params: {
|
149
|
-
id: id,
|
150
|
-
message: message,
|
151
|
-
percentage: percentage,
|
152
|
-
}
|
153
|
-
)
|
154
|
-
end
|
155
|
-
|
156
|
-
# @param id [String, Symbol]
|
157
|
-
def done_progress(id:)
|
158
|
-
write(
|
159
|
-
method: 'window/progress/done',
|
160
|
-
params: {
|
161
|
-
id: id,
|
162
|
-
}
|
163
|
-
)
|
164
|
-
end
|
165
|
-
|
166
|
-
# @param id [String, Symbol]
|
167
|
-
def cancel_progress(id:)
|
168
|
-
write(
|
169
|
-
method: 'window/progress/cancel',
|
170
|
-
params: {
|
171
|
-
id: id,
|
172
|
-
}
|
173
|
-
)
|
174
|
-
end
|
175
|
-
|
176
123
|
private
|
177
124
|
|
178
125
|
def write(params)
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module Yoda
|
2
|
+
module Services
|
3
|
+
class LoadablePathResolver
|
4
|
+
def initialize
|
5
|
+
end
|
6
|
+
|
7
|
+
# @param base_paths [Array<String>]
|
8
|
+
# @param pattern [String]
|
9
|
+
# @return [String, nil]
|
10
|
+
def find_loadable_path(base_paths, pattern)
|
11
|
+
# TODO: Support absolute path
|
12
|
+
return nil if absolute_path?(pattern)
|
13
|
+
return nil if pattern.start_with?("~/")
|
14
|
+
return nil if pattern.start_with?("./")
|
15
|
+
return nil if pattern.start_with?("../")
|
16
|
+
|
17
|
+
base_paths.each do |base_path|
|
18
|
+
path = File.join(base_path, pattern)
|
19
|
+
|
20
|
+
if File.extname(path).empty?
|
21
|
+
paths_with_suffix = ::Gem.suffixes.map { |suffix| path + suffix }
|
22
|
+
matched_path = paths_with_suffix.find { |path| File.file?(path) }
|
23
|
+
return matched_path if matched_path
|
24
|
+
else
|
25
|
+
return path if File.file?(path)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
return nil
|
30
|
+
end
|
31
|
+
|
32
|
+
# This is a workaround for Ruby 2.6 (This version does not have `File.absolute_path?`)
|
33
|
+
# @param path [String]
|
34
|
+
# @return [Boolean]
|
35
|
+
def absolute_path?(path)
|
36
|
+
path[0] == "/"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/lib/yoda/services.rb
CHANGED
@@ -2,21 +2,23 @@ module Yoda
|
|
2
2
|
module Store
|
3
3
|
module Actions
|
4
4
|
class ReadProjectFiles
|
5
|
+
# @return [Project]
|
6
|
+
attr_reader :project
|
7
|
+
|
5
8
|
# @return [Registry]
|
6
9
|
attr_reader :registry
|
7
10
|
|
8
|
-
# @return [String]
|
9
|
-
attr_reader :root_path
|
10
|
-
|
11
11
|
# @param project [Project]
|
12
12
|
# @return [ReadProjectFiles]
|
13
13
|
def self.for_project(project)
|
14
|
-
new(project
|
14
|
+
new(project, project.registry)
|
15
15
|
end
|
16
16
|
|
17
|
-
|
17
|
+
# @param project [Project]
|
18
|
+
# @param registry [Project]
|
19
|
+
def initialize(project, registry)
|
20
|
+
@project = project
|
18
21
|
@registry = registry
|
19
|
-
@root_path = root_path
|
20
22
|
end
|
21
23
|
|
22
24
|
def run
|
@@ -35,7 +37,7 @@ module Yoda
|
|
35
37
|
|
36
38
|
# @return [Array<String>]
|
37
39
|
def project_files
|
38
|
-
|
40
|
+
project.project_source_paths
|
39
41
|
end
|
40
42
|
end
|
41
43
|
end
|
@@ -10,7 +10,7 @@ module Yoda
|
|
10
10
|
# @param dependency [Project::Dependency]
|
11
11
|
# @return [Array<Object::Library::Core, Object::Library::Std, Object::Library::Gem>]
|
12
12
|
def self.libraies_from_dependency(dependency)
|
13
|
-
[dependency.core, dependency.std, *dependency.
|
13
|
+
[dependency.core, dependency.std, *dependency.autoload_gems.select(&:installed?)]
|
14
14
|
end
|
15
15
|
|
16
16
|
# @param libraries [Array<Library::Core, Library::Std, Library::Gem>]
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'yoda/store/objects/library/path_resolvable'
|
2
|
+
|
1
3
|
module Yoda
|
2
4
|
module Store
|
3
5
|
module Objects
|
@@ -42,6 +44,7 @@ module Yoda
|
|
42
44
|
class Connected
|
43
45
|
extend ConnectedDelegation
|
44
46
|
include WithRegistry
|
47
|
+
include PathResolvable
|
45
48
|
|
46
49
|
delegate_to_object :version
|
47
50
|
delegate_to_object :id, :name, :doc_path, :to_h, :with_project_connection
|
@@ -64,6 +67,11 @@ module Yoda
|
|
64
67
|
def registry_path
|
65
68
|
VersionStore.for_current_version.registry_path_for_core
|
66
69
|
end
|
70
|
+
|
71
|
+
# @return [Array<String>]
|
72
|
+
def require_paths
|
73
|
+
[]
|
74
|
+
end
|
67
75
|
end
|
68
76
|
end
|
69
77
|
end
|
@@ -1,18 +1,24 @@
|
|
1
|
+
require 'yoda/store/objects/library/path_resolvable'
|
2
|
+
|
1
3
|
module Yoda
|
2
4
|
module Store
|
3
5
|
module Objects
|
4
6
|
module Library
|
5
7
|
class Gem
|
6
8
|
include Serializable
|
9
|
+
include PathResolvable
|
7
10
|
|
8
11
|
# @return [String]
|
9
12
|
attr_reader :name, :version, :source_path, :full_gem_path, :doc_dir
|
10
13
|
|
14
|
+
# @return [Array<String>]
|
15
|
+
attr_reader :require_paths
|
16
|
+
|
11
17
|
# @return [Symbol, nil]
|
12
18
|
attr_reader :source_type
|
13
19
|
|
14
20
|
class << self
|
15
|
-
# @param spec [Bundler::LazySpecification]
|
21
|
+
# @param spec [Bundler::LazySpecification, Gem::Specification]
|
16
22
|
def from_gem_spec(spec)
|
17
23
|
if spec.respond_to?(:full_gem_path)
|
18
24
|
# Installed
|
@@ -20,6 +26,7 @@ module Yoda
|
|
20
26
|
name: spec.name,
|
21
27
|
version: spec.version.version,
|
22
28
|
source_path: spec.source.respond_to?(:path) ? spec.source.path : nil,
|
29
|
+
require_paths: spec.full_require_paths,
|
23
30
|
full_gem_path: spec.full_gem_path,
|
24
31
|
doc_dir: spec.doc_dir,
|
25
32
|
source_type: source_type_of(spec.source),
|
@@ -30,6 +37,7 @@ module Yoda
|
|
30
37
|
name: spec.name,
|
31
38
|
version: spec.version.version,
|
32
39
|
source_path: nil,
|
40
|
+
require_paths: [],
|
33
41
|
full_gem_path: nil,
|
34
42
|
doc_dir: nil,
|
35
43
|
source_type: nil,
|
@@ -57,11 +65,12 @@ module Yoda
|
|
57
65
|
end
|
58
66
|
end
|
59
67
|
|
60
|
-
def initialize(name:, version:, source_path:, full_gem_path:, doc_dir:, source_type:)
|
68
|
+
def initialize(name:, version:, source_path:, full_gem_path:, require_paths:, doc_dir:, source_type:)
|
61
69
|
@name = name
|
62
70
|
@version = version
|
63
71
|
@source_path = source_path
|
64
72
|
@full_gem_path = full_gem_path
|
73
|
+
@require_paths = require_paths
|
65
74
|
@doc_dir = doc_dir
|
66
75
|
@source_type = source_type&.to_sym
|
67
76
|
end
|
@@ -80,6 +89,7 @@ module Yoda
|
|
80
89
|
version: version,
|
81
90
|
source_path: source_path,
|
82
91
|
full_gem_path: full_gem_path,
|
92
|
+
require_paths: require_paths,
|
83
93
|
doc_dir: doc_dir,
|
84
94
|
source_type: source_type,
|
85
95
|
}
|
@@ -103,9 +113,10 @@ module Yoda
|
|
103
113
|
extend ConnectedDelegation
|
104
114
|
include WithRegistry
|
105
115
|
|
106
|
-
delegate_to_object :name, :version, :source_path, :full_gem_path, :doc_dir, :source_type
|
116
|
+
delegate_to_object :name, :version, :source_path, :full_gem_path, :doc_dir, :source_type, :require_paths
|
107
117
|
delegate_to_object :id, :local?, :to_h, :installed?, :managed_by_rubygems?, :with_project_connection
|
108
118
|
delegate_to_object :hash, :eql?, :==, :to_json, :derive
|
119
|
+
delegate_to_object :contain_requirable_file?, :find_requirable_file
|
109
120
|
|
110
121
|
# @return [Gem]
|
111
122
|
attr_reader :object
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'yoda/store/objects/library/path_resolvable'
|
2
|
+
|
3
|
+
module Yoda
|
4
|
+
module Store
|
5
|
+
module Objects
|
6
|
+
module Library
|
7
|
+
module PathResolvable
|
8
|
+
# @abstract
|
9
|
+
# @return [Array<String>]
|
10
|
+
def require_paths
|
11
|
+
fail NotImplementedError
|
12
|
+
end
|
13
|
+
|
14
|
+
# @param relative_path [String]
|
15
|
+
# @return [Boolean]
|
16
|
+
def contain_requirable_file?(relative_path)
|
17
|
+
!!find_requirable_file(relative_path)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @param relative_path [String]
|
21
|
+
# @return [String, nil]
|
22
|
+
def find_requirable_file(relative_path)
|
23
|
+
Services::LoadablePathResolver.new.find_loadable_path(require_paths, relative_path)
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'yoda/store/objects/library/path_resolvable'
|
2
|
+
|
1
3
|
module Yoda
|
2
4
|
module Store
|
3
5
|
module Objects
|
@@ -42,6 +44,7 @@ module Yoda
|
|
42
44
|
class Connected
|
43
45
|
extend ConnectedDelegation
|
44
46
|
include WithRegistry
|
47
|
+
include PathResolvable
|
45
48
|
|
46
49
|
delegate_to_object :version
|
47
50
|
delegate_to_object :id, :name, :doc_path, :to_h, :with_project_connection
|
@@ -64,6 +67,12 @@ module Yoda
|
|
64
67
|
def registry_path
|
65
68
|
VersionStore.for_current_version.registry_path_for_stdlib
|
66
69
|
end
|
70
|
+
|
71
|
+
# @return [Array<String>]
|
72
|
+
def require_paths
|
73
|
+
# TODO: Calculate from registry
|
74
|
+
[File.join(VersionStore.for_current_version.ruby_source_path, "lib/")]
|
75
|
+
end
|
67
76
|
end
|
68
77
|
end
|
69
78
|
end
|
@@ -13,7 +13,7 @@ module Yoda
|
|
13
13
|
|
14
14
|
# @param address [Symbol]
|
15
15
|
# @return [Set<Symbol>]
|
16
|
-
def get(address)
|
16
|
+
def get(address, **)
|
17
17
|
index[address] ||= Set.new
|
18
18
|
end
|
19
19
|
|
@@ -73,7 +73,7 @@ module Yoda
|
|
73
73
|
|
74
74
|
# @param address [String, Symbol]
|
75
75
|
# @return [Addressable, nil]
|
76
|
-
def find(address)
|
76
|
+
def find(address, **)
|
77
77
|
if (patches = get_patches(address)).empty?
|
78
78
|
nil
|
79
79
|
else
|
@@ -12,8 +12,13 @@ module Yoda
|
|
12
12
|
end
|
13
13
|
|
14
14
|
# @return [Array<Objects::Library::Gem>]
|
15
|
-
def
|
16
|
-
builder.
|
15
|
+
def loadable_gems
|
16
|
+
builder.loadable_gems
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [Array<Objects::Library::Gem>]
|
20
|
+
def autoload_gems
|
21
|
+
builder.autoload_gems
|
17
22
|
end
|
18
23
|
|
19
24
|
# @param name [String]
|
@@ -33,6 +38,7 @@ module Yoda
|
|
33
38
|
@std ||= Objects::Library.std
|
34
39
|
end
|
35
40
|
|
41
|
+
# @return [Builder]
|
36
42
|
def builder
|
37
43
|
@builder ||= Builder.new(project)
|
38
44
|
end
|
@@ -47,14 +53,21 @@ module Yoda
|
|
47
53
|
end
|
48
54
|
|
49
55
|
# @return [Array<Objects::Library::Gem>]
|
50
|
-
def
|
51
|
-
@
|
56
|
+
def loadable_gems
|
57
|
+
@loadable_gems ||= begin
|
52
58
|
dependencies
|
53
59
|
.map { |attrs| Objects::Library::Gem.new(**attrs) }
|
54
60
|
.reject { |spec| project.config.ignored_gems.include?(spec.name) }
|
55
61
|
end
|
56
62
|
end
|
57
63
|
|
64
|
+
# @return [Array<Objects::Library::Gem>]
|
65
|
+
def autoload_gems
|
66
|
+
@autoload_gems ||= begin
|
67
|
+
loadable_gems.select { |gem| autoload_dependency_ids.include?(gem.id) }
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
58
71
|
private
|
59
72
|
|
60
73
|
# @return [Array<Hash>]
|
@@ -62,6 +75,11 @@ module Yoda
|
|
62
75
|
analyzed_deps[:dependencies] || []
|
63
76
|
end
|
64
77
|
|
78
|
+
# @return [Array<String>]
|
79
|
+
def autoload_dependency_ids
|
80
|
+
analyzed_deps[:autoload_dependency_ids] || []
|
81
|
+
end
|
82
|
+
|
65
83
|
# @return [Hash]
|
66
84
|
def analyzed_deps
|
67
85
|
@analyzed_deps ||= begin
|