yoda-language-server 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (171) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +16 -0
  3. data/.rspec +3 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +6 -0
  6. data/Gemfile.lock +78 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.md +85 -0
  9. data/Rakefile +6 -0
  10. data/bin/console +14 -0
  11. data/bin/setup +8 -0
  12. data/client/atom/main.js +27 -0
  13. data/client/vscode/.gitignore +4 -0
  14. data/client/vscode/.vscode/launch.json +28 -0
  15. data/client/vscode/.vscode/settings.json +9 -0
  16. data/client/vscode/.vscode/tasks.json +20 -0
  17. data/client/vscode/.vscodeignore +8 -0
  18. data/client/vscode/CHANGELOG.md +7 -0
  19. data/client/vscode/README.md +65 -0
  20. data/client/vscode/package-lock.json +2688 -0
  21. data/client/vscode/package.json +39 -0
  22. data/client/vscode/src/extension.ts +42 -0
  23. data/client/vscode/src/test/extension.test.ts +22 -0
  24. data/client/vscode/src/test/index.ts +22 -0
  25. data/client/vscode/tsconfig.json +16 -0
  26. data/client/vscode/vsc-extension-quickstart.md +33 -0
  27. data/exe/yoda +27 -0
  28. data/lib/yoda.rb +11 -0
  29. data/lib/yoda/evaluation.rb +9 -0
  30. data/lib/yoda/evaluation/code_completion.rb +65 -0
  31. data/lib/yoda/evaluation/code_completion/base_provider.rb +57 -0
  32. data/lib/yoda/evaluation/code_completion/const_provider.rb +90 -0
  33. data/lib/yoda/evaluation/code_completion/method_provider.rb +82 -0
  34. data/lib/yoda/evaluation/code_completion/variable_provider.rb +18 -0
  35. data/lib/yoda/evaluation/comment_completion.rb +70 -0
  36. data/lib/yoda/evaluation/comment_completion/base_provider.rb +64 -0
  37. data/lib/yoda/evaluation/comment_completion/param_provider.rb +18 -0
  38. data/lib/yoda/evaluation/comment_completion/tag_provider.rb +41 -0
  39. data/lib/yoda/evaluation/comment_completion/type_provider.rb +58 -0
  40. data/lib/yoda/evaluation/current_node_explain.rb +70 -0
  41. data/lib/yoda/evaluation/evaluator.rb +103 -0
  42. data/lib/yoda/evaluation/signature_discovery.rb +83 -0
  43. data/lib/yoda/model.rb +12 -0
  44. data/lib/yoda/model/completion_item.rb +56 -0
  45. data/lib/yoda/model/descriptions.rb +10 -0
  46. data/lib/yoda/model/descriptions/base.rb +26 -0
  47. data/lib/yoda/model/descriptions/function_description.rb +40 -0
  48. data/lib/yoda/model/descriptions/value_description.rb +33 -0
  49. data/lib/yoda/model/descriptions/word_description.rb +32 -0
  50. data/lib/yoda/model/function_signatures.rb +13 -0
  51. data/lib/yoda/model/function_signatures/base.rb +68 -0
  52. data/lib/yoda/model/function_signatures/constructor.rb +70 -0
  53. data/lib/yoda/model/function_signatures/formatter.rb +82 -0
  54. data/lib/yoda/model/function_signatures/method.rb +67 -0
  55. data/lib/yoda/model/function_signatures/overload.rb +79 -0
  56. data/lib/yoda/model/function_signatures/parameter_list.rb +108 -0
  57. data/lib/yoda/model/function_signatures/type_builder.rb +101 -0
  58. data/lib/yoda/model/node_signature.rb +28 -0
  59. data/lib/yoda/model/path.rb +96 -0
  60. data/lib/yoda/model/scoped_path.rb +44 -0
  61. data/lib/yoda/model/types.rb +84 -0
  62. data/lib/yoda/model/types/any_type.rb +32 -0
  63. data/lib/yoda/model/types/base.rb +37 -0
  64. data/lib/yoda/model/types/duck_type.rb +41 -0
  65. data/lib/yoda/model/types/function_type.rb +174 -0
  66. data/lib/yoda/model/types/generic_type.rb +66 -0
  67. data/lib/yoda/model/types/instance_type.rb +42 -0
  68. data/lib/yoda/model/types/module_type.rb +42 -0
  69. data/lib/yoda/model/types/sequence_type.rb +53 -0
  70. data/lib/yoda/model/types/union_type.rb +56 -0
  71. data/lib/yoda/model/types/unknown_type.rb +40 -0
  72. data/lib/yoda/model/types/value_type.rb +58 -0
  73. data/lib/yoda/model/values.rb +9 -0
  74. data/lib/yoda/model/values/base.rb +32 -0
  75. data/lib/yoda/model/values/instance_value.rb +65 -0
  76. data/lib/yoda/model/values/module_value.rb +72 -0
  77. data/lib/yoda/parsing.rb +15 -0
  78. data/lib/yoda/parsing/ast_traversable.rb +18 -0
  79. data/lib/yoda/parsing/comment_tokenizer.rb +59 -0
  80. data/lib/yoda/parsing/location.rb +101 -0
  81. data/lib/yoda/parsing/node_objects.rb +10 -0
  82. data/lib/yoda/parsing/node_objects/const_node.rb +52 -0
  83. data/lib/yoda/parsing/node_objects/method_definition.rb +46 -0
  84. data/lib/yoda/parsing/node_objects/namespace.rb +104 -0
  85. data/lib/yoda/parsing/node_objects/send_node.rb +72 -0
  86. data/lib/yoda/parsing/parser.rb +27 -0
  87. data/lib/yoda/parsing/query.rb +11 -0
  88. data/lib/yoda/parsing/query/current_comment_query.rb +80 -0
  89. data/lib/yoda/parsing/query/current_comment_token_query.rb +153 -0
  90. data/lib/yoda/parsing/query/current_commenting_node_query.rb +68 -0
  91. data/lib/yoda/parsing/query/current_location_node_query.rb +51 -0
  92. data/lib/yoda/parsing/query/current_node_comment_query.rb +40 -0
  93. data/lib/yoda/parsing/range.rb +41 -0
  94. data/lib/yoda/parsing/scopes.rb +15 -0
  95. data/lib/yoda/parsing/scopes/base.rb +78 -0
  96. data/lib/yoda/parsing/scopes/builder.rb +60 -0
  97. data/lib/yoda/parsing/scopes/class_definition.rb +47 -0
  98. data/lib/yoda/parsing/scopes/meta_class_definition.rb +44 -0
  99. data/lib/yoda/parsing/scopes/meta_method_definition.rb +70 -0
  100. data/lib/yoda/parsing/scopes/method_definition.rb +69 -0
  101. data/lib/yoda/parsing/scopes/module_definition.rb +36 -0
  102. data/lib/yoda/parsing/scopes/root.rb +25 -0
  103. data/lib/yoda/parsing/source_analyzer.rb +59 -0
  104. data/lib/yoda/parsing/source_cutter.rb +231 -0
  105. data/lib/yoda/parsing/type_parser.rb +141 -0
  106. data/lib/yoda/runner.rb +6 -0
  107. data/lib/yoda/runner/infer.rb +50 -0
  108. data/lib/yoda/runner/setup.rb +26 -0
  109. data/lib/yoda/server.rb +191 -0
  110. data/lib/yoda/server/client_info.rb +98 -0
  111. data/lib/yoda/server/completion_provider.rb +78 -0
  112. data/lib/yoda/server/definition_provider.rb +36 -0
  113. data/lib/yoda/server/deserializer.rb +27 -0
  114. data/lib/yoda/server/hover_provider.rb +38 -0
  115. data/lib/yoda/server/signature_provider.rb +46 -0
  116. data/lib/yoda/store.rb +13 -0
  117. data/lib/yoda/store/actions.rb +10 -0
  118. data/lib/yoda/store/actions/import_core_library.rb +30 -0
  119. data/lib/yoda/store/actions/import_gems.rb +91 -0
  120. data/lib/yoda/store/actions/read_file.rb +36 -0
  121. data/lib/yoda/store/actions/read_project_files.rb +29 -0
  122. data/lib/yoda/store/adapters.rb +14 -0
  123. data/lib/yoda/store/adapters/base.rb +58 -0
  124. data/lib/yoda/store/adapters/leveldb_adapter.rb +80 -0
  125. data/lib/yoda/store/adapters/lmdb_adapter.rb +113 -0
  126. data/lib/yoda/store/objects.rb +46 -0
  127. data/lib/yoda/store/objects/addressable.rb +25 -0
  128. data/lib/yoda/store/objects/base.rb +116 -0
  129. data/lib/yoda/store/objects/class_object.rb +51 -0
  130. data/lib/yoda/store/objects/merger.rb +94 -0
  131. data/lib/yoda/store/objects/meta_class_object.rb +41 -0
  132. data/lib/yoda/store/objects/method_object.rb +94 -0
  133. data/lib/yoda/store/objects/module_object.rb +11 -0
  134. data/lib/yoda/store/objects/namespace_object.rb +67 -0
  135. data/lib/yoda/store/objects/overload.rb +51 -0
  136. data/lib/yoda/store/objects/patch.rb +46 -0
  137. data/lib/yoda/store/objects/patch_set.rb +80 -0
  138. data/lib/yoda/store/objects/tag.rb +62 -0
  139. data/lib/yoda/store/objects/value_object.rb +45 -0
  140. data/lib/yoda/store/project.rb +159 -0
  141. data/lib/yoda/store/query.rb +12 -0
  142. data/lib/yoda/store/query/associators.rb +10 -0
  143. data/lib/yoda/store/query/associators/associate_ancestors.rb +103 -0
  144. data/lib/yoda/store/query/associators/associate_methods.rb +38 -0
  145. data/lib/yoda/store/query/base.rb +16 -0
  146. data/lib/yoda/store/query/find_constant.rb +150 -0
  147. data/lib/yoda/store/query/find_meta_class.rb +18 -0
  148. data/lib/yoda/store/query/find_method.rb +74 -0
  149. data/lib/yoda/store/query/find_signature.rb +43 -0
  150. data/lib/yoda/store/registry.rb +67 -0
  151. data/lib/yoda/store/yard_importer.rb +260 -0
  152. data/lib/yoda/typing.rb +10 -0
  153. data/lib/yoda/typing/context.rb +96 -0
  154. data/lib/yoda/typing/environment.rb +35 -0
  155. data/lib/yoda/typing/evaluator.rb +256 -0
  156. data/lib/yoda/typing/lexical_scope.rb +26 -0
  157. data/lib/yoda/typing/relation.rb +15 -0
  158. data/lib/yoda/typing/traces.rb +9 -0
  159. data/lib/yoda/typing/traces/base.rb +26 -0
  160. data/lib/yoda/typing/traces/normal.rb +22 -0
  161. data/lib/yoda/typing/traces/send.rb +26 -0
  162. data/lib/yoda/version.rb +3 -0
  163. data/lib/yoda/yard_extensions.rb +11 -0
  164. data/lib/yoda/yard_extensions/sig_directive.rb +40 -0
  165. data/lib/yoda/yard_extensions/type_tag.rb +10 -0
  166. data/package.json +76 -0
  167. data/scripts/benchmark.rb +6 -0
  168. data/scripts/build_core_index.sh +16 -0
  169. data/yarn.lock +13 -0
  170. data/yoda-language-server.gemspec +40 -0
  171. metadata +424 -0
