yoda-language-server 0.4.0 → 0.5.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.
- checksums.yaml +4 -4
- data/Gemfile.lock +5 -3
- data/README.md +50 -48
- data/client/atom/main.js +13 -3
- data/client/vscode/.vscode/launch.json +7 -4
- data/client/vscode/package-lock.json +585 -1454
- data/client/vscode/package.json +10 -7
- data/client/vscode/src/extension.ts +3 -3
- data/client/vscode/src/test/completion.test.ts +39 -0
- data/client/vscode/src/test/helper.ts +38 -0
- data/client/vscode/src/test/index.ts +5 -3
- data/client/vscode/testFixture/completion.rb +1 -0
- data/exe/yoda +1 -20
- data/lib/yoda.rb +2 -1
- data/lib/yoda/commands.rb +34 -0
- data/lib/yoda/commands/base.rb +10 -0
- data/lib/yoda/commands/complete.rb +36 -0
- data/lib/yoda/commands/file_cursor_parsable.rb +29 -0
- data/lib/yoda/{runner → commands}/infer.rb +4 -9
- data/lib/yoda/commands/setup.rb +37 -0
- data/lib/yoda/errors.rb +34 -0
- data/lib/yoda/evaluation/evaluator.rb +2 -0
- data/lib/yoda/server.rb +60 -15
- data/lib/yoda/server/completion_provider.rb +8 -8
- data/lib/yoda/server/definition_provider.rb +8 -8
- data/lib/yoda/server/hover_provider.rb +6 -6
- data/lib/yoda/server/initialization_provider.rb +85 -0
- data/lib/yoda/server/{client_info.rb → session.rb} +6 -2
- data/lib/yoda/server/signature_provider.rb +6 -6
- data/lib/yoda/store/actions.rb +3 -1
- data/lib/yoda/store/actions/build_core_index.rb +44 -0
- data/lib/yoda/store/actions/import_core_library.rb +14 -9
- data/lib/yoda/store/actions/import_gem.rb +98 -0
- data/lib/yoda/store/actions/import_std_library.rb +35 -0
- data/lib/yoda/store/adapters.rb +1 -0
- data/lib/yoda/store/adapters/memory_adapter.rb +81 -0
- data/lib/yoda/store/objects.rb +4 -0
- data/lib/yoda/store/objects/addressable.rb +0 -12
- data/lib/yoda/store/objects/base.rb +4 -14
- data/lib/yoda/store/objects/merger.rb +4 -4
- data/lib/yoda/store/objects/patchable.rb +19 -0
- data/lib/yoda/store/objects/project_status.rb +169 -0
- data/lib/yoda/store/objects/serializable.rb +39 -0
- data/lib/yoda/store/project.rb +28 -114
- data/lib/yoda/store/project/cache.rb +79 -0
- data/lib/yoda/store/project/library_doc_loader.rb +102 -0
- data/lib/yoda/store/query/find_constant.rb +2 -1
- data/lib/yoda/store/registry.rb +15 -0
- data/lib/yoda/store/yard_importer.rb +58 -28
- data/lib/yoda/typing/evaluator.rb +8 -5
- data/lib/yoda/version.rb +1 -1
- data/package.json +32 -11
- data/scripts/benchmark.rb +1 -1
- data/yoda-language-server.gemspec +1 -0
- metadata +37 -7
- data/client/vscode/src/test/extension.test.ts +0 -22
- data/lib/yoda/runner/setup.rb +0 -26
- data/lib/yoda/store/actions/import_gems.rb +0 -91
@@ -0,0 +1,35 @@
|
|
1
|
+
module Yoda
|
2
|
+
module Store
|
3
|
+
module Actions
|
4
|
+
class ImportStdLibrary
|
5
|
+
# @return [Registry]
|
6
|
+
attr_reader :registry
|
7
|
+
|
8
|
+
class << self
|
9
|
+
# @return [true, false]
|
10
|
+
def run(registry)
|
11
|
+
new(registry).run
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
def initialize(registry)
|
16
|
+
@registry = registry
|
17
|
+
end
|
18
|
+
|
19
|
+
# @return [true, false]
|
20
|
+
def run
|
21
|
+
return false unless File.exist?(doc_path)
|
22
|
+
patch = YardImporter.import(doc_path)
|
23
|
+
registry.add_patch(patch)
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
private
|
28
|
+
|
29
|
+
def doc_path
|
30
|
+
File.expand_path("~/.yoda/sources/ruby-#{RUBY_VERSION}/.yardoc-stdlib")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
data/lib/yoda/store/adapters.rb
CHANGED
@@ -0,0 +1,81 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module Yoda
|
4
|
+
module Store
|
5
|
+
module Adapters
|
6
|
+
# An adapter implementation to store object in memory.
|
7
|
+
# This implementation losts data on exit and we recommend to use this adapter only for test.
|
8
|
+
class MemoryAdapter < Base
|
9
|
+
class << self
|
10
|
+
def for(path)
|
11
|
+
@pool ||= {}
|
12
|
+
@pool[path] || (@pool[path] = new(path))
|
13
|
+
end
|
14
|
+
|
15
|
+
def type
|
16
|
+
:memory
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Hash{String => String}]
|
21
|
+
attr_reader :db
|
22
|
+
|
23
|
+
# @param path [String, nil] represents the path to store db.
|
24
|
+
def initialize(path = nil)
|
25
|
+
@path = path
|
26
|
+
@db = {}
|
27
|
+
end
|
28
|
+
|
29
|
+
# @param address [String]
|
30
|
+
# @return [any]
|
31
|
+
def get(address)
|
32
|
+
JSON.load(db[address.to_s], symbolize_names: true)
|
33
|
+
end
|
34
|
+
|
35
|
+
# @param data [Enumerator<(String, Object)>]
|
36
|
+
# @param bar [ProgressBar, nil]
|
37
|
+
def batch_write(data, bar)
|
38
|
+
data.each do |(k, v)|
|
39
|
+
put(k, v)
|
40
|
+
bar&.increment
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# @param address [String]
|
45
|
+
# @param object [Object]
|
46
|
+
# @return [void]
|
47
|
+
def put(address, object)
|
48
|
+
db[address.to_s] = object.to_json
|
49
|
+
end
|
50
|
+
|
51
|
+
# @param address [String]
|
52
|
+
# @return [void]
|
53
|
+
def delete(address)
|
54
|
+
db.delete(address.to_s)
|
55
|
+
end
|
56
|
+
|
57
|
+
# @param address [String]
|
58
|
+
# @return [true, false]
|
59
|
+
def exist?(address)
|
60
|
+
db.member?(address.to_s)
|
61
|
+
end
|
62
|
+
|
63
|
+
# @return [Array<String>]
|
64
|
+
def keys
|
65
|
+
db.keys
|
66
|
+
end
|
67
|
+
|
68
|
+
def stats
|
69
|
+
"No stats"
|
70
|
+
end
|
71
|
+
|
72
|
+
def clear
|
73
|
+
db.clear
|
74
|
+
end
|
75
|
+
|
76
|
+
def sync
|
77
|
+
end
|
78
|
+
end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
data/lib/yoda/store/objects.rb
CHANGED
@@ -4,6 +4,9 @@ module Yoda
|
|
4
4
|
VALUE_REGEXP = /\A[0-9a-z]/
|
5
5
|
MODULE_TAIL_PATTERN = /(?:::(\w+)|^(\w+))$/
|
6
6
|
|
7
|
+
require 'yoda/store/objects/serializable'
|
8
|
+
require 'yoda/store/objects/addressable'
|
9
|
+
require 'yoda/store/objects/patchable'
|
7
10
|
require 'yoda/store/objects/base'
|
8
11
|
require 'yoda/store/objects/namespace_object'
|
9
12
|
require 'yoda/store/objects/class_object'
|
@@ -16,6 +19,7 @@ module Yoda
|
|
16
19
|
require 'yoda/store/objects/patch'
|
17
20
|
require 'yoda/store/objects/patch_set'
|
18
21
|
require 'yoda/store/objects/tag'
|
22
|
+
require 'yoda/store/objects/project_status'
|
19
23
|
|
20
24
|
class << self
|
21
25
|
# @param hsh [Hash]
|
@@ -2,23 +2,11 @@ module Yoda
|
|
2
2
|
module Store
|
3
3
|
module Objects
|
4
4
|
module Addressable
|
5
|
-
# @abstract
|
6
|
-
# @return [Symbol]
|
7
|
-
def kind
|
8
|
-
fail NotImplementedError
|
9
|
-
end
|
10
|
-
|
11
5
|
# @abstract
|
12
6
|
# @return [String]
|
13
7
|
def address
|
14
8
|
fail NotImplementedError
|
15
9
|
end
|
16
|
-
|
17
|
-
# @abstract
|
18
|
-
# @return [Hash]
|
19
|
-
def to_hash
|
20
|
-
fail NotImplementedError
|
21
|
-
end
|
22
10
|
end
|
23
11
|
end
|
24
12
|
end
|
@@ -3,16 +3,11 @@ module Yoda
|
|
3
3
|
module Objects
|
4
4
|
# @abstract
|
5
5
|
class Base
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
end
|
10
|
-
|
11
|
-
# @param params [Hash]
|
12
|
-
def json_create(params)
|
13
|
-
new(params.map { |k, v| [k.to_sym, v] }.to_h)
|
14
|
-
end
|
6
|
+
include Addressable
|
7
|
+
include Serializable
|
8
|
+
include Patchable
|
15
9
|
|
10
|
+
class << self
|
16
11
|
# @return [Array<Symbol>]
|
17
12
|
def attr_names
|
18
13
|
%i(path document tag_list sources primary_source)
|
@@ -74,11 +69,6 @@ module Yoda
|
|
74
69
|
}
|
75
70
|
end
|
76
71
|
|
77
|
-
# @return [String]
|
78
|
-
def to_json
|
79
|
-
to_h.merge(json_class: self.class.name).to_json
|
80
|
-
end
|
81
|
-
|
82
72
|
# @param another [self]
|
83
73
|
# @return [self]
|
84
74
|
def merge(another)
|
@@ -48,11 +48,11 @@ module Yoda
|
|
48
48
|
tag_list: one[:tag_list] + another[:tag_list],
|
49
49
|
sources: one[:sources] + another[:sources],
|
50
50
|
primary_source: one[:primary_source] || another[:primary_source],
|
51
|
-
instance_method_addresses: one[:instance_method_addresses] + another[:instance_method_addresses],
|
52
|
-
mixin_addresses: one[:mixin_addresses] + another[:mixin_addresses],
|
53
|
-
constant_addresses: one[:constant_addresses] + another[:constant_addresses],
|
51
|
+
instance_method_addresses: (one[:instance_method_addresses] + another[:instance_method_addresses]).uniq,
|
52
|
+
mixin_addresses: (one[:mixin_addresses] + another[:mixin_addresses]).uniq,
|
53
|
+
constant_addresses: (one[:constant_addresses] + another[:constant_addresses]).uniq,
|
54
54
|
visibility: one[:visibility] || another[:visibility],
|
55
|
-
parameters: one[:parameters].empty? ? another[:parameters] : one[:parameters],
|
55
|
+
parameters: one[:parameters].empty? ? another[:parameters] : one[:parameters],
|
56
56
|
overloads: one[:overloads] + another[:overloads],
|
57
57
|
superclass_path: select_superclass(one, another),
|
58
58
|
value: one[:value] || another[:value],
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Yoda
|
2
|
+
module Store
|
3
|
+
module Objects
|
4
|
+
module Patchable
|
5
|
+
# @abstract
|
6
|
+
# @return [Symbol]
|
7
|
+
def kind
|
8
|
+
fail NotImplementedError
|
9
|
+
end
|
10
|
+
|
11
|
+
# @abstract
|
12
|
+
# @return [Hash]
|
13
|
+
def to_h
|
14
|
+
fail NotImplementedError
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,169 @@
|
|
1
|
+
module Yoda
|
2
|
+
module Store
|
3
|
+
module Objects
|
4
|
+
class ProjectStatus
|
5
|
+
include Serializable
|
6
|
+
|
7
|
+
# @return [Integer]
|
8
|
+
attr_reader :version
|
9
|
+
|
10
|
+
# @return [BundleStatus]
|
11
|
+
attr_reader :bundle
|
12
|
+
|
13
|
+
# @param specs [Array<Bundler::LazySpecification>]
|
14
|
+
# @return [BundleStatus]
|
15
|
+
def self.initial_build(specs:)
|
16
|
+
new(bundle: BundleStatus.initial_build(specs), version: Registry::REGISTRY_VERSION)
|
17
|
+
end
|
18
|
+
|
19
|
+
# @param bundle [BundleStatus]
|
20
|
+
# @param version [Integer] the version number of registry
|
21
|
+
def initialize(bundle:, version:)
|
22
|
+
@bundle = bundle
|
23
|
+
@version = version
|
24
|
+
end
|
25
|
+
|
26
|
+
def to_h
|
27
|
+
{ bundle: bundle, version: version }
|
28
|
+
end
|
29
|
+
|
30
|
+
# Remember gem dependencies and loaded gems
|
31
|
+
class BundleStatus
|
32
|
+
include Serializable
|
33
|
+
|
34
|
+
# @return [Array<GemStatus>]
|
35
|
+
attr_reader :gem_statuses
|
36
|
+
|
37
|
+
# @return [StdStatus]
|
38
|
+
attr_reader :std_status
|
39
|
+
|
40
|
+
# @param specs [Array<Bundler::LazySpecification>]
|
41
|
+
# @return [BundleStatus]
|
42
|
+
def self.initial_build(specs)
|
43
|
+
gem_statuses = specs.map { |spec| ProjectStatus::GemStatus.initial_build(spec) }
|
44
|
+
std_status = StdStatus.initial_build
|
45
|
+
new(gem_statuses: gem_statuses, std_status: std_status)
|
46
|
+
end
|
47
|
+
|
48
|
+
# @param gem_statuses [Array<GemStatus>]
|
49
|
+
# @param std_status [StdStatus]
|
50
|
+
def initialize(gem_statuses:, std_status:)
|
51
|
+
@gem_statuses = gem_statuses
|
52
|
+
@std_status = std_status
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_h
|
56
|
+
{ gem_statuses: gem_statuses, std_status: std_status }
|
57
|
+
end
|
58
|
+
|
59
|
+
# @param name [String]
|
60
|
+
# @return [GemStatus, nil]
|
61
|
+
def [](name)
|
62
|
+
dictionary[name]
|
63
|
+
end
|
64
|
+
|
65
|
+
# @return [true, false]
|
66
|
+
def all_present?
|
67
|
+
gem_statuses.all?(&:present?) && std_status.all_present?
|
68
|
+
end
|
69
|
+
|
70
|
+
# @return [Array<GemStatus>]
|
71
|
+
def present_gems
|
72
|
+
gem_statuses.select(&:present?)
|
73
|
+
end
|
74
|
+
|
75
|
+
# @return [Array<GemStatus>]
|
76
|
+
def not_present_gems
|
77
|
+
gem_statuses.reject(&:present?)
|
78
|
+
end
|
79
|
+
|
80
|
+
private
|
81
|
+
|
82
|
+
# @return [Hash{String => GemStatus}]
|
83
|
+
def dictionary
|
84
|
+
@dictionary ||= gem_statuses.map do |gem_status|
|
85
|
+
[gem_status.name, gem_status]
|
86
|
+
end.to_h
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
# Remember ruby core and standard library state
|
91
|
+
class StdStatus
|
92
|
+
include Serializable
|
93
|
+
# @return [String]
|
94
|
+
attr_reader :version
|
95
|
+
|
96
|
+
# @return [true, false]
|
97
|
+
attr_reader :core_present, :std_present
|
98
|
+
|
99
|
+
# @return [StdStatus]
|
100
|
+
def self.initial_build
|
101
|
+
new(version: RUBY_VERSION, core_present: false, std_present: false)
|
102
|
+
end
|
103
|
+
|
104
|
+
# @param version [String]
|
105
|
+
# @param core_present [true, false] represents the flag if core's index file is present.
|
106
|
+
# @param std_present [true, false] represents the flag if standard library's index file is present.
|
107
|
+
def initialize(version:, core_present:, std_present:)
|
108
|
+
@version = version
|
109
|
+
@core_present = core_present
|
110
|
+
@std_present = std_present
|
111
|
+
end
|
112
|
+
|
113
|
+
# @return [true, false]
|
114
|
+
def all_present?
|
115
|
+
core_present? && std_present?
|
116
|
+
end
|
117
|
+
|
118
|
+
# @return [true, false]
|
119
|
+
def core_present?
|
120
|
+
core_present
|
121
|
+
end
|
122
|
+
|
123
|
+
# @return [true, false]
|
124
|
+
def std_present?
|
125
|
+
std_present
|
126
|
+
end
|
127
|
+
|
128
|
+
def to_h
|
129
|
+
{ version: version, core_present: core_present, std_present: std_present }
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Remember each gem state
|
134
|
+
class GemStatus
|
135
|
+
include Serializable
|
136
|
+
# @return [String]
|
137
|
+
attr_reader :name, :version
|
138
|
+
|
139
|
+
# @return [true, false]
|
140
|
+
attr_reader :present
|
141
|
+
|
142
|
+
# @param gem [Bundler::LazySpecification]
|
143
|
+
# @return [GemStatus]
|
144
|
+
def self.initial_build(gem)
|
145
|
+
new(name: gem.name, version: gem.version, present: false)
|
146
|
+
end
|
147
|
+
|
148
|
+
# @param name [String]
|
149
|
+
# @param version [String]
|
150
|
+
# @param present [true, false] represents the flag if the specified gem's index file is present.
|
151
|
+
def initialize(name:, version:, present:)
|
152
|
+
@name = name
|
153
|
+
@version = version
|
154
|
+
@present = present
|
155
|
+
end
|
156
|
+
|
157
|
+
def to_h
|
158
|
+
{ name: name, version: version, present: present }
|
159
|
+
end
|
160
|
+
|
161
|
+
# @return [true, false]
|
162
|
+
def present?
|
163
|
+
!!present
|
164
|
+
end
|
165
|
+
end
|
166
|
+
end
|
167
|
+
end
|
168
|
+
end
|
169
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Yoda
|
2
|
+
module Store
|
3
|
+
module Objects
|
4
|
+
module Serializable
|
5
|
+
module ClassMethods
|
6
|
+
def json_creatable?
|
7
|
+
true
|
8
|
+
end
|
9
|
+
|
10
|
+
# @param params [Hash]
|
11
|
+
def json_create(params)
|
12
|
+
new(params.reject { |k, _v| k.to_sym == :json_class }.map { |k, v| [k.to_sym, v] }.to_h)
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.included(klass)
|
17
|
+
klass.extend(ClassMethods)
|
18
|
+
end
|
19
|
+
|
20
|
+
# @abstract
|
21
|
+
# @return [Hash]
|
22
|
+
def to_h
|
23
|
+
fail NotImplementedError
|
24
|
+
end
|
25
|
+
|
26
|
+
# @return [String]
|
27
|
+
def to_json(*options)
|
28
|
+
to_h.merge(json_class: self.class.name).to_json
|
29
|
+
end
|
30
|
+
|
31
|
+
# Create a new instance which has the original parameters and overrided parameters.
|
32
|
+
# @param params [Hash{Symbol => Object}] parameters to override
|
33
|
+
def derive(params = {})
|
34
|
+
self.class.new(to_h.merge(params))
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|