yoda-language-server 0.9.0 → 0.10.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +5 -0
- data/client/vscode/package-lock.json +6 -6
- data/client/vscode/src/check-versions.ts +5 -11
- data/client/vscode/src/install-tools.ts +1 -1
- data/lib/yoda/cli/analyze_deps.rb +46 -25
- data/lib/yoda/id_mask.rb +84 -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/services/loadable_path_resolver.rb +33 -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 +1 -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
- metadata +25 -13
- 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
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: ac5417cb4b65a5825e8cbbafc5e7c2396dd676f8c9be6635b6ae9721a58d9d4e
|
4
|
+
data.tar.gz: 93c16d20eeef7a4af4483df0313814529adeefa8f0561e1fa96f72627730eb5a
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 57ab04ba88f6d0047c00ef4a0c92531ddc8a7966dcf10b93c16d01152ea62981bba5eb40d8a94dcaf1c6eea015f710fb44c5a1eca45bc40614b51c5f79325d9e
|
7
|
+
data.tar.gz: 7af4d13dd31562946ee5c3dd7e57e5c95b14450dce1b8ab8a9e1719a4b53067f384f069cb522b027158cca2407e9c47d84e86dcf604f940d3cea1cf47318a00d
|
data/CHANGELOG.md
CHANGED
@@ -1472,9 +1472,9 @@
|
|
1472
1472
|
}
|
1473
1473
|
},
|
1474
1474
|
"node_modules/minimist": {
|
1475
|
-
"version": "1.2.
|
1476
|
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.
|
1477
|
-
"integrity": "sha512-
|
1475
|
+
"version": "1.2.6",
|
1476
|
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
1477
|
+
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
1478
1478
|
"dev": true
|
1479
1479
|
},
|
1480
1480
|
"node_modules/mkdirp": {
|
@@ -3784,9 +3784,9 @@
|
|
3784
3784
|
}
|
3785
3785
|
},
|
3786
3786
|
"minimist": {
|
3787
|
-
"version": "1.2.
|
3788
|
-
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.
|
3789
|
-
"integrity": "sha512-
|
3787
|
+
"version": "1.2.6",
|
3788
|
+
"resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.6.tgz",
|
3789
|
+
"integrity": "sha512-Jsjnk4bw3YJqYzbdyBiNsPWHPfO++UGG749Cxs6peCu5Xg4nrena6OVxOYxrQTqww0Jmwt+Ref8rggumkTLz9Q==",
|
3790
3790
|
"dev": true
|
3791
3791
|
},
|
3792
3792
|
"mkdirp": {
|
@@ -10,8 +10,11 @@ interface CheckResult {
|
|
10
10
|
}
|
11
11
|
|
12
12
|
export async function checkVersions(): Promise<CheckResult> {
|
13
|
-
const { stdout } = await asyncExec("gem list --
|
14
|
-
const
|
13
|
+
const { stdout: localStdout } = await asyncExec("gem list --local --exact yoda-language-server")
|
14
|
+
const localVersion = extractVersion(localStdout)
|
15
|
+
|
16
|
+
const { stdout: remoteStdout } = await asyncExec("gem list --remote --no-prerelease --exact yoda-language-server")
|
17
|
+
const remoteVersion = extractVersion(remoteStdout)
|
15
18
|
|
16
19
|
return {
|
17
20
|
shouldUpdate: shouldUpdate(localVersion, remoteVersion),
|
@@ -32,15 +35,6 @@ function shouldUpdate(localVersion: string, remoteVersion: string): boolean {
|
|
32
35
|
return cmp(localVersion, "<", remoteVersion)
|
33
36
|
}
|
34
37
|
|
35
|
-
function parseGemList(stdout: string): [string, string] {
|
36
|
-
const [local, remote] = stdout.split("*** REMOTE GEMS ***")
|
37
|
-
|
38
|
-
const localVersion = extractVersion(local)
|
39
|
-
const remoteVersion = extractVersion(remote)
|
40
|
-
|
41
|
-
return [localVersion, remoteVersion]
|
42
|
-
}
|
43
|
-
|
44
38
|
function extractVersion(text: string): string {
|
45
39
|
const lines = text.split("\n")
|
46
40
|
for (const line of lines) {
|
@@ -44,7 +44,7 @@ export async function promptForInstallTool(update: boolean, newVersion?: string)
|
|
44
44
|
const newVersionLabel = newVersion ? ` (${newVersion})` : ''
|
45
45
|
|
46
46
|
const message = update ?
|
47
|
-
`A newer version of yoda${newVersionLabel} is
|
47
|
+
`A newer version of yoda${newVersionLabel} is available.` :
|
48
48
|
'yoda command is not available. Please install.'
|
49
49
|
|
50
50
|
const selected = await window.showInformationMessage(message, ...choises)
|
@@ -16,7 +16,7 @@ module Yoda
|
|
16
16
|
|
17
17
|
# @param root_path [String]
|
18
18
|
def initialize(root_path)
|
19
|
-
@root_path = root_path
|
19
|
+
@root_path = File.expand_path(root_path)
|
20
20
|
end
|
21
21
|
|
22
22
|
# @return [Array<Yoda::Store::Objects::Library::Gem>]
|
@@ -28,6 +28,7 @@ module Yoda
|
|
28
28
|
{
|
29
29
|
path: root_path,
|
30
30
|
dependencies: gems.map(&:to_h),
|
31
|
+
autoload_dependency_ids: autoload_gem_ids,
|
31
32
|
}
|
32
33
|
end
|
33
34
|
|
@@ -45,39 +46,47 @@ module Yoda
|
|
45
46
|
end
|
46
47
|
end
|
47
48
|
|
48
|
-
# @return [Array<
|
49
|
+
# @return [Array<String>]
|
50
|
+
def autoload_gem_ids
|
51
|
+
if has_gemfile?
|
52
|
+
gems.map(&:id)
|
53
|
+
else
|
54
|
+
[]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Array<Bundler::LazySpecification, Gem::Specification>, nil]
|
49
59
|
def gem_specs
|
50
60
|
@gem_specs ||= begin
|
51
|
-
|
52
|
-
|
53
|
-
#
|
54
|
-
Bundler.
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
Bundler.definition.resolve_remotely!
|
61
|
-
spec_set = Bundler.definition.resolve
|
62
|
-
|
63
|
-
if Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('2.2.25')
|
64
|
-
deps = Bundler.definition.requested_dependencies
|
65
|
-
spec_set.materialize(deps).to_a
|
66
|
-
else
|
67
|
-
# For backward compatibility (Ref: https://github.com/rubygems/rubygems/pull/4788)
|
68
|
-
deps = Bundler.definition.send(:requested_dependencies)
|
69
|
-
missing = []
|
70
|
-
materialized = spec_set.materialize(deps, missing)
|
71
|
-
materialized.to_a + missing
|
72
|
-
end
|
61
|
+
with_project_env do
|
62
|
+
if has_gemfile?
|
63
|
+
# Resolve dependencies of uninstalled gems and ensure remote sources are available.
|
64
|
+
Bundler.definition.resolve_remotely!
|
65
|
+
spec_set = Bundler.definition.resolve
|
66
|
+
|
67
|
+
if Gem::Version.new(Bundler::VERSION) >= Gem::Version.new('2.2.25')
|
68
|
+
deps = Bundler.definition.requested_dependencies
|
69
|
+
spec_set.materialize(deps).to_a
|
73
70
|
else
|
74
|
-
|
71
|
+
# For backward compatibility (Ref: https://github.com/rubygems/rubygems/pull/4788)
|
72
|
+
deps = Bundler.definition.send(:requested_dependencies)
|
73
|
+
missing = []
|
74
|
+
materialized = spec_set.materialize(deps, missing)
|
75
|
+
|
76
|
+
materialized.to_a + missing
|
75
77
|
end
|
78
|
+
else
|
79
|
+
[] # Gem::Specification.latest_specs(true)
|
76
80
|
end
|
77
81
|
end
|
78
82
|
end
|
79
83
|
end
|
80
84
|
|
85
|
+
# @return [Boolean]
|
86
|
+
def has_gemfile?
|
87
|
+
File.exists?(File.expand_path("Gemfile", root_path))
|
88
|
+
end
|
89
|
+
|
81
90
|
# @param [Gem::Specification]
|
82
91
|
def metadata?(spec)
|
83
92
|
spec.source.is_a?(Bundler::Source::Metadata)
|
@@ -88,6 +97,18 @@ module Yoda
|
|
88
97
|
spec.source.is_a?(Bundler::Source::Path) && (File.expand_path(spec.source.path) == File.expand_path(root_path))
|
89
98
|
end
|
90
99
|
|
100
|
+
def with_project_env
|
101
|
+
Dir.chdir(root_path) do
|
102
|
+
with_unbundled_env do
|
103
|
+
# Suppress bundler outputs to stdout.
|
104
|
+
Bundler.ui = Bundler::UI::Silent.new
|
105
|
+
Bundler.reset!
|
106
|
+
|
107
|
+
yield
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
91
112
|
def with_unbundled_env(&block)
|
92
113
|
if Bundler.respond_to?(:with_unbundled_env)
|
93
114
|
Bundler.with_unbundled_env(&block)
|
data/lib/yoda/id_mask.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require 'set'
|
2
|
+
|
3
|
+
module Yoda
|
4
|
+
class IdMask
|
5
|
+
# @return [Hash<Symbol>, nil]
|
6
|
+
attr_reader :pattern
|
7
|
+
|
8
|
+
# @param pattern [IdMask, Set<Symbol>, Array<Symbol>, Hash<Symbol>, nil]
|
9
|
+
# @return [IdMask]
|
10
|
+
def self.build(pattern)
|
11
|
+
if pattern.is_a?(IdMask)
|
12
|
+
pattern
|
13
|
+
elsif pattern.nil?
|
14
|
+
new(pattern)
|
15
|
+
elsif pattern.is_a?(Hash)
|
16
|
+
new(pattern.map { |k, v| [k.to_sym, v] }.to_h)
|
17
|
+
else
|
18
|
+
new(pattern.to_a.to_h { |id| [id.to_sym, nil] })
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# @param pattern [Hash<Symbol>, nil]
|
23
|
+
def initialize(pattern)
|
24
|
+
fail TypeError, "pattern must be a Hash or nil" unless pattern.is_a?(Hash) || pattern.nil?
|
25
|
+
@pattern = pattern
|
26
|
+
end
|
27
|
+
|
28
|
+
# @param id [Symbol, String]
|
29
|
+
# @return [Boolean]
|
30
|
+
def cover?(id)
|
31
|
+
return true if any?
|
32
|
+
pattern.has_key?(id.to_sym)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param another [IdMasklia, Set<Symbol>, Array<Symbol>, Hash<Symbol>, nil]
|
36
|
+
# @return [IdMask]
|
37
|
+
def intersection(another)
|
38
|
+
another_mask = IdMask.build(another)
|
39
|
+
return another_mask if any?
|
40
|
+
return self if another_mask.any?
|
41
|
+
|
42
|
+
ids_intersection = covering_ids & another_mask.covering_ids
|
43
|
+
|
44
|
+
intersection_pattern = ids_intersection.map do |id|
|
45
|
+
[id, nesting_mask(id) & another_mask.nesting_mask(id)]
|
46
|
+
end.to_h
|
47
|
+
|
48
|
+
IdMask.build(intersection_pattern)
|
49
|
+
end
|
50
|
+
|
51
|
+
alias_method :&, :intersection
|
52
|
+
|
53
|
+
# @return [Boolean]
|
54
|
+
def any?
|
55
|
+
pattern.nil?
|
56
|
+
end
|
57
|
+
|
58
|
+
# @return [Set<Symbol>, nil]
|
59
|
+
def covering_ids
|
60
|
+
@covering_ids ||= begin
|
61
|
+
if any?
|
62
|
+
nil
|
63
|
+
else
|
64
|
+
Set.new(pattern.keys)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
# @param id [String, Symbol]
|
70
|
+
# @return [IdMask]
|
71
|
+
def nesting_mask(id)
|
72
|
+
if pattern.is_a?(Hash)
|
73
|
+
IdMask.build(pattern[id.to_sym])
|
74
|
+
else
|
75
|
+
IdMask.build(nil)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
# @return [Hash, nil]
|
80
|
+
def to_pattern
|
81
|
+
pattern&.map { |k, v| [k, v&.to_pattern] }&.to_h
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
module Yoda
|
2
|
+
module Model
|
3
|
+
module Descriptions
|
4
|
+
# @abstract
|
5
|
+
class RequirePathDescription
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :path
|
8
|
+
|
9
|
+
# @param path [String]
|
10
|
+
def initialize(path)
|
11
|
+
@path = path
|
12
|
+
end
|
13
|
+
|
14
|
+
# @abstract
|
15
|
+
# @return [String]
|
16
|
+
def title
|
17
|
+
path
|
18
|
+
end
|
19
|
+
|
20
|
+
# @abstract
|
21
|
+
# @return [String]
|
22
|
+
def sort_text
|
23
|
+
path
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String]
|
27
|
+
def label
|
28
|
+
sort_text
|
29
|
+
end
|
30
|
+
|
31
|
+
# @abstract
|
32
|
+
# @return [String]
|
33
|
+
def to_markdown
|
34
|
+
path
|
35
|
+
end
|
36
|
+
|
37
|
+
# Return an LSP MarkedString content for description
|
38
|
+
# @return [String, Hash]
|
39
|
+
def markup_content
|
40
|
+
to_markdown
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -7,6 +7,7 @@ module Yoda
|
|
7
7
|
require 'yoda/model/descriptions/value_description'
|
8
8
|
require 'yoda/model/descriptions/word_description'
|
9
9
|
require 'yoda/model/descriptions/node_description'
|
10
|
+
require 'yoda/model/descriptions/require_path_description'
|
10
11
|
require 'yoda/model/descriptions/variable_description'
|
11
12
|
end
|
12
13
|
end
|
@@ -3,7 +3,15 @@ module Yoda
|
|
3
3
|
module NodeSignatures
|
4
4
|
class Node < Base
|
5
5
|
def descriptions
|
6
|
-
|
6
|
+
if node_info.require_paths.empty?
|
7
|
+
[node_type_description, *type_descriptions]
|
8
|
+
else
|
9
|
+
node_info.require_paths.map { |path| Descriptions::RequirePathDescription.new(path) }
|
10
|
+
end
|
11
|
+
end
|
12
|
+
|
13
|
+
def defined_files
|
14
|
+
node_info.require_paths.map { |path| [path, Parsing::Location.first_row, Parsing::Location.first_column] }
|
7
15
|
end
|
8
16
|
end
|
9
17
|
end
|
@@ -17,6 +17,15 @@ module Yoda
|
|
17
17
|
@column = column
|
18
18
|
end
|
19
19
|
|
20
|
+
def self.first_row
|
21
|
+
1
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.first_column
|
25
|
+
0
|
26
|
+
end
|
27
|
+
|
28
|
+
|
20
29
|
# @param ast_location [Parser::Source::Map, Parser::Source::Range]
|
21
30
|
# @return [Location, nil]
|
22
31
|
def self.of_ast_location(ast_location)
|
@@ -0,0 +1,33 @@
|
|
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 File.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
|
+
end
|
32
|
+
end
|
33
|
+
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
|