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.
- checksums.yaml +7 -0
- data/.gitignore +16 -0
- data/.rspec +3 -0
- data/.travis.yml +8 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +78 -0
- data/LICENSE.txt +21 -0
- data/README.md +85 -0
- data/Rakefile +6 -0
- data/bin/console +14 -0
- data/bin/setup +8 -0
- data/client/atom/main.js +27 -0
- data/client/vscode/.gitignore +4 -0
- data/client/vscode/.vscode/launch.json +28 -0
- data/client/vscode/.vscode/settings.json +9 -0
- data/client/vscode/.vscode/tasks.json +20 -0
- data/client/vscode/.vscodeignore +8 -0
- data/client/vscode/CHANGELOG.md +7 -0
- data/client/vscode/README.md +65 -0
- data/client/vscode/package-lock.json +2688 -0
- data/client/vscode/package.json +39 -0
- data/client/vscode/src/extension.ts +42 -0
- data/client/vscode/src/test/extension.test.ts +22 -0
- data/client/vscode/src/test/index.ts +22 -0
- data/client/vscode/tsconfig.json +16 -0
- data/client/vscode/vsc-extension-quickstart.md +33 -0
- data/exe/yoda +27 -0
- data/lib/yoda.rb +11 -0
- data/lib/yoda/evaluation.rb +9 -0
- data/lib/yoda/evaluation/code_completion.rb +65 -0
- data/lib/yoda/evaluation/code_completion/base_provider.rb +57 -0
- data/lib/yoda/evaluation/code_completion/const_provider.rb +90 -0
- data/lib/yoda/evaluation/code_completion/method_provider.rb +82 -0
- data/lib/yoda/evaluation/code_completion/variable_provider.rb +18 -0
- data/lib/yoda/evaluation/comment_completion.rb +70 -0
- data/lib/yoda/evaluation/comment_completion/base_provider.rb +64 -0
- data/lib/yoda/evaluation/comment_completion/param_provider.rb +18 -0
- data/lib/yoda/evaluation/comment_completion/tag_provider.rb +41 -0
- data/lib/yoda/evaluation/comment_completion/type_provider.rb +58 -0
- data/lib/yoda/evaluation/current_node_explain.rb +70 -0
- data/lib/yoda/evaluation/evaluator.rb +103 -0
- data/lib/yoda/evaluation/signature_discovery.rb +83 -0
- data/lib/yoda/model.rb +12 -0
- data/lib/yoda/model/completion_item.rb +56 -0
- data/lib/yoda/model/descriptions.rb +10 -0
- data/lib/yoda/model/descriptions/base.rb +26 -0
- data/lib/yoda/model/descriptions/function_description.rb +40 -0
- data/lib/yoda/model/descriptions/value_description.rb +33 -0
- data/lib/yoda/model/descriptions/word_description.rb +32 -0
- data/lib/yoda/model/function_signatures.rb +13 -0
- data/lib/yoda/model/function_signatures/base.rb +68 -0
- data/lib/yoda/model/function_signatures/constructor.rb +70 -0
- data/lib/yoda/model/function_signatures/formatter.rb +82 -0
- data/lib/yoda/model/function_signatures/method.rb +67 -0
- data/lib/yoda/model/function_signatures/overload.rb +79 -0
- data/lib/yoda/model/function_signatures/parameter_list.rb +108 -0
- data/lib/yoda/model/function_signatures/type_builder.rb +101 -0
- data/lib/yoda/model/node_signature.rb +28 -0
- data/lib/yoda/model/path.rb +96 -0
- data/lib/yoda/model/scoped_path.rb +44 -0
- data/lib/yoda/model/types.rb +84 -0
- data/lib/yoda/model/types/any_type.rb +32 -0
- data/lib/yoda/model/types/base.rb +37 -0
- data/lib/yoda/model/types/duck_type.rb +41 -0
- data/lib/yoda/model/types/function_type.rb +174 -0
- data/lib/yoda/model/types/generic_type.rb +66 -0
- data/lib/yoda/model/types/instance_type.rb +42 -0
- data/lib/yoda/model/types/module_type.rb +42 -0
- data/lib/yoda/model/types/sequence_type.rb +53 -0
- data/lib/yoda/model/types/union_type.rb +56 -0
- data/lib/yoda/model/types/unknown_type.rb +40 -0
- data/lib/yoda/model/types/value_type.rb +58 -0
- data/lib/yoda/model/values.rb +9 -0
- data/lib/yoda/model/values/base.rb +32 -0
- data/lib/yoda/model/values/instance_value.rb +65 -0
- data/lib/yoda/model/values/module_value.rb +72 -0
- data/lib/yoda/parsing.rb +15 -0
- data/lib/yoda/parsing/ast_traversable.rb +18 -0
- data/lib/yoda/parsing/comment_tokenizer.rb +59 -0
- data/lib/yoda/parsing/location.rb +101 -0
- data/lib/yoda/parsing/node_objects.rb +10 -0
- data/lib/yoda/parsing/node_objects/const_node.rb +52 -0
- data/lib/yoda/parsing/node_objects/method_definition.rb +46 -0
- data/lib/yoda/parsing/node_objects/namespace.rb +104 -0
- data/lib/yoda/parsing/node_objects/send_node.rb +72 -0
- data/lib/yoda/parsing/parser.rb +27 -0
- data/lib/yoda/parsing/query.rb +11 -0
- data/lib/yoda/parsing/query/current_comment_query.rb +80 -0
- data/lib/yoda/parsing/query/current_comment_token_query.rb +153 -0
- data/lib/yoda/parsing/query/current_commenting_node_query.rb +68 -0
- data/lib/yoda/parsing/query/current_location_node_query.rb +51 -0
- data/lib/yoda/parsing/query/current_node_comment_query.rb +40 -0
- data/lib/yoda/parsing/range.rb +41 -0
- data/lib/yoda/parsing/scopes.rb +15 -0
- data/lib/yoda/parsing/scopes/base.rb +78 -0
- data/lib/yoda/parsing/scopes/builder.rb +60 -0
- data/lib/yoda/parsing/scopes/class_definition.rb +47 -0
- data/lib/yoda/parsing/scopes/meta_class_definition.rb +44 -0
- data/lib/yoda/parsing/scopes/meta_method_definition.rb +70 -0
- data/lib/yoda/parsing/scopes/method_definition.rb +69 -0
- data/lib/yoda/parsing/scopes/module_definition.rb +36 -0
- data/lib/yoda/parsing/scopes/root.rb +25 -0
- data/lib/yoda/parsing/source_analyzer.rb +59 -0
- data/lib/yoda/parsing/source_cutter.rb +231 -0
- data/lib/yoda/parsing/type_parser.rb +141 -0
- data/lib/yoda/runner.rb +6 -0
- data/lib/yoda/runner/infer.rb +50 -0
- data/lib/yoda/runner/setup.rb +26 -0
- data/lib/yoda/server.rb +191 -0
- data/lib/yoda/server/client_info.rb +98 -0
- data/lib/yoda/server/completion_provider.rb +78 -0
- data/lib/yoda/server/definition_provider.rb +36 -0
- data/lib/yoda/server/deserializer.rb +27 -0
- data/lib/yoda/server/hover_provider.rb +38 -0
- data/lib/yoda/server/signature_provider.rb +46 -0
- data/lib/yoda/store.rb +13 -0
- data/lib/yoda/store/actions.rb +10 -0
- data/lib/yoda/store/actions/import_core_library.rb +30 -0
- data/lib/yoda/store/actions/import_gems.rb +91 -0
- data/lib/yoda/store/actions/read_file.rb +36 -0
- data/lib/yoda/store/actions/read_project_files.rb +29 -0
- data/lib/yoda/store/adapters.rb +14 -0
- data/lib/yoda/store/adapters/base.rb +58 -0
- data/lib/yoda/store/adapters/leveldb_adapter.rb +80 -0
- data/lib/yoda/store/adapters/lmdb_adapter.rb +113 -0
- data/lib/yoda/store/objects.rb +46 -0
- data/lib/yoda/store/objects/addressable.rb +25 -0
- data/lib/yoda/store/objects/base.rb +116 -0
- data/lib/yoda/store/objects/class_object.rb +51 -0
- data/lib/yoda/store/objects/merger.rb +94 -0
- data/lib/yoda/store/objects/meta_class_object.rb +41 -0
- data/lib/yoda/store/objects/method_object.rb +94 -0
- data/lib/yoda/store/objects/module_object.rb +11 -0
- data/lib/yoda/store/objects/namespace_object.rb +67 -0
- data/lib/yoda/store/objects/overload.rb +51 -0
- data/lib/yoda/store/objects/patch.rb +46 -0
- data/lib/yoda/store/objects/patch_set.rb +80 -0
- data/lib/yoda/store/objects/tag.rb +62 -0
- data/lib/yoda/store/objects/value_object.rb +45 -0
- data/lib/yoda/store/project.rb +159 -0
- data/lib/yoda/store/query.rb +12 -0
- data/lib/yoda/store/query/associators.rb +10 -0
- data/lib/yoda/store/query/associators/associate_ancestors.rb +103 -0
- data/lib/yoda/store/query/associators/associate_methods.rb +38 -0
- data/lib/yoda/store/query/base.rb +16 -0
- data/lib/yoda/store/query/find_constant.rb +150 -0
- data/lib/yoda/store/query/find_meta_class.rb +18 -0
- data/lib/yoda/store/query/find_method.rb +74 -0
- data/lib/yoda/store/query/find_signature.rb +43 -0
- data/lib/yoda/store/registry.rb +67 -0
- data/lib/yoda/store/yard_importer.rb +260 -0
- data/lib/yoda/typing.rb +10 -0
- data/lib/yoda/typing/context.rb +96 -0
- data/lib/yoda/typing/environment.rb +35 -0
- data/lib/yoda/typing/evaluator.rb +256 -0
- data/lib/yoda/typing/lexical_scope.rb +26 -0
- data/lib/yoda/typing/relation.rb +15 -0
- data/lib/yoda/typing/traces.rb +9 -0
- data/lib/yoda/typing/traces/base.rb +26 -0
- data/lib/yoda/typing/traces/normal.rb +22 -0
- data/lib/yoda/typing/traces/send.rb +26 -0
- data/lib/yoda/version.rb +3 -0
- data/lib/yoda/yard_extensions.rb +11 -0
- data/lib/yoda/yard_extensions/sig_directive.rb +40 -0
- data/lib/yoda/yard_extensions/type_tag.rb +10 -0
- data/package.json +76 -0
- data/scripts/benchmark.rb +6 -0
- data/scripts/build_core_index.sh +16 -0
- data/yarn.lock +13 -0
- data/yoda-language-server.gemspec +40 -0
- metadata +424 -0
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
class MetaClassObject < NamespaceObject
|
|
5
|
+
# @param path [String]
|
|
6
|
+
# @return [String]
|
|
7
|
+
def self.address_of(path)
|
|
8
|
+
"#{path}%class"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @param path [String]
|
|
12
|
+
# @param document [Document, nil]
|
|
13
|
+
# @param tag_list [TagList, nil]
|
|
14
|
+
# @param instance_method_paths [Array<String>]
|
|
15
|
+
# @param instance_mixin_paths [Array<String>]
|
|
16
|
+
def initialize(**kwargs)
|
|
17
|
+
super(kwargs)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @return [String]
|
|
21
|
+
def name
|
|
22
|
+
@name ||= path.match(MODULE_TAIL_PATTERN) { |md| md[1] || md[2] }
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def kind
|
|
26
|
+
:meta_class
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
# @return [String]
|
|
30
|
+
def address
|
|
31
|
+
MetaClassObject.address_of(path)
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# @return [String]
|
|
35
|
+
def base_class_address
|
|
36
|
+
path
|
|
37
|
+
end
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
class MethodObject < Base
|
|
5
|
+
# @return [Array<(String, String)>]
|
|
6
|
+
attr_reader :parameters
|
|
7
|
+
|
|
8
|
+
# @return [Symbol]
|
|
9
|
+
attr_reader :visibility
|
|
10
|
+
|
|
11
|
+
# @return [Array<Overload>]
|
|
12
|
+
attr_reader :overloads
|
|
13
|
+
|
|
14
|
+
class << self
|
|
15
|
+
# @param path [String]
|
|
16
|
+
# @return [String]
|
|
17
|
+
def namespace_of_path(path)
|
|
18
|
+
path.slice(0, (path.rindex(/[#.]/) || 0))
|
|
19
|
+
end
|
|
20
|
+
|
|
21
|
+
# @param path [String]
|
|
22
|
+
# @return [String]
|
|
23
|
+
def name_of_path(path)
|
|
24
|
+
path.slice((path.rindex(/[#.]/) || -1) + 1, path.length)
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param path [String]
|
|
28
|
+
# @return [String]
|
|
29
|
+
def sep_of_path(path)
|
|
30
|
+
path.slice(path.rindex(/[#.]/))
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @return [Array<Symbol>]
|
|
34
|
+
def attr_names
|
|
35
|
+
super + %i(parameters visibility overloads)
|
|
36
|
+
end
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @param path [String]
|
|
40
|
+
# @param document [Document, nil]
|
|
41
|
+
# @param tag_list [TagList, nil]
|
|
42
|
+
# @param visibility [Symbol]
|
|
43
|
+
# @param overloads [Array<Overload>]
|
|
44
|
+
# @param parameters [Array<(String, String)>, nil]
|
|
45
|
+
def initialize(parameters: [], visibility: :public, overloads: [], **kwargs)
|
|
46
|
+
super(kwargs)
|
|
47
|
+
fail ArgumentError, visibility unless %i(public private protected)
|
|
48
|
+
@visibility = visibility.to_sym
|
|
49
|
+
@parameters = parameters
|
|
50
|
+
@overloads = overloads
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# @return [String]
|
|
54
|
+
def name
|
|
55
|
+
@name ||= MethodObject.name_of_path(path)
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
# @return [String]
|
|
59
|
+
def sep
|
|
60
|
+
@sep ||= MethodObject.sep_of_path(path)
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# @return [String]
|
|
64
|
+
def namespace_path
|
|
65
|
+
@namespace_path ||= MethodObject.namespace_of_path(path)
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def kind
|
|
69
|
+
:method
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def to_h
|
|
73
|
+
super.merge(
|
|
74
|
+
parameters: parameters.to_a,
|
|
75
|
+
visibility: visibility,
|
|
76
|
+
overloads: overloads,
|
|
77
|
+
)
|
|
78
|
+
end
|
|
79
|
+
|
|
80
|
+
private
|
|
81
|
+
|
|
82
|
+
# @param another [self]
|
|
83
|
+
# @return [Hash]
|
|
84
|
+
def merge_attributes(another)
|
|
85
|
+
super.merge(
|
|
86
|
+
visibility: another.visibility,
|
|
87
|
+
parameters: another.parameters.to_a,
|
|
88
|
+
overloads: overloads + another.overloads,
|
|
89
|
+
)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
# @abstract
|
|
5
|
+
class NamespaceObject < Base
|
|
6
|
+
# @return [Array<String>]
|
|
7
|
+
attr_reader :instance_method_addresses
|
|
8
|
+
|
|
9
|
+
# @type Array<String>
|
|
10
|
+
attr_reader :mixin_addresses
|
|
11
|
+
|
|
12
|
+
# @type Array<String>
|
|
13
|
+
attr_reader :constant_addresses
|
|
14
|
+
|
|
15
|
+
# @return [Enumerable<NamespaceObject>]
|
|
16
|
+
attr_accessor :ancestors
|
|
17
|
+
|
|
18
|
+
# @return [Enumerable<MethodObject>]
|
|
19
|
+
attr_accessor :methods
|
|
20
|
+
|
|
21
|
+
# @return [Array<Symbol>]
|
|
22
|
+
def self.attr_names
|
|
23
|
+
super + %i(instance_method_addresses mixin_addresses constant_addresses)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# @param path [String]
|
|
27
|
+
# @param document [Document, nil]
|
|
28
|
+
# @param tag_list [TagList, nil]
|
|
29
|
+
# @param instance_method_paths [Array<String>]
|
|
30
|
+
# @param constant_addresses [Array<String>]
|
|
31
|
+
# @param mixin_addresses [Array<String>]
|
|
32
|
+
def initialize(instance_method_addresses: [], mixin_addresses: [], constant_addresses: [], **kwargs)
|
|
33
|
+
super(kwargs)
|
|
34
|
+
@instance_method_addresses = instance_method_addresses
|
|
35
|
+
@mixin_addresses = mixin_addresses
|
|
36
|
+
@constant_addresses = constant_addresses
|
|
37
|
+
@ancestors ||= []
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @return [String]
|
|
41
|
+
def name
|
|
42
|
+
@name ||= path.match(MODULE_TAIL_PATTERN) { |md| md[1] || md[2] }
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
def to_h
|
|
46
|
+
super.merge(
|
|
47
|
+
instance_method_addresses: instance_method_addresses,
|
|
48
|
+
mixin_addresses: mixin_addresses,
|
|
49
|
+
constant_addresses: constant_addresses,
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
private
|
|
54
|
+
|
|
55
|
+
# @param another [self]
|
|
56
|
+
# @return [Hash]
|
|
57
|
+
def merge_attributes(another)
|
|
58
|
+
super.merge(
|
|
59
|
+
instance_method_addresses: (instance_method_addresses + another.instance_method_addresses).uniq,
|
|
60
|
+
mixin_addresses: (mixin_addresses + another.mixin_addresses).uniq,
|
|
61
|
+
constant_addresses: (constant_addresses + another.constant_addresses).uniq,
|
|
62
|
+
)
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
class Overload
|
|
5
|
+
class << self
|
|
6
|
+
def json_creatable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @param params [Hash]
|
|
11
|
+
def json_create(params)
|
|
12
|
+
new(params.map { |k, v| [k.to_sym, v] }.select { |(k, v)| %i(name tag_list document parameters).include?(k) }.to_h)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [String]
|
|
17
|
+
attr_reader :name
|
|
18
|
+
|
|
19
|
+
# @return [Array<(String, String)>]
|
|
20
|
+
attr_reader :parameters
|
|
21
|
+
|
|
22
|
+
# @return [String, nil]
|
|
23
|
+
attr_reader :document
|
|
24
|
+
|
|
25
|
+
# @return [Array<Tag>]
|
|
26
|
+
attr_reader :tag_list
|
|
27
|
+
|
|
28
|
+
# @param name [String]
|
|
29
|
+
# @param parameters [Array<(String, String)>]
|
|
30
|
+
# @param document [String]
|
|
31
|
+
# @param tag_list [Array<Tag>]
|
|
32
|
+
def initialize(name:, parameters: [], document: '', tag_list: [])
|
|
33
|
+
@name = name
|
|
34
|
+
@parameters = parameters
|
|
35
|
+
@document = document
|
|
36
|
+
@tag_list = tag_list
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Hash]
|
|
40
|
+
def to_h
|
|
41
|
+
{ name: name, parameters: parameters, document: document, tag_list: tag_list }
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
# @return [String]
|
|
45
|
+
def to_json(_mode = nil)
|
|
46
|
+
to_h.merge(json_class: self.class.name).to_json
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
end
|
|
51
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
class Patch
|
|
5
|
+
# @param id [String]
|
|
6
|
+
attr_reader :id
|
|
7
|
+
|
|
8
|
+
# @param registry [Hash{ Symbol => Addressable }]
|
|
9
|
+
attr_reader :registry
|
|
10
|
+
|
|
11
|
+
# @param id [String]
|
|
12
|
+
def initialize(id)
|
|
13
|
+
@id = id
|
|
14
|
+
@registry = Hash.new
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @param addressable [Addressable]
|
|
18
|
+
# @return [void]
|
|
19
|
+
def register(addressable)
|
|
20
|
+
if el = @registry[addressable.address.to_sym]
|
|
21
|
+
@registry[addressable.address.to_sym] = el.merge(addressable)
|
|
22
|
+
else
|
|
23
|
+
@registry[addressable.address.to_sym] = addressable
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# @param address [String, Symbol]
|
|
28
|
+
# @return [Addressable, nil]
|
|
29
|
+
def find(address)
|
|
30
|
+
@registry[address.to_sym]
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
# @param address [String, Symbol]
|
|
34
|
+
# @return [true, false]
|
|
35
|
+
def has_key?(address)
|
|
36
|
+
@registry.has_key?(address.to_sym)
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
# @return [Array<Symbol>]
|
|
40
|
+
def keys
|
|
41
|
+
@registry.keys
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
# PatchSet manages patch updates and patch outdates.
|
|
5
|
+
# Besides, this class provides api to modify objects by using owning patches.
|
|
6
|
+
class PatchSet
|
|
7
|
+
# @return [{ Symbol => Array<Symbol> }]
|
|
8
|
+
attr_reader :address_index
|
|
9
|
+
|
|
10
|
+
# @return [{ Symbol => Patch }]
|
|
11
|
+
attr_reader :patches
|
|
12
|
+
|
|
13
|
+
def initialize
|
|
14
|
+
@patches = Hash.new
|
|
15
|
+
@address_index = Hash.new
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @param patch [Patch]
|
|
19
|
+
# @return [void]
|
|
20
|
+
def register(patch)
|
|
21
|
+
register_to_index(patch)
|
|
22
|
+
patches[patch.id.to_sym] = patch
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
# @param id [String, Symbol]
|
|
26
|
+
def delete(id)
|
|
27
|
+
patches.delete(id.to_sym)
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# @param object [Addressable]
|
|
31
|
+
# @return [Addressable]
|
|
32
|
+
def patch(object)
|
|
33
|
+
check_outdated_index(object.address.to_sym)
|
|
34
|
+
objects_in_patch = (address_index[object.address.to_sym] || []).map { |patch_id| patches[patch_id].find(object.address.to_sym) }
|
|
35
|
+
Merger.new([object, *objects_in_patch]).merged_instance
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @param address [String, Symbol]
|
|
39
|
+
# @return [Addressable, nil]
|
|
40
|
+
def find(address)
|
|
41
|
+
check_outdated_index(address.to_sym)
|
|
42
|
+
if (patch_ids = address_index[address.to_sym] || []).empty?
|
|
43
|
+
nil
|
|
44
|
+
else
|
|
45
|
+
objects = patch_ids.map { |id| patches[id].find(address.to_sym) }
|
|
46
|
+
Merger.new(objects).merged_instance
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [Array<Symbol>]
|
|
51
|
+
def keys
|
|
52
|
+
address_index.keys
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @param address [String, Symbol]
|
|
56
|
+
# @return [true, false]
|
|
57
|
+
def has_key?(address)
|
|
58
|
+
check_outdated_index(address.to_sym)
|
|
59
|
+
address_index[address.to_sym] && !address_index[address.to_sym].empty?
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
private
|
|
63
|
+
|
|
64
|
+
# @param patch [Patch]
|
|
65
|
+
# @return [void]
|
|
66
|
+
def register_to_index(patch)
|
|
67
|
+
patch.keys.each do |key|
|
|
68
|
+
address_index[key.to_sym] ||= []
|
|
69
|
+
address_index[key.to_sym].push(patch.id.to_sym)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
# @param address [Symbol]
|
|
74
|
+
def check_outdated_index(address)
|
|
75
|
+
(address_index[address] || []).select! { |patch_id| patches[patch_id].has_key?(address) }
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
module Yoda
|
|
2
|
+
module Store
|
|
3
|
+
module Objects
|
|
4
|
+
class Tag
|
|
5
|
+
class << self
|
|
6
|
+
def json_creatable?
|
|
7
|
+
true
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
# @param params [Hash]
|
|
11
|
+
def json_create(params)
|
|
12
|
+
new(params.map { |k, v| [k.to_sym, v] }.select { |(k, v)| %i(tag_name name yard_types text lexical_scope).include?(k) }.to_h)
|
|
13
|
+
end
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# @return [String]
|
|
17
|
+
attr_reader :tag_name
|
|
18
|
+
|
|
19
|
+
# @return [String, nil]
|
|
20
|
+
attr_reader :name, :text
|
|
21
|
+
|
|
22
|
+
# @return [Array<String>]
|
|
23
|
+
attr_reader :yard_types, :lexical_scope
|
|
24
|
+
|
|
25
|
+
# @param tag_name [String]
|
|
26
|
+
# @param name [String, nil]
|
|
27
|
+
# @param yard_types [Array<String>]
|
|
28
|
+
# @param text [String, nil]
|
|
29
|
+
# @param lexical_scope [Array<String>]
|
|
30
|
+
def initialize(tag_name:, name: nil, yard_types: [], text: nil, lexical_scope: [])
|
|
31
|
+
@tag_name = tag_name
|
|
32
|
+
@name = name
|
|
33
|
+
@yard_types = yard_types
|
|
34
|
+
@text = text
|
|
35
|
+
@lexical_scope = lexical_scope
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
# @return [Hash]
|
|
39
|
+
def to_h
|
|
40
|
+
{ name: name, tag_name: tag_name, yard_types: yard_types, text: text, lexical_scope: lexical_scope }
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def hash
|
|
44
|
+
([self.class.name] + to_h.to_a).hash
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def eql?(another)
|
|
48
|
+
self.class == another.class && to_h == another.to_h
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def ==(another)
|
|
52
|
+
eql?(another)
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [String]
|
|
56
|
+
def to_json(_state = nil)
|
|
57
|
+
to_h.merge(json_class: self.class.name).to_json
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
end
|
|
62
|
+
end
|