@@ -0,0 +1,96 @@
1
+ module Yoda
2
+ module Model
3
+ class Path
4
+ attr_reader :name
5
+
6
+ # @param path [Path, String]
7
+ # @return [Path]
8
+ def self.build(path)
9
+ path.is_a?(Path) ? path : new(path)
10
+ end
11
+
12
+ # @param names [Array<Path, String>]
13
+ # @return [Path]
14
+ def self.from_names(names)
15
+ new(names.join('::'))
16
+ end
17
+
18
+ # @param name [String]
19
+ def initialize(name)
20
+ fail ArgumentError, name unless name.is_a?(String)
21
+ @name = name
22
+ end
23
+
24
+ def absolute?
25
+ name.start_with?('::')
26
+ end
27
+
28
+ # @return [String]
29
+ def basename
30
+ @basename ||= begin
31
+ if name.end_with?('::')
32
+ ''
33
+ else
34
+ name.split('::').last || ''
35
+ end
36
+ end
37
+ end
38
+
39
+ # @return [String]
40
+ def spacename
41
+ @spacename ||= begin
42
+ if name.end_with?('::')
43
+ name.gsub(/::\Z/, '')
44
+ else
45
+ name.split('::').slice(0..-2).join('::')
46
+ end
47
+ end
48
+ end
49
+
50
+ # @return [String]
51
+ def to_s
52
+ name
53
+ end
54
+
55
+ def split
56
+ name.gsub(/\A::/, '').split('::') + (name.end_with?('::') ? [''] : [])
57
+ end
58
+
59
+ # @param another [Path, String]
60
+ # @return [Path]
61
+ def concat(another)
62
+ if self.class.build(another).absolute?
63
+ self
64
+ else
65
+ self.class.new([self.to_s, another.to_s].reject(&:empty?).join('::'))
66
+ end
67
+ end
68
+
69
+ # @return [Array<String>]
70
+ def namespaces
71
+ name.split('::')
72
+ end
73
+
74
+ # @return [Array<Path>]
75
+ def parent_paths
76
+ if spacename.empty?
77
+ []
78
+ else
79
+ [spacename] + Path.new(spacename).parent_paths
80
+ end
81
+ end
82
+
83
+ def hash
84
+ [self.class.name, name].hash
85
+ end
86
+
87
+ def ==(another)
88
+ eql?(another)
89
+ end
90
+
91
+ def eql?(another)
92
+ another.is_a?(Path) && name == another.name
93
+ end
94
+ end
95
+ end
96
+ end
@@ -0,0 +1,44 @@
1
+ module Yoda
2
+ module Model
3
+ # ScopedPath represents a path name written in namespaces.
4
+ # ScopedPath owns lexical scopes where the path is written.
5
+ class ScopedPath
6
+ # @return [Array<Path>] represents namespaces in order of nearness.
7
+ attr_reader :scopes
8
+
9
+ # @return [Path]
10
+ attr_reader :path
11
+
12
+ # @param path [Path]
13
+ # @return [ScopedPath]
14
+ def self.build(path)
15
+ path.is_a?(ScopedPath) ? path : ScopedPath.new(['Object'], Path.build(path))
16
+ end
17
+
18
+ # @param scopes [Array<Path>] represents namespaces in order of nearness.
19
+ # @param path [Path]
20
+ def initialize(scopes, path)
21
+ @scopes = scopes.map { |pa| Path.build(pa) }
22
+ @path = Path.build(path)
23
+ end
24
+
25
+ # @param paths [Array<String, Path>]
26
+ # @return [ScopedPath]
27
+ def change_scope(paths)
28
+ self.class.new(paths, path)
29
+ end
30
+
31
+ def hash
32
+ [self.class.name, scopes, path].hash
33
+ end
34
+
35
+ def ==(another)
36
+ eql?(another)
37
+ end
38
+
39
+ def eql?(another)
40
+ another.is_a?(ScopedPath) && path == another.path && scopes == another.scopes
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,84 @@
1
+ require 'parslet'
2
+
3
+ module Yoda
4
+ module Model
5
+ module Types
6
+ require 'yoda/model/types/base'
7
+ require 'yoda/model/types/any_type'
8
+ require 'yoda/model/types/value_type'
9
+ require 'yoda/model/types/instance_type'
10
+ require 'yoda/model/types/function_type'
11
+ require 'yoda/model/types/duck_type'
12
+ require 'yoda/model/types/module_type'
13
+ require 'yoda/model/types/sequence_type'
14
+ require 'yoda/model/types/generic_type'
15
+ require 'yoda/model/types/union_type'
16
+ require 'yoda/model/types/unknown_type'
17
+
18
+ # @param string [String]
19
+ # @return [Types::Base]
20
+ def self.parse(string)
21
+ Parsing::Generator.new.apply(Parsing::Parser.new.parse(string))
22
+ rescue Parslet::ParseFailed => failure
23
+ Types::UnknownType.new(string)
24
+ end
25
+
26
+ # @param strings [Array<String>]
27
+ # @return [Types::Base]
28
+ def self.parse_type_strings(strings)
29
+ Types::UnionType.new(strings.map { |string| parse(string) })
30
+ end
31
+
32
+ module Parsing
33
+ class Parser < Parslet::Parser
34
+ rule(:method_name) { match('[a-z]') >> match('[a-zA-Z0-9_]').repeat }
35
+ rule(:duck_type) { str('#') >> method_name.as(:method_name) }
36
+ rule(:constant_name) { match('[A-Z]') >> match('[a-zA-Z0-9_]').repeat }
37
+ rule(:constant_full_name) { str('::').maybe >> (constant_name >> (str('::') | str('.'))).repeat >> constant_name }
38
+ rule(:value_name) { match('[a-z0-9]') >> match('[a-zA-Z0-9_]').repeat }
39
+
40
+ rule(:space) { match('\s').repeat(1) }
41
+ rule(:space?) { space.maybe }
42
+
43
+ rule(:constant_type) { value_name.as(:value) | constant_full_name.as(:instance_type) }
44
+
45
+ rule(:key_value_type) { constant_type.as(:base_type) >> str('{') >> space? >> type.as(:key_type) >> space? >> str('=>') >> space? >> type.as(:value_type) >> space? >> str('}') }
46
+ rule(:sequence_type) { constant_type.as(:base_type) >> str('(') >> space? >> types.as(:value_types) >> space? >> str(')') }
47
+ rule(:generic_type) { constant_type.as(:base_type) >> (str('<') >> space? >> type >> space? >> str('>')).repeat(1).as(:type_arguments) }
48
+
49
+ rule(:shorthand_key_value) { str('{') >> space? >> type.as(:key_type) >> space? >> str('=>') >> space? >> type.as(:value_type) >> space? >> str('}') }
50
+ rule(:shorthand_sequence) { str('(') >> space? >> types.as(:value_types) >> space? >> str(')') }
51
+ rule(:shorthand_array) { str('<') >> space? >> type.as(:type_in_array) >> space? >> str('>') }
52
+
53
+ rule(:union_type) { types.as(:types) }
54
+
55
+ rule(:single_type) { duck_type | shorthand_key_value | shorthand_array | shorthand_sequence | generic_type | key_value_type | sequence_type | constant_type }
56
+ rule(:types) { (single_type >> str(',') >> space?).repeat >> space? >> single_type }
57
+
58
+ rule(:type) { union_type }
59
+ rule(:base) { space? >> type >> space? }
60
+ root :base
61
+ end
62
+
63
+ class Generator < Parslet::Transform
64
+ rule(instance_type: simple(:instance_type)) { Types::InstanceType.new(instance_type.to_s) }
65
+ rule(value: simple(:value)) { Types::ValueType.new(value.to_s) }
66
+
67
+ rule(base_type: simple(:base_type), key_type: simple(:key_type), value_type: simple(:value_type)) { Types::GenericType.from_key_value(base_type, key_type, value_type) }
68
+ rule(base_type: simple(:base_type), value_types: sequence(:value_types)) { Types::SequenceType.new(base_type, value_types) }
69
+ rule(base_type: simple(:base_type), value_types: simple(:value_type)) { Types::SequenceType.new(base_type, [value_type]) }
70
+ rule(base_type: simple(:base_type), type_arguments: sequence(:type_arguments)) { Types::GenericType.new(base_type, type_arguments) }
71
+
72
+ rule(method_name: simple(:method_name)) { Types::DuckType.new(method_name) }
73
+ rule(key_type: simple(:key_type), value_type: simple(:value_type)) { Types::GenericType.from_key_value(Types::InstanceType.new('::Hash'), key_type, value_type) }
74
+ rule(value_types: sequence(:value_types)) { Types::SequenceType.new(Types::InstanceType.new('::Array'), value_types) }
75
+ rule(value_types: simple(:value_type)) { Types::SequenceType.new(Types::InstanceType.new('::Array'), [value_type]) }
76
+ rule(type_in_array: simple(:type)) { Types::GenericType.new(Types::InstanceType.new('::Array'), [type]) }
77
+
78
+ rule(types: sequence(:types)) { Types::UnionType.new(types) }
79
+ rule(types: simple(:type)) { type }
80
+ end
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,32 @@
1
+ module Yoda
2
+ module Model
3
+ module Types
4
+ class AnyType < Base
5
+ def eql?(another)
6
+ another.is_a?(AnyType)
7
+ end
8
+
9
+ def hash
10
+ [self.class.name].hash
11
+ end
12
+
13
+ # @param paths [Array<Paths>]
14
+ # @return [self]
15
+ def change_root(paths)
16
+ self
17
+ end
18
+
19
+ # @param registry [Registry]
20
+ # @return [Array<Store::Objects::Base>]
21
+ def resolve(registry)
22
+ []
23
+ end
24
+
25
+ # @return [String]
26
+ def to_s
27
+ value
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
@@ -0,0 +1,37 @@
1
+ module Yoda
2
+ module Model
3
+ module Types
4
+ # @abstract
5
+ class Base
6
+ def ==(another)
7
+ eql?(another)
8
+ end
9
+
10
+ # @abstract
11
+ # @param paths [Array<Path>]
12
+ # @return [Base]
13
+ def change_root(paths)
14
+ fail NotImplementedError
15
+ end
16
+
17
+ # @abstract
18
+ # @param registry [Registry]
19
+ # @return [Array<Store::Objects::Base>]
20
+ def resolve(registry)
21
+ fail NotImplementedError
22
+ end
23
+
24
+ # @abstract
25
+ # @return [String]
26
+ def to_s
27
+ fail NotImplementedError
28
+ end
29
+
30
+ # @return [Base]
31
+ def map
32
+ yield self
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,41 @@
1
+ module Yoda
2
+ module Model
3
+ module Types
4
+ class DuckType < Base
5
+ attr_reader :method_name
6
+
7
+ # @param method_name [String]
8
+ def initialize(method_name)
9
+ @method_name = method_name
10
+ end
11
+
12
+ # @param another [Object]
13
+ def eql?(another)
14
+ another.is_a?(DuckType) &&
15
+ method_name == another.method_name
16
+ end
17
+
18
+ def hash
19
+ [self.class.name, method_name].hash
20
+ end
21
+
22
+ # @param paths [Array<Paths>]
23
+ # @return [self]
24
+ def change_root(paths)
25
+ self
26
+ end
27
+
28
+ # @param registry [Registry]
29
+ # @return [Array<Store::Objects::Base>]
30
+ def resolve(registry)
31
+ []
32
+ end
33
+
34
+ # @return [String]
35
+ def to_s
36
+ "##{method_name}"
37
+ end
38
+ end
39
+ end
40
+ end
41
+ end
@@ -0,0 +1,174 @@
1
+ module Yoda
2
+ module Model
3
+ module Types
4
+ class FunctionType < Base
5
+ # @return [Base, nil]
6
+ attr_reader :context
7
+
8
+ # @return [Array<Base>]
9
+ attr_reader :required_parameters, :optional_parameters, :post_parameters
10
+
11
+ # @return [Array<(String, Base)>]
12
+ attr_reader :required_keyword_parameters
13
+
14
+ # @return [Array<(String, Base)>]
15
+ attr_reader :optional_keyword_parameters
16
+
17
+ # @return [Base, nil]
18
+ attr_reader :rest_parameter, :keyword_rest_parameter, :block_parameter
19
+
20
+ # @return [Base]
21
+ attr_reader :return_type
22
+
23
+ # @param context [Base, nil]
24
+ # @param required_parameters [Array<Base>]
25
+ # @param optional_parameters [Array<Base>]
26
+ # @param rest_parameter [Base, nil]
27
+ # @param post_parameters [Array<Base>]
28
+ # @param keyword_parameters [Array<(String, Base)>]
29
+ # @param keyword_rest_parameter [Base, nil]
30
+ # @param block_parameter [Base, nil]
31
+ # @param return_type [Base]
32
+ def initialize(context: nil, return_type:, required_parameters: [], optional_parameters: [], rest_parameter: nil, post_parameters: [], optional_keyword_parameters: [], required_keyword_parameters: [], keyword_rest_parameter: nil, block_parameter: nil)
33
+ @context = context
34
+ @required_parameters = required_parameters
35
+ @optional_parameters = optional_parameters
36
+ @required_keyword_parameters = required_keyword_parameters
37
+ @optional_keyword_parameters = optional_keyword_parameters
38
+ @rest_parameter = rest_parameter
39
+ @post_parameters = post_parameters
40
+ @keyword_rest_parameter = keyword_rest_parameter
41
+ @block_parameter = block_parameter
42
+ @return_type = return_type
43
+ end
44
+
45
+ def eql?(another)
46
+ another.is_a?(FunctionType) &&
47
+ context == another.context &&
48
+ required_parameters == another.required_parameters &&
49
+ optional_parameters == another.optional_parameters &&
50
+ required_keyword_parameters.to_set == another.required_keyword_parameters.to_set &&
51
+ optional_keyword_parameters.to_set == another.optional_keyword_parameters.to_set &&
52
+ keyword_rest_parameter == another.keyword_rest_parameter &&
53
+ rest_parameter == another.rest_parameter &&
54
+ post_parameters == another.post_parameters &&
55
+ block_parameter == another.block_parameter &&
56
+ return_type == another.return_type
57
+ end
58
+
59
+ def hash
60
+ [
61
+ self.class.name,
62
+ context,
63
+ return_type,
64
+ required_parameters,
65
+ optional_parameters,
66
+ rest_parameter,
67
+ post_parameters,
68
+ required_keyword_parameters,
69
+ optional_keyword_parameters,
70
+ keyword_rest_parameter,
71
+ block_parameter,
72
+ ].hash
73
+ end
74
+
75
+ # @param namespace [YARD::CodeObjects::Base]
76
+ # @return [UnionType]
77
+ def change_root(namespace)
78
+ self.class.new(
79
+ context: context&.change_root(namespace),
80
+ return_type: return_type.change_root(namespace),
81
+ required_parameters: required_parameters.map { |param| param.change_root(namespace) },
82
+ optional_parameters: optional_parameters.map { |param| param.change_root(namespace) },
83
+ rest_parameter: rest_parameter&.change_root(namespace),
84
+ post_parameters: post_parameters.map { |param| param.change_root(namespace) },
85
+ required_keyword_parameters: required_keyword_parameters.map { |name, param| [name, param.change_root(namespace)] },
86
+ optional_keyword_parameters: required_keyword_parameters.map { |name, param| [name, param.change_root(namespace)] },
87
+ keyword_rest_parameter: keyword_rest_parameter&.change_root(namespace),
88
+ block_parameter: block_parameter&.change_root(namespace),
89
+ )
90
+ end
91
+
92
+ # @param registry [Registry]
93
+ # @return [Array<Store::Objects::Base>]
94
+ def resolve(registry)
95
+ []
96
+ end
97
+
98
+ def method_type_signature
99
+ params_str = all_parameters_to_s
100
+ (params_str.empty? ? ': ' : "(#{params_str}): ") + "#{return_type}"
101
+ end
102
+
103
+ def to_s
104
+ params_str = all_parameters_to_s
105
+ (params_str.empty? ? '' : "(#{params_str}) -> ") + "#{return_type}"
106
+ end
107
+
108
+ # @return [self]
109
+ def map(&block)
110
+ self.class.new(
111
+ context: context&.map(&block),
112
+ return_type: return_type.map(&block),
113
+ required_parameters: required_parameters.map { |param| param.map(&block) },
114
+ optional_parameters: optional_parameters.map { |param| param.map(&block) },
115
+ rest_parameter: rest_parameter&.map(&block),
116
+ post_parameters: post_parameters.map { |param| param.map(&block) },
117
+ required_keyword_parameters: required_keyword_parameters.map { |name, param| [name, param.map(&block)] },
118
+ optional_keyword_parameters: required_keyword_parameters.map { |name, param| [name, param.map(&block)] },
119
+ keyword_rest_parameter: keyword_rest_parameter&.map(&block),
120
+ block_parameter: block_parameter&.map(&block),
121
+ )
122
+ end
123
+
124
+ private
125
+
126
+ def all_parameters_to_s
127
+ [
128
+ required_parameters_to_s,
129
+ optional_parameters_to_s,
130
+ rest_parameter_to_s,
131
+ post_parameters_to_s,
132
+ keyword_parameters_to_s,
133
+ keyword_rest_parameter_to_s,
134
+ block_parameter_to_s
135
+ ].reject { |str| str.empty? }.join(', ')
136
+ end
137
+
138
+ def required_parameters_to_s
139
+ required_parameters.map { |type| type.to_s }.join(', ')
140
+ end
141
+
142
+ def optional_parameters_to_s
143
+ optional_parameters.map { |type| "?#{type}" }.join(', ')
144
+ end
145
+
146
+ def required_keyword_parameters_to_s
147
+ return '' if required_keyword_parameters.empty?
148
+ required_keyword_parameters.map { |(name, type)| "#{name}: #{type}" }.join(', ')
149
+ end
150
+
151
+ def optional_keyword_parameters_to_s
152
+ return '' if optional_keyword_parameters.empty?
153
+ optional_keyword_parameters.map { |(name, type)| "?#{name}: #{type}" }.join(', ')
154
+ end
155
+
156
+ def post_parameters_to_s
157
+ post_parameters.map { |type| type.to_s }.join(', ')
158
+ end
159
+
160
+ def rest_parameter_to_s
161
+ rest_parameter ? "*#{rest_parameter}" : ''
162
+ end
163
+
164
+ def keyword_rest_parameter_to_s
165
+ keyword_rest_parameter ? "**#{keyword_rest_parameter}" : ''
166
+ end
167
+
168
+ def block_parameter_to_s
169
+ block_parameter ? "&#{block_parameter}" : ''
170
+ end
171
+ end
172
+ end
173
+ end
174
+ end