solargraph 0.54.0 → 0.58.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/.github/workflows/linting.yml +127 -0
- data/.github/workflows/plugins.yml +184 -6
- data/.github/workflows/rspec.yml +55 -5
- data/.github/workflows/typecheck.yml +8 -3
- data/.gitignore +7 -0
- data/.overcommit.yml +72 -0
- data/.rspec +1 -0
- data/.rubocop.yml +66 -0
- data/.rubocop_todo.yml +1279 -0
- data/.yardopts +1 -0
- data/CHANGELOG.md +171 -0
- data/README.md +20 -6
- data/Rakefile +125 -13
- data/bin/solargraph +8 -5
- data/lib/solargraph/api_map/cache.rb +13 -3
- data/lib/solargraph/api_map/constants.rb +279 -0
- data/lib/solargraph/api_map/index.rb +193 -0
- data/lib/solargraph/api_map/source_to_yard.rb +13 -4
- data/lib/solargraph/api_map/store.rb +207 -132
- data/lib/solargraph/api_map.rb +394 -261
- data/lib/solargraph/bench.rb +18 -1
- data/lib/solargraph/complex_type/type_methods.rb +29 -12
- data/lib/solargraph/complex_type/unique_type.rb +205 -26
- data/lib/solargraph/complex_type.rb +126 -26
- data/lib/solargraph/convention/active_support_concern.rb +111 -0
- data/lib/solargraph/convention/base.rb +20 -3
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +61 -0
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +91 -0
- data/lib/solargraph/convention/data_definition.rb +105 -0
- data/lib/solargraph/convention/gemspec.rb +3 -2
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +61 -0
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +102 -0
- data/lib/solargraph/convention/struct_definition.rb +164 -0
- data/lib/solargraph/convention.rb +36 -4
- data/lib/solargraph/diagnostics/rubocop.rb +6 -1
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/doc_map.rb +316 -64
- data/lib/solargraph/environ.rb +9 -2
- data/lib/solargraph/equality.rb +34 -0
- data/lib/solargraph/gem_pins.rb +64 -38
- data/lib/solargraph/language_server/host/dispatch.rb +2 -0
- data/lib/solargraph/language_server/host/message_worker.rb +54 -5
- data/lib/solargraph/language_server/host.rb +36 -18
- data/lib/solargraph/language_server/message/base.rb +20 -12
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +2 -0
- data/lib/solargraph/language_server/message/extended/document.rb +5 -2
- data/lib/solargraph/language_server/message/extended/document_gems.rb +3 -3
- data/lib/solargraph/language_server/message/initialize.rb +3 -1
- data/lib/solargraph/language_server/message/text_document/completion.rb +0 -3
- data/lib/solargraph/language_server/message/text_document/definition.rb +5 -3
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +3 -3
- data/lib/solargraph/language_server/message/text_document/formatting.rb +23 -2
- data/lib/solargraph/language_server/message/text_document/hover.rb +1 -1
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +4 -3
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +2 -0
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -2
- data/lib/solargraph/language_server/progress.rb +27 -2
- data/lib/solargraph/language_server/request.rb +4 -1
- data/lib/solargraph/library.rb +83 -73
- data/lib/solargraph/location.rb +45 -1
- data/lib/solargraph/logging.rb +12 -2
- data/lib/solargraph/page.rb +3 -0
- data/lib/solargraph/parser/comment_ripper.rb +20 -7
- data/lib/solargraph/parser/flow_sensitive_typing.rb +255 -0
- data/lib/solargraph/parser/node_processor/base.rb +10 -5
- data/lib/solargraph/parser/node_processor.rb +26 -8
- data/lib/solargraph/parser/parser_gem/class_methods.rb +10 -18
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_methods.rb +10 -19
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +26 -20
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +7 -4
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +6 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +4 -2
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +14 -2
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +8 -7
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +16 -6
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +64 -32
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +29 -0
- data/lib/solargraph/parser/parser_gem/node_processors.rb +14 -0
- data/lib/solargraph/parser/region.rb +4 -1
- data/lib/solargraph/parser/snippet.rb +2 -0
- data/lib/solargraph/parser.rb +3 -5
- data/lib/solargraph/pin/base.rb +417 -42
- data/lib/solargraph/pin/base_variable.rb +21 -12
- data/lib/solargraph/pin/block.rb +9 -26
- data/lib/solargraph/pin/breakable.rb +9 -0
- data/lib/solargraph/pin/callable.rb +231 -0
- data/lib/solargraph/pin/closure.rb +30 -10
- data/lib/solargraph/pin/common.rb +12 -7
- data/lib/solargraph/pin/constant.rb +2 -0
- data/lib/solargraph/pin/conversions.rb +3 -2
- data/lib/solargraph/pin/delegated_method.rb +20 -1
- data/lib/solargraph/pin/documenting.rb +16 -0
- data/lib/solargraph/pin/instance_variable.rb +2 -2
- data/lib/solargraph/pin/keyword.rb +7 -2
- data/lib/solargraph/pin/local_variable.rb +15 -7
- data/lib/solargraph/pin/method.rb +241 -70
- data/lib/solargraph/pin/method_alias.rb +3 -0
- data/lib/solargraph/pin/namespace.rb +21 -13
- data/lib/solargraph/pin/parameter.rb +94 -32
- data/lib/solargraph/pin/proxy_type.rb +17 -7
- data/lib/solargraph/pin/reference/override.rb +24 -6
- data/lib/solargraph/pin/reference/require.rb +2 -2
- data/lib/solargraph/pin/reference/superclass.rb +5 -0
- data/lib/solargraph/pin/reference.rb +17 -0
- data/lib/solargraph/pin/search.rb +6 -1
- data/lib/solargraph/pin/signature.rb +39 -121
- data/lib/solargraph/pin/singleton.rb +1 -1
- data/lib/solargraph/pin/symbol.rb +8 -2
- data/lib/solargraph/pin/until.rb +18 -0
- data/lib/solargraph/pin/while.rb +18 -0
- data/lib/solargraph/pin.rb +8 -2
- data/lib/solargraph/pin_cache.rb +245 -0
- data/lib/solargraph/position.rb +19 -0
- data/lib/solargraph/range.rb +23 -4
- data/lib/solargraph/rbs_map/conversions.rb +315 -99
- data/lib/solargraph/rbs_map/core_fills.rb +50 -16
- data/lib/solargraph/rbs_map/core_map.rb +41 -11
- data/lib/solargraph/rbs_map/stdlib_map.rb +15 -5
- data/lib/solargraph/rbs_map.rb +87 -16
- data/lib/solargraph/shell.rb +117 -17
- data/lib/solargraph/source/chain/array.rb +13 -8
- data/lib/solargraph/source/chain/block_symbol.rb +1 -1
- data/lib/solargraph/source/chain/block_variable.rb +1 -1
- data/lib/solargraph/source/chain/call.rb +135 -66
- data/lib/solargraph/source/chain/constant.rb +3 -66
- data/lib/solargraph/source/chain/hash.rb +9 -3
- data/lib/solargraph/source/chain/head.rb +1 -1
- data/lib/solargraph/source/chain/if.rb +7 -2
- data/lib/solargraph/source/chain/link.rb +38 -6
- data/lib/solargraph/source/chain/literal.rb +27 -2
- data/lib/solargraph/source/chain/or.rb +2 -2
- data/lib/solargraph/source/chain/z_super.rb +1 -1
- data/lib/solargraph/source/chain.rb +140 -63
- data/lib/solargraph/source/change.rb +2 -2
- data/lib/solargraph/source/cursor.rb +4 -4
- data/lib/solargraph/source/source_chainer.rb +3 -3
- data/lib/solargraph/source.rb +110 -89
- data/lib/solargraph/source_map/clip.rb +22 -28
- data/lib/solargraph/source_map/data.rb +34 -0
- data/lib/solargraph/source_map/mapper.rb +11 -7
- data/lib/solargraph/source_map.rb +50 -43
- data/lib/solargraph/type_checker/checks.rb +4 -0
- data/lib/solargraph/type_checker/param_def.rb +2 -0
- data/lib/solargraph/type_checker/rules.rb +35 -8
- data/lib/solargraph/type_checker.rb +331 -189
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/views/_method.erb +10 -10
- data/lib/solargraph/views/_namespace.erb +3 -3
- data/lib/solargraph/views/document.erb +10 -10
- data/lib/solargraph/views/environment.erb +3 -5
- data/lib/solargraph/workspace/config.rb +25 -5
- data/lib/solargraph/workspace/require_paths.rb +97 -0
- data/lib/solargraph/workspace.rb +53 -72
- data/lib/solargraph/yard_map/helpers.rb +29 -1
- data/lib/solargraph/yard_map/mapper/to_constant.rb +8 -5
- data/lib/solargraph/yard_map/mapper/to_method.rb +55 -19
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +11 -7
- data/lib/solargraph/yard_map/mapper.rb +5 -3
- data/lib/solargraph/yard_map/to_method.rb +6 -3
- data/lib/solargraph/yardoc.rb +45 -10
- data/lib/solargraph.rb +35 -1
- data/rbs/fills/bundler/0/bundler.rbs +4271 -0
- data/rbs/fills/open3/0/open3.rbs +172 -0
- data/rbs/fills/rubygems/0/basic_specification.rbs +326 -0
- data/rbs/fills/rubygems/0/errors.rbs +364 -0
- data/rbs/fills/rubygems/0/spec_fetcher.rbs +107 -0
- data/rbs/fills/rubygems/0/specification.rbs +1753 -0
- data/rbs/fills/tuple/tuple.rbs +149 -0
- data/rbs_collection.yaml +19 -0
- data/sig/shims/ast/0/node.rbs +5 -0
- data/sig/shims/ast/2.4/.rbs_meta.yaml +9 -0
- data/sig/shims/ast/2.4/ast.rbs +73 -0
- data/sig/shims/parser/3.2.0.1/builders/default.rbs +195 -0
- data/sig/shims/parser/3.2.0.1/manifest.yaml +7 -0
- data/sig/shims/parser/3.2.0.1/parser.rbs +201 -0
- data/sig/shims/parser/3.2.0.1/polyfill.rbs +4 -0
- data/sig/shims/thor/1.2.0.1/.rbs_meta.yaml +9 -0
- data/sig/shims/thor/1.2.0.1/manifest.yaml +7 -0
- data/sig/shims/thor/1.2.0.1/thor.rbs +17 -0
- data/solargraph.gemspec +32 -10
- metadata +237 -37
- data/lib/.rubocop.yml +0 -22
- data/lib/solargraph/cache.rb +0 -77
- data/lib/solargraph/parser/node_methods.rb +0 -83
data/lib/solargraph/bench.rb
CHANGED
|
@@ -11,18 +11,35 @@ module Solargraph
|
|
|
11
11
|
# @return [Workspace]
|
|
12
12
|
attr_reader :workspace
|
|
13
13
|
|
|
14
|
+
# @return [SourceMap]
|
|
15
|
+
attr_reader :live_map
|
|
16
|
+
|
|
14
17
|
# @return [Set<String>]
|
|
15
18
|
attr_reader :external_requires
|
|
16
19
|
|
|
17
20
|
# @param source_maps [Array<SourceMap>, Set<SourceMap>]
|
|
18
21
|
# @param workspace [Workspace]
|
|
22
|
+
# @param live_map [SourceMap, nil]
|
|
19
23
|
# @param external_requires [Array<String>, Set<String>]
|
|
20
|
-
def initialize source_maps: [], workspace: Workspace.new, external_requires: []
|
|
24
|
+
def initialize source_maps: [], workspace: Workspace.new, live_map: nil, external_requires: []
|
|
21
25
|
@source_maps = source_maps.to_set
|
|
22
26
|
@workspace = workspace
|
|
27
|
+
@live_map = live_map
|
|
23
28
|
@external_requires = external_requires.reject { |path| workspace.would_require?(path) }
|
|
24
29
|
.compact
|
|
25
30
|
.to_set
|
|
26
31
|
end
|
|
32
|
+
|
|
33
|
+
# @return [Hash{String => SourceMap}]
|
|
34
|
+
def source_map_hash
|
|
35
|
+
# @todo Work around #to_h bug in current Ruby head (3.5) with #map#to_h
|
|
36
|
+
@source_map_hash ||= source_maps.map { |s| [s.filename, s] }
|
|
37
|
+
.to_h
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# @return [Set<SourceMap>]
|
|
41
|
+
def icebox
|
|
42
|
+
@icebox ||= (source_maps - [live_map])
|
|
43
|
+
end
|
|
27
44
|
end
|
|
28
45
|
end
|
|
@@ -12,12 +12,20 @@ module Solargraph
|
|
|
12
12
|
# @rooted: boolish
|
|
13
13
|
# methods:
|
|
14
14
|
# transform()
|
|
15
|
+
# all_params()
|
|
16
|
+
# rooted?()
|
|
17
|
+
# can_root_name?()
|
|
15
18
|
module TypeMethods
|
|
16
19
|
# @!method transform(new_name = nil, &transform_type)
|
|
17
20
|
# @param new_name [String, nil]
|
|
18
21
|
# @yieldparam t [UniqueType]
|
|
19
22
|
# @yieldreturn [UniqueType]
|
|
20
23
|
# @return [UniqueType, nil]
|
|
24
|
+
# @!method all_params
|
|
25
|
+
# @return [Array<ComplexType>]
|
|
26
|
+
# @!method rooted?
|
|
27
|
+
# @!method can_root_name?(name_to_check = nil)
|
|
28
|
+
# @param name_to_check [String, nil]
|
|
21
29
|
|
|
22
30
|
# @return [String]
|
|
23
31
|
attr_reader :name
|
|
@@ -35,6 +43,10 @@ module Solargraph
|
|
|
35
43
|
@rooted_tag ||= rooted_name + rooted_substring
|
|
36
44
|
end
|
|
37
45
|
|
|
46
|
+
def interface?
|
|
47
|
+
name.start_with?('_')
|
|
48
|
+
end
|
|
49
|
+
|
|
38
50
|
# @return [Boolean]
|
|
39
51
|
def duck_type?
|
|
40
52
|
@duck_type ||= name.start_with?('#')
|
|
@@ -45,11 +57,6 @@ module Solargraph
|
|
|
45
57
|
@nil_type ||= (name.casecmp('nil') == 0)
|
|
46
58
|
end
|
|
47
59
|
|
|
48
|
-
# @return [Boolean]
|
|
49
|
-
def parameters?
|
|
50
|
-
!substring.empty?
|
|
51
|
-
end
|
|
52
|
-
|
|
53
60
|
def tuple?
|
|
54
61
|
@tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
|
|
55
62
|
end
|
|
@@ -85,6 +92,7 @@ module Solargraph
|
|
|
85
92
|
# @return [Symbol, nil]
|
|
86
93
|
attr_reader :parameters_type
|
|
87
94
|
|
|
95
|
+
# @type [Hash{String => Symbol}]
|
|
88
96
|
PARAMETERS_TYPE_BY_STARTING_TAG = {
|
|
89
97
|
'{' => :hash,
|
|
90
98
|
'(' => :fixed,
|
|
@@ -126,15 +134,23 @@ module Solargraph
|
|
|
126
134
|
end.call
|
|
127
135
|
end
|
|
128
136
|
|
|
137
|
+
# @return [self]
|
|
138
|
+
def namespace_type
|
|
139
|
+
return ComplexType.parse('::Object') if duck_type?
|
|
140
|
+
return ComplexType.parse('::NilClass') if nil_type?
|
|
141
|
+
return subtypes.first if (name == 'Class' || name == 'Module') && !subtypes.empty?
|
|
142
|
+
self
|
|
143
|
+
end
|
|
144
|
+
|
|
129
145
|
# @return [String]
|
|
130
146
|
def rooted_namespace
|
|
131
|
-
return namespace unless rooted?
|
|
147
|
+
return namespace unless rooted? && can_root_name?(namespace)
|
|
132
148
|
"::#{namespace}"
|
|
133
149
|
end
|
|
134
150
|
|
|
135
151
|
# @return [String]
|
|
136
152
|
def rooted_name
|
|
137
|
-
return name unless rooted?
|
|
153
|
+
return name unless @rooted && can_root_name?
|
|
138
154
|
"::#{name}"
|
|
139
155
|
end
|
|
140
156
|
|
|
@@ -161,7 +177,11 @@ module Solargraph
|
|
|
161
177
|
elsif fixed_parameters?
|
|
162
178
|
"(#{subtypes_str})"
|
|
163
179
|
else
|
|
164
|
-
|
|
180
|
+
if name == 'Hash'
|
|
181
|
+
"<#{key_types_str}, #{subtypes_str}>"
|
|
182
|
+
else
|
|
183
|
+
"<#{key_types_str}#{subtypes_str}>"
|
|
184
|
+
end
|
|
165
185
|
end
|
|
166
186
|
end
|
|
167
187
|
|
|
@@ -174,13 +194,10 @@ module Solargraph
|
|
|
174
194
|
# @param other [Object]
|
|
175
195
|
def == other
|
|
176
196
|
return false unless self.class == other.class
|
|
197
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
177
198
|
tag == other.tag
|
|
178
199
|
end
|
|
179
200
|
|
|
180
|
-
def rooted?
|
|
181
|
-
@rooted
|
|
182
|
-
end
|
|
183
|
-
|
|
184
201
|
# Generate a ComplexType that fully qualifies this type's namespaces.
|
|
185
202
|
#
|
|
186
203
|
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
@@ -7,9 +7,15 @@ module Solargraph
|
|
|
7
7
|
#
|
|
8
8
|
class UniqueType
|
|
9
9
|
include TypeMethods
|
|
10
|
+
include Equality
|
|
10
11
|
|
|
11
12
|
attr_reader :all_params, :subtypes, :key_types
|
|
12
13
|
|
|
14
|
+
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
15
|
+
protected def equality_fields
|
|
16
|
+
[@name, @all_params, @subtypes, @key_types]
|
|
17
|
+
end
|
|
18
|
+
|
|
13
19
|
# Create a UniqueType with the specified name and an optional substring.
|
|
14
20
|
# The substring is the parameter section of a parametrized type, e.g.,
|
|
15
21
|
# for the type `Array<String>`, the name is `Array` and the substring is
|
|
@@ -21,11 +27,13 @@ module Solargraph
|
|
|
21
27
|
# @return [UniqueType]
|
|
22
28
|
def self.parse name, substring = '', make_rooted: nil
|
|
23
29
|
if name.start_with?(':::')
|
|
24
|
-
raise "Illegal prefix: #{name}"
|
|
30
|
+
raise ComplexTypeError, "Illegal prefix: #{name}"
|
|
25
31
|
end
|
|
26
32
|
if name.start_with?('::')
|
|
27
33
|
name = name[2..-1]
|
|
28
34
|
rooted = true
|
|
35
|
+
elsif !can_root_name?(name)
|
|
36
|
+
rooted = true
|
|
29
37
|
else
|
|
30
38
|
rooted = false
|
|
31
39
|
end
|
|
@@ -40,12 +48,15 @@ module Solargraph
|
|
|
40
48
|
subs = ComplexType.parse(substring[1..-2], partial: true)
|
|
41
49
|
parameters_type = PARAMETERS_TYPE_BY_STARTING_TAG.fetch(substring[0])
|
|
42
50
|
if parameters_type == :hash
|
|
43
|
-
raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
51
|
+
raise ComplexTypeError, "Bad hash type: name=#{name}, substring=#{substring}" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(UniqueType) and !subs[1].is_a?(UniqueType)
|
|
52
|
+
key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
|
|
53
|
+
subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
|
|
54
|
+
elsif parameters_type == :list && name == 'Hash'
|
|
55
|
+
# Treat Hash<A, B> as Hash{A => B}
|
|
56
|
+
if subs.length != 2
|
|
57
|
+
raise ComplexTypeError, "Bad hash type: name=#{name}, substring=#{substring} - must have exactly two parameters"
|
|
58
|
+
end
|
|
47
59
|
key_types.concat(subs[0].map { |u| ComplexType.new([u]) })
|
|
48
|
-
# @sg-ignore
|
|
49
60
|
subtypes.concat(subs[1].map { |u| ComplexType.new([u]) })
|
|
50
61
|
else
|
|
51
62
|
subtypes.concat subs
|
|
@@ -63,21 +74,92 @@ module Solargraph
|
|
|
63
74
|
if parameters_type.nil?
|
|
64
75
|
raise "You must supply parameters_type if you provide parameters" unless key_types.empty? && subtypes.empty?
|
|
65
76
|
end
|
|
66
|
-
raise "Please remove leading :: and set rooted instead - #{name}" if name.start_with?('::')
|
|
77
|
+
raise "Please remove leading :: and set rooted instead - #{name.inspect}" if name.start_with?('::')
|
|
67
78
|
@name = name
|
|
68
|
-
@
|
|
69
|
-
|
|
79
|
+
@parameters_type = parameters_type
|
|
80
|
+
if implicit_union?
|
|
81
|
+
@key_types = key_types.uniq
|
|
82
|
+
@subtypes = subtypes.uniq
|
|
83
|
+
else
|
|
84
|
+
@key_types = key_types
|
|
85
|
+
@subtypes = subtypes
|
|
86
|
+
end
|
|
70
87
|
@rooted = rooted
|
|
71
88
|
@all_params = []
|
|
72
|
-
@all_params.concat key_types
|
|
73
|
-
@all_params.concat subtypes
|
|
74
|
-
|
|
89
|
+
@all_params.concat @key_types
|
|
90
|
+
@all_params.concat @subtypes
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def implicit_union?
|
|
94
|
+
# @todo use api_map to establish number of generics in type;
|
|
95
|
+
# if only one is allowed but multiple are passed in, treat
|
|
96
|
+
# those as implicit unions
|
|
97
|
+
['Hash', 'Array', 'Set', '_ToAry', 'Enumerable', '_Each'].include?(name) && parameters_type != :fixed
|
|
75
98
|
end
|
|
76
99
|
|
|
77
100
|
def to_s
|
|
78
101
|
tag
|
|
79
102
|
end
|
|
80
103
|
|
|
104
|
+
# @return [self]
|
|
105
|
+
def simplify_literals
|
|
106
|
+
transform do |t|
|
|
107
|
+
next t unless t.literal?
|
|
108
|
+
t.recreate(new_name: t.non_literal_name)
|
|
109
|
+
end
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
def literal?
|
|
113
|
+
non_literal_name != name
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# @return [String]
|
|
117
|
+
def non_literal_name
|
|
118
|
+
@non_literal_name ||= determine_non_literal_name
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
# @return [String]
|
|
122
|
+
def determine_non_literal_name
|
|
123
|
+
# https://github.com/ruby/rbs/blob/master/docs/syntax.md
|
|
124
|
+
#
|
|
125
|
+
# _literal_ ::= _string-literal_
|
|
126
|
+
# | _symbol-literal_
|
|
127
|
+
# | _integer-literal_
|
|
128
|
+
# | `true`
|
|
129
|
+
# | `false`
|
|
130
|
+
return name if name.empty?
|
|
131
|
+
return 'NilClass' if name == 'nil'
|
|
132
|
+
return 'Boolean' if ['true', 'false'].include?(name)
|
|
133
|
+
return 'Symbol' if name[0] == ':'
|
|
134
|
+
return 'String' if ['"', "'"].include?(name[0])
|
|
135
|
+
return 'Integer' if name.match?(/^-?\d+$/)
|
|
136
|
+
name
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def eql?(other)
|
|
140
|
+
self.class == other.class &&
|
|
141
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
142
|
+
@name == other.name &&
|
|
143
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
144
|
+
@key_types == other.key_types &&
|
|
145
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
146
|
+
@subtypes == other.subtypes &&
|
|
147
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
148
|
+
@rooted == other.rooted? &&
|
|
149
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
150
|
+
@all_params == other.all_params &&
|
|
151
|
+
# @sg-ignore https://github.com/castwide/solargraph/pull/1114
|
|
152
|
+
@parameters_type == other.parameters_type
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
def ==(other)
|
|
156
|
+
eql?(other)
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
def hash
|
|
160
|
+
[self.class, @name, @key_types, @sub_types, @rooted, @all_params, @parameters_type].hash
|
|
161
|
+
end
|
|
162
|
+
|
|
81
163
|
# @return [Array<UniqueType>]
|
|
82
164
|
def items
|
|
83
165
|
[self]
|
|
@@ -87,11 +169,18 @@ module Solargraph
|
|
|
87
169
|
def rbs_name
|
|
88
170
|
if name == 'undefined'
|
|
89
171
|
'untyped'
|
|
172
|
+
elsif literal?
|
|
173
|
+
name
|
|
90
174
|
else
|
|
91
175
|
rooted_name
|
|
92
176
|
end
|
|
93
177
|
end
|
|
94
178
|
|
|
179
|
+
# @return [String]
|
|
180
|
+
def desc
|
|
181
|
+
rooted_tags
|
|
182
|
+
end
|
|
183
|
+
|
|
95
184
|
# @return [String]
|
|
96
185
|
def to_rbs
|
|
97
186
|
if duck_type?
|
|
@@ -108,7 +197,11 @@ module Solargraph
|
|
|
108
197
|
# tuples don't have a name; they're just [foo, bar, baz].
|
|
109
198
|
if substring == '()'
|
|
110
199
|
# but there are no zero element tuples, so we go with an array
|
|
111
|
-
|
|
200
|
+
if rooted?
|
|
201
|
+
'::Array[]'
|
|
202
|
+
else
|
|
203
|
+
'Array[]'
|
|
204
|
+
end
|
|
112
205
|
else
|
|
113
206
|
# already generated surrounded by []
|
|
114
207
|
parameters_as_rbs
|
|
@@ -149,9 +242,26 @@ module Solargraph
|
|
|
149
242
|
name == GENERIC_TAG_NAME || all_params.any?(&:generic?)
|
|
150
243
|
end
|
|
151
244
|
|
|
245
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
246
|
+
# @param atype [ComplexType] type which may be assigned to this type
|
|
247
|
+
def can_assign?(api_map, atype)
|
|
248
|
+
logger.debug { "UniqueType#can_assign?(self=#{rooted_tags.inspect}, atype=#{atype.rooted_tags.inspect})" }
|
|
249
|
+
downcasted_atype = atype.downcast_to_literal_if_possible
|
|
250
|
+
out = downcasted_atype.all? do |autype|
|
|
251
|
+
autype.name == name || api_map.super_and_sub?(name, autype.name)
|
|
252
|
+
end
|
|
253
|
+
logger.debug { "UniqueType#can_assign?(self=#{rooted_tags.inspect}, atype=#{atype.rooted_tags.inspect}) => #{out}" }
|
|
254
|
+
out
|
|
255
|
+
end
|
|
256
|
+
|
|
257
|
+
# @return [UniqueType]
|
|
258
|
+
def downcast_to_literal_if_possible
|
|
259
|
+
SINGLE_SUBTYPE.fetch(rooted_tag, self)
|
|
260
|
+
end
|
|
261
|
+
|
|
152
262
|
# @param generics_to_resolve [Enumerable<String>]
|
|
153
263
|
# @param context_type [UniqueType, nil]
|
|
154
|
-
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
|
264
|
+
# @param resolved_generic_values [Hash{String => ComplexType, ComplexType::UniqueType}] Added to as types are encountered or resolved
|
|
155
265
|
# @return [UniqueType, ComplexType]
|
|
156
266
|
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
|
157
267
|
if name == ComplexType::GENERIC_TAG_NAME
|
|
@@ -176,7 +286,7 @@ module Solargraph
|
|
|
176
286
|
end
|
|
177
287
|
|
|
178
288
|
# @param generics_to_resolve [Enumerable<String>]
|
|
179
|
-
# @param context_type [UniqueType]
|
|
289
|
+
# @param context_type [UniqueType, nil]
|
|
180
290
|
# @param resolved_generic_values [Hash{String => ComplexType}]
|
|
181
291
|
# @yieldreturn [Array<ComplexType>]
|
|
182
292
|
# @return [Array<ComplexType>]
|
|
@@ -209,9 +319,26 @@ module Solargraph
|
|
|
209
319
|
|
|
210
320
|
transform(name) do |t|
|
|
211
321
|
if t.name == GENERIC_TAG_NAME
|
|
212
|
-
|
|
322
|
+
generic_name = t.subtypes.first&.name
|
|
323
|
+
idx = definitions.generics.index(generic_name)
|
|
213
324
|
next t if idx.nil?
|
|
214
|
-
context_type.
|
|
325
|
+
if context_type.parameters_type == :hash
|
|
326
|
+
if idx == 0
|
|
327
|
+
next ComplexType.new(context_type.key_types)
|
|
328
|
+
elsif idx == 1
|
|
329
|
+
next ComplexType.new(context_type.subtypes)
|
|
330
|
+
else
|
|
331
|
+
next ComplexType::UNDEFINED
|
|
332
|
+
end
|
|
333
|
+
elsif context_type.all?(&:implicit_union?)
|
|
334
|
+
if idx == 0 && !context_type.all_params.empty?
|
|
335
|
+
ComplexType.new(context_type.all_params)
|
|
336
|
+
else
|
|
337
|
+
ComplexType::UNDEFINED
|
|
338
|
+
end
|
|
339
|
+
else
|
|
340
|
+
context_type.all_params[idx] || definitions.generic_defaults[generic_name] || ComplexType::UNDEFINED
|
|
341
|
+
end
|
|
215
342
|
else
|
|
216
343
|
t
|
|
217
344
|
end
|
|
@@ -232,12 +359,13 @@ module Solargraph
|
|
|
232
359
|
|
|
233
360
|
# @param new_name [String, nil]
|
|
234
361
|
# @param make_rooted [Boolean, nil]
|
|
235
|
-
# @param new_key_types [Array<
|
|
362
|
+
# @param new_key_types [Array<ComplexType>, nil]
|
|
236
363
|
# @param rooted [Boolean, nil]
|
|
237
|
-
# @param new_subtypes [Array<
|
|
364
|
+
# @param new_subtypes [Array<ComplexType>, nil]
|
|
238
365
|
# @return [self]
|
|
239
366
|
def recreate(new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil)
|
|
240
367
|
raise "Please remove leading :: and set rooted instead - #{new_name}" if new_name&.start_with?('::')
|
|
368
|
+
|
|
241
369
|
new_name ||= name
|
|
242
370
|
new_key_types ||= @key_types
|
|
243
371
|
new_subtypes ||= @subtypes
|
|
@@ -278,17 +406,26 @@ module Solargraph
|
|
|
278
406
|
new_key_types = @key_types.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
|
|
279
407
|
new_subtypes = @subtypes.flat_map { |ct| ct.items.map { |ut| ut.transform(&transform_type) } }
|
|
280
408
|
end
|
|
281
|
-
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes)
|
|
409
|
+
new_type = recreate(new_name: new_name || name, new_key_types: new_key_types, new_subtypes: new_subtypes, make_rooted: @rooted)
|
|
282
410
|
yield new_type
|
|
283
411
|
end
|
|
284
412
|
|
|
285
|
-
#
|
|
286
|
-
#
|
|
287
|
-
# @
|
|
288
|
-
|
|
413
|
+
# Generate a ComplexType that fully qualifies this type's namespaces.
|
|
414
|
+
#
|
|
415
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
416
|
+
# @param context [String] The namespace from which to resolve names
|
|
417
|
+
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
|
418
|
+
def qualify api_map, *gates
|
|
289
419
|
transform do |t|
|
|
290
|
-
next t if t.name
|
|
291
|
-
t.
|
|
420
|
+
next t if t.name == GENERIC_TAG_NAME
|
|
421
|
+
next t if t.duck_type? || t.void? || t.undefined? || t.literal?
|
|
422
|
+
open = t.rooted? ? [''] : gates
|
|
423
|
+
fqns = api_map.qualify(t.non_literal_name, *open)
|
|
424
|
+
if fqns.nil?
|
|
425
|
+
next UniqueType::BOOLEAN if t.tag == 'Boolean'
|
|
426
|
+
next UniqueType::UNDEFINED
|
|
427
|
+
end
|
|
428
|
+
t.recreate(new_name: fqns, make_rooted: true)
|
|
292
429
|
end
|
|
293
430
|
end
|
|
294
431
|
|
|
@@ -296,8 +433,50 @@ module Solargraph
|
|
|
296
433
|
@name == 'self' || @key_types.any?(&:selfy?) || @subtypes.any?(&:selfy?)
|
|
297
434
|
end
|
|
298
435
|
|
|
436
|
+
# @param dst [ComplexType]
|
|
437
|
+
# @return [self]
|
|
438
|
+
def self_to_type dst
|
|
439
|
+
object_type_dst = dst.reduce_class_type
|
|
440
|
+
transform do |t|
|
|
441
|
+
next t if t.name != 'self'
|
|
442
|
+
object_type_dst
|
|
443
|
+
end
|
|
444
|
+
end
|
|
445
|
+
|
|
446
|
+
def all_rooted?
|
|
447
|
+
return true if name == GENERIC_TAG_NAME
|
|
448
|
+
rooted? && all_params.all?(&:rooted?)
|
|
449
|
+
end
|
|
450
|
+
|
|
451
|
+
def rooted?
|
|
452
|
+
!can_root_name? || @rooted
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
# @param name_to_check [String]
|
|
456
|
+
def can_root_name?(name_to_check = name)
|
|
457
|
+
self.class.can_root_name?(name_to_check)
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
# @param name [String]
|
|
461
|
+
def self.can_root_name?(name)
|
|
462
|
+
# name is not lowercase
|
|
463
|
+
!name.empty? && name != name.downcase
|
|
464
|
+
end
|
|
465
|
+
|
|
299
466
|
UNDEFINED = UniqueType.new('undefined', rooted: false)
|
|
300
467
|
BOOLEAN = UniqueType.new('Boolean', rooted: true)
|
|
468
|
+
TRUE = UniqueType.new('true', rooted: true)
|
|
469
|
+
FALSE = UniqueType.new('false', rooted: true)
|
|
470
|
+
NIL = UniqueType.new('nil', rooted: true)
|
|
471
|
+
# @type [Hash{String => UniqueType}]
|
|
472
|
+
SINGLE_SUBTYPE = {
|
|
473
|
+
'::TrueClass' => UniqueType::TRUE,
|
|
474
|
+
'::FalseClass' => UniqueType::FALSE,
|
|
475
|
+
'::NilClass' => UniqueType::NIL
|
|
476
|
+
}.freeze
|
|
477
|
+
|
|
478
|
+
|
|
479
|
+
include Logging
|
|
301
480
|
end
|
|
302
481
|
end
|
|
303
482
|
end
|