solargraph 0.58.1 → 0.59.0.dev.1
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/.envrc +3 -0
- data/.github/workflows/linting.yml +4 -5
- data/.github/workflows/plugins.yml +40 -36
- data/.github/workflows/rspec.yml +45 -13
- data/.github/workflows/typecheck.yml +2 -2
- data/.rubocop_todo.yml +27 -49
- data/README.md +3 -3
- data/Rakefile +1 -0
- data/lib/solargraph/api_map/cache.rb +110 -110
- data/lib/solargraph/api_map/constants.rb +289 -279
- data/lib/solargraph/api_map/index.rb +204 -193
- data/lib/solargraph/api_map/source_to_yard.rb +109 -97
- data/lib/solargraph/api_map/store.rb +387 -384
- data/lib/solargraph/api_map.rb +1000 -945
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +242 -228
- data/lib/solargraph/complex_type/unique_type.rb +632 -482
- data/lib/solargraph/complex_type.rb +549 -444
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +93 -91
- data/lib/solargraph/convention/data_definition.rb +108 -105
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +62 -61
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +103 -102
- data/lib/solargraph/convention/struct_definition.rb +168 -164
- data/lib/solargraph/diagnostics/require_not_found.rb +54 -53
- data/lib/solargraph/diagnostics/rubocop.rb +119 -118
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +70 -68
- data/lib/solargraph/diagnostics/type_check.rb +56 -55
- data/lib/solargraph/doc_map.rb +200 -439
- data/lib/solargraph/equality.rb +34 -34
- data/lib/solargraph/gem_pins.rb +97 -98
- data/lib/solargraph/language_server/host/dispatch.rb +131 -130
- data/lib/solargraph/language_server/host/message_worker.rb +113 -112
- data/lib/solargraph/language_server/host/sources.rb +100 -99
- data/lib/solargraph/language_server/host.rb +883 -878
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +109 -114
- data/lib/solargraph/language_server/message/extended/document.rb +24 -23
- data/lib/solargraph/language_server/message/text_document/completion.rb +58 -56
- data/lib/solargraph/language_server/message/text_document/definition.rb +42 -40
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +28 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +150 -148
- data/lib/solargraph/language_server/message/text_document/hover.rb +60 -58
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +25 -24
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +27 -25
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +25 -23
- data/lib/solargraph/library.rb +729 -683
- data/lib/solargraph/location.rb +87 -82
- data/lib/solargraph/logging.rb +57 -37
- data/lib/solargraph/parser/comment_ripper.rb +76 -69
- data/lib/solargraph/parser/flow_sensitive_typing.rb +483 -255
- data/lib/solargraph/parser/node_processor/base.rb +122 -92
- data/lib/solargraph/parser/node_processor.rb +63 -62
- data/lib/solargraph/parser/parser_gem/class_methods.rb +167 -149
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +191 -166
- data/lib/solargraph/parser/parser_gem/node_methods.rb +506 -486
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +22 -22
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +24 -15
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +46 -46
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +60 -53
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +53 -23
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +41 -40
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +30 -29
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +61 -59
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +98 -98
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +17 -17
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +39 -38
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +53 -52
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +296 -291
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +33 -29
- data/lib/solargraph/parser/parser_gem/node_processors.rb +74 -70
- data/lib/solargraph/parser/region.rb +75 -69
- data/lib/solargraph/parser/snippet.rb +17 -17
- data/lib/solargraph/pin/base.rb +761 -729
- data/lib/solargraph/pin/base_variable.rb +418 -126
- data/lib/solargraph/pin/block.rb +126 -104
- data/lib/solargraph/pin/breakable.rb +13 -9
- data/lib/solargraph/pin/callable.rb +278 -231
- data/lib/solargraph/pin/closure.rb +68 -72
- data/lib/solargraph/pin/common.rb +94 -79
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/conversions.rb +124 -123
- data/lib/solargraph/pin/delegated_method.rb +131 -120
- data/lib/solargraph/pin/documenting.rb +115 -114
- data/lib/solargraph/pin/instance_variable.rb +38 -34
- data/lib/solargraph/pin/keyword.rb +16 -20
- data/lib/solargraph/pin/local_variable.rb +31 -75
- data/lib/solargraph/pin/method.rb +720 -672
- data/lib/solargraph/pin/method_alias.rb +42 -34
- data/lib/solargraph/pin/namespace.rb +121 -115
- data/lib/solargraph/pin/parameter.rb +338 -275
- data/lib/solargraph/pin/proxy_type.rb +40 -39
- data/lib/solargraph/pin/reference/override.rb +47 -47
- data/lib/solargraph/pin/reference/superclass.rb +17 -15
- data/lib/solargraph/pin/reference.rb +41 -39
- data/lib/solargraph/pin/search.rb +62 -61
- data/lib/solargraph/pin/signature.rb +69 -61
- data/lib/solargraph/pin/symbol.rb +53 -53
- data/lib/solargraph/pin/until.rb +18 -18
- data/lib/solargraph/pin/while.rb +18 -18
- data/lib/solargraph/pin.rb +46 -44
- data/lib/solargraph/pin_cache.rb +665 -245
- data/lib/solargraph/position.rb +118 -119
- data/lib/solargraph/range.rb +112 -112
- data/lib/solargraph/rbs_map/conversions.rb +846 -823
- data/lib/solargraph/rbs_map/core_map.rb +65 -58
- data/lib/solargraph/rbs_map/stdlib_map.rb +72 -43
- data/lib/solargraph/rbs_map.rb +217 -163
- data/lib/solargraph/shell.rb +397 -352
- data/lib/solargraph/source/chain/call.rb +372 -337
- data/lib/solargraph/source/chain/constant.rb +28 -26
- data/lib/solargraph/source/chain/hash.rb +35 -34
- data/lib/solargraph/source/chain/if.rb +29 -28
- data/lib/solargraph/source/chain/instance_variable.rb +34 -13
- data/lib/solargraph/source/chain/literal.rb +53 -48
- data/lib/solargraph/source/chain/or.rb +31 -23
- data/lib/solargraph/source/chain.rb +294 -291
- data/lib/solargraph/source/change.rb +89 -82
- data/lib/solargraph/source/cursor.rb +172 -166
- data/lib/solargraph/source/source_chainer.rb +204 -194
- data/lib/solargraph/source/updater.rb +59 -55
- data/lib/solargraph/source.rb +524 -498
- data/lib/solargraph/source_map/clip.rb +237 -226
- data/lib/solargraph/source_map/data.rb +37 -34
- data/lib/solargraph/source_map/mapper.rb +282 -259
- data/lib/solargraph/source_map.rb +220 -212
- data/lib/solargraph/type_checker/problem.rb +34 -32
- data/lib/solargraph/type_checker/rules.rb +157 -84
- data/lib/solargraph/type_checker.rb +895 -814
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +257 -255
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +98 -97
- data/lib/solargraph/workspace.rb +362 -220
- data/lib/solargraph/yard_map/helpers.rb +45 -44
- data/lib/solargraph/yard_map/mapper/to_method.rb +134 -130
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +32 -31
- data/lib/solargraph/yard_map/mapper.rb +84 -79
- data/lib/solargraph/yardoc.rb +97 -87
- data/lib/solargraph.rb +126 -105
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/fills/tuple/tuple.rbs +28 -0
- data/rbs/shims/ast/0/node.rbs +5 -0
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/rbs_collection.yaml +1 -1
- data/solargraph.gemspec +2 -1
- metadata +22 -17
- data/lib/solargraph/type_checker/checks.rb +0 -124
- data/lib/solargraph/type_checker/param_def.rb +0 -37
- data/lib/solargraph/yard_map/to_method.rb +0 -89
- data/sig/shims/ast/0/node.rbs +0 -5
- /data/{sig → rbs}/shims/ast/2.4/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/ast/2.4/ast.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/builders/default.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/parser.rbs +0 -0
- /data/{sig → rbs}/shims/parser/3.2.0.1/polyfill.rbs +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/.rbs_meta.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/manifest.yaml +0 -0
- /data/{sig → rbs}/shims/thor/1.2.0.1/thor.rbs +0 -0
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class ComplexType
|
|
5
|
+
# Checks whether a type can be used in a given situation
|
|
6
|
+
class Conformance
|
|
7
|
+
# @param api_map [ApiMap]
|
|
8
|
+
# @param inferred [ComplexType::UniqueType]
|
|
9
|
+
# @param expected [ComplexType::UniqueType]
|
|
10
|
+
# @param situation [:method_call, :return_type]
|
|
11
|
+
# @param rules [Array<:allow_subtype_skew, :allow_empty_params, :allow_reverse_match,
|
|
12
|
+
# :allow_any_match, :allow_undefined, :allow_unresolved_generic,
|
|
13
|
+
# :allow_unmatched_interface>]
|
|
14
|
+
# @param variance [:invariant, :covariant, :contravariant]
|
|
15
|
+
def initialize api_map, inferred, expected,
|
|
16
|
+
situation = :method_call, rules = [],
|
|
17
|
+
variance: inferred.erased_variance(situation)
|
|
18
|
+
@api_map = api_map
|
|
19
|
+
@inferred = inferred
|
|
20
|
+
@expected = expected
|
|
21
|
+
@situation = situation
|
|
22
|
+
@rules = rules
|
|
23
|
+
@variance = variance
|
|
24
|
+
# :nocov:
|
|
25
|
+
unless expected.is_a?(UniqueType)
|
|
26
|
+
# @sg-ignore This should never happen and the typechecker is angry about it
|
|
27
|
+
raise "Expected type must be a UniqueType, got #{expected.class} in #{expected.inspect}"
|
|
28
|
+
end
|
|
29
|
+
# :nocov:
|
|
30
|
+
return if inferred.is_a?(UniqueType)
|
|
31
|
+
# :nocov:
|
|
32
|
+
# @sg-ignore This should never happen and the typechecker is angry about it
|
|
33
|
+
raise "Inferred type must be a UniqueType, got #{inferred.class} in #{inferred.inspect}"
|
|
34
|
+
# :nocov:
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
def conforms_to_unique_type?
|
|
38
|
+
unless expected.is_a?(UniqueType)
|
|
39
|
+
# :nocov:
|
|
40
|
+
raise "Expected type must be a UniqueType, got #{expected.class} in #{expected.inspect}"
|
|
41
|
+
# :nocov:
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
return true if ignore_interface?
|
|
45
|
+
return true if conforms_via_reverse_match?
|
|
46
|
+
|
|
47
|
+
downcast_inferred = inferred.downcast_to_literal_if_possible
|
|
48
|
+
downcast_expected = expected.downcast_to_literal_if_possible
|
|
49
|
+
if (downcast_inferred.name != inferred.name) || (downcast_expected.name != expected.name)
|
|
50
|
+
return with_new_types(downcast_inferred, downcast_expected).conforms_to_unique_type?
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
if rules.include?(:allow_subtype_skew) && !expected.all_params.empty?
|
|
54
|
+
# parameters are not considered in this case
|
|
55
|
+
return with_new_types(inferred, expected.erase_parameters).conforms_to_unique_type?
|
|
56
|
+
end
|
|
57
|
+
|
|
58
|
+
return with_new_types(inferred.erase_parameters, expected).conforms_to_unique_type? if only_inferred_parameters?
|
|
59
|
+
|
|
60
|
+
return conforms_via_stripped_expected_parameters? if can_strip_expected_parameters?
|
|
61
|
+
|
|
62
|
+
return true if inferred == expected
|
|
63
|
+
|
|
64
|
+
return false unless erased_type_conforms?
|
|
65
|
+
|
|
66
|
+
return true if inferred.all_params.empty? && rules.include?(:allow_empty_params)
|
|
67
|
+
|
|
68
|
+
# at this point we know the erased type is fine - time to look at parameters
|
|
69
|
+
|
|
70
|
+
# there's an implicit 'any' on the expectation parameters
|
|
71
|
+
# if there are none specified
|
|
72
|
+
return true if expected.all_params.empty?
|
|
73
|
+
|
|
74
|
+
return false unless key_types_conform?
|
|
75
|
+
|
|
76
|
+
subtypes_conform?
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
private
|
|
80
|
+
|
|
81
|
+
def only_inferred_parameters?
|
|
82
|
+
!expected.parameters? && inferred.parameters?
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def conforms_via_stripped_expected_parameters?
|
|
86
|
+
with_new_types(inferred, expected.erase_parameters).conforms_to_unique_type?
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def ignore_interface?
|
|
90
|
+
(expected.any?(&:interface?) && rules.include?(:allow_unmatched_interface)) ||
|
|
91
|
+
(inferred.interface? && rules.include?(:allow_unmatched_interface))
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
def can_strip_expected_parameters?
|
|
95
|
+
expected.parameters? && !inferred.parameters? && rules.include?(:allow_empty_params)
|
|
96
|
+
end
|
|
97
|
+
|
|
98
|
+
def conforms_via_reverse_match?
|
|
99
|
+
return false unless rules.include? :allow_reverse_match
|
|
100
|
+
|
|
101
|
+
expected.conforms_to?(api_map, inferred, situation,
|
|
102
|
+
rules - [:allow_reverse_match],
|
|
103
|
+
variance: variance)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def erased_type_conforms?
|
|
107
|
+
case variance
|
|
108
|
+
when :invariant
|
|
109
|
+
return false unless inferred.name == expected.name
|
|
110
|
+
when :covariant
|
|
111
|
+
# covariant: we can pass in a more specific type
|
|
112
|
+
# we contain the expected mix-in, or we have a more specific type
|
|
113
|
+
return false unless api_map.type_include?(inferred.name, expected.name) ||
|
|
114
|
+
api_map.super_and_sub?(expected.name, inferred.name) ||
|
|
115
|
+
inferred.name == expected.name
|
|
116
|
+
when :contravariant
|
|
117
|
+
# contravariant: we can pass in a more general type
|
|
118
|
+
# we contain the expected mix-in, or we have a more general type
|
|
119
|
+
return false unless api_map.type_include?(inferred.name, expected.name) ||
|
|
120
|
+
api_map.super_and_sub?(inferred.name, expected.name) ||
|
|
121
|
+
inferred.name == expected.name
|
|
122
|
+
else
|
|
123
|
+
# :nocov:
|
|
124
|
+
raise "Unknown variance: #{variance.inspect}"
|
|
125
|
+
# :nocov:
|
|
126
|
+
end
|
|
127
|
+
true
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
def key_types_conform?
|
|
131
|
+
return true if expected.key_types.empty?
|
|
132
|
+
|
|
133
|
+
return false if inferred.key_types.empty?
|
|
134
|
+
|
|
135
|
+
unless ComplexType.new(inferred.key_types).conforms_to?(api_map,
|
|
136
|
+
ComplexType.new(expected.key_types),
|
|
137
|
+
situation,
|
|
138
|
+
rules,
|
|
139
|
+
variance: inferred.parameter_variance(situation))
|
|
140
|
+
return false
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
true
|
|
144
|
+
end
|
|
145
|
+
|
|
146
|
+
def subtypes_conform?
|
|
147
|
+
return true if expected.subtypes.empty?
|
|
148
|
+
|
|
149
|
+
return true if expected.subtypes.any?(&:undefined?) && rules.include?(:allow_undefined)
|
|
150
|
+
|
|
151
|
+
return true if inferred.subtypes.any?(&:undefined?) && rules.include?(:allow_undefined)
|
|
152
|
+
|
|
153
|
+
return true if inferred.subtypes.all?(&:generic?) && rules.include?(:allow_unresolved_generic)
|
|
154
|
+
|
|
155
|
+
return true if expected.subtypes.all?(&:generic?) && rules.include?(:allow_unresolved_generic)
|
|
156
|
+
|
|
157
|
+
return false if inferred.subtypes.empty?
|
|
158
|
+
|
|
159
|
+
ComplexType.new(inferred.subtypes).conforms_to?(api_map,
|
|
160
|
+
ComplexType.new(expected.subtypes),
|
|
161
|
+
situation,
|
|
162
|
+
rules,
|
|
163
|
+
variance: inferred.parameter_variance(situation))
|
|
164
|
+
end
|
|
165
|
+
|
|
166
|
+
# @return [self]
|
|
167
|
+
# @param inferred [ComplexType::UniqueType]
|
|
168
|
+
# @param expected [ComplexType::UniqueType]
|
|
169
|
+
def with_new_types inferred, expected
|
|
170
|
+
self.class.new(api_map, inferred, expected, situation, rules, variance: variance)
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
attr_reader :api_map, :inferred, :expected, :situation, :rules, :variance
|
|
174
|
+
end
|
|
175
|
+
end
|
|
176
|
+
end
|
|
@@ -1,228 +1,242 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class ComplexType
|
|
5
|
-
# Methods for accessing type data available from
|
|
6
|
-
# both ComplexType and UniqueType.
|
|
7
|
-
#
|
|
8
|
-
# @abstract This mixin relies on these -
|
|
9
|
-
# instance variables:
|
|
10
|
-
# @name: String
|
|
11
|
-
# @subtypes: Array<ComplexType>
|
|
12
|
-
# @rooted: boolish
|
|
13
|
-
# methods:
|
|
14
|
-
# transform()
|
|
15
|
-
# all_params()
|
|
16
|
-
# rooted?()
|
|
17
|
-
# can_root_name?()
|
|
18
|
-
module TypeMethods
|
|
19
|
-
# @!method transform(new_name = nil, &transform_type)
|
|
20
|
-
# @param new_name [String, nil]
|
|
21
|
-
# @yieldparam t [UniqueType]
|
|
22
|
-
# @yieldreturn [UniqueType]
|
|
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]
|
|
29
|
-
|
|
30
|
-
# @return [String]
|
|
31
|
-
attr_reader :name
|
|
32
|
-
|
|
33
|
-
# @return [Array<ComplexType>]
|
|
34
|
-
attr_reader :subtypes
|
|
35
|
-
|
|
36
|
-
# @return [String]
|
|
37
|
-
def tag
|
|
38
|
-
@tag ||= "#{name}#{substring}"
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# @return [String]
|
|
42
|
-
def rooted_tag
|
|
43
|
-
@rooted_tag ||= rooted_name + rooted_substring
|
|
44
|
-
end
|
|
45
|
-
|
|
46
|
-
def interface?
|
|
47
|
-
name.start_with?('_')
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# @return [Boolean]
|
|
51
|
-
def duck_type?
|
|
52
|
-
@duck_type ||= name.start_with?('#')
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
# @return [Boolean]
|
|
56
|
-
def nil_type?
|
|
57
|
-
@nil_type ||= (name.casecmp('nil') == 0)
|
|
58
|
-
end
|
|
59
|
-
|
|
60
|
-
def tuple?
|
|
61
|
-
@tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
|
|
62
|
-
end
|
|
63
|
-
|
|
64
|
-
def void?
|
|
65
|
-
name == 'void'
|
|
66
|
-
end
|
|
67
|
-
|
|
68
|
-
def defined?
|
|
69
|
-
!undefined?
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
def undefined?
|
|
73
|
-
name == 'undefined'
|
|
74
|
-
end
|
|
75
|
-
|
|
76
|
-
#
|
|
77
|
-
# @return [
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
# @
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
return name
|
|
154
|
-
|
|
155
|
-
end
|
|
156
|
-
|
|
157
|
-
# @return [String]
|
|
158
|
-
def
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class ComplexType
|
|
5
|
+
# Methods for accessing type data available from
|
|
6
|
+
# both ComplexType and UniqueType.
|
|
7
|
+
#
|
|
8
|
+
# @abstract This mixin relies on these -
|
|
9
|
+
# instance variables:
|
|
10
|
+
# @name: String
|
|
11
|
+
# @subtypes: Array<ComplexType>
|
|
12
|
+
# @rooted: boolish
|
|
13
|
+
# methods:
|
|
14
|
+
# transform()
|
|
15
|
+
# all_params()
|
|
16
|
+
# rooted?()
|
|
17
|
+
# can_root_name?()
|
|
18
|
+
module TypeMethods
|
|
19
|
+
# @!method transform(new_name = nil, &transform_type)
|
|
20
|
+
# @param new_name [String, nil]
|
|
21
|
+
# @yieldparam t [UniqueType]
|
|
22
|
+
# @yieldreturn [UniqueType]
|
|
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]
|
|
29
|
+
|
|
30
|
+
# @return [String]
|
|
31
|
+
attr_reader :name
|
|
32
|
+
|
|
33
|
+
# @return [Array<ComplexType>]
|
|
34
|
+
attr_reader :subtypes
|
|
35
|
+
|
|
36
|
+
# @return [String]
|
|
37
|
+
def tag
|
|
38
|
+
@tag ||= "#{name}#{substring}"
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @return [String]
|
|
42
|
+
def rooted_tag
|
|
43
|
+
@rooted_tag ||= rooted_name + rooted_substring
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
def interface?
|
|
47
|
+
name.start_with?('_')
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# @return [Boolean]
|
|
51
|
+
def duck_type?
|
|
52
|
+
@duck_type ||= name.start_with?('#')
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# @return [Boolean]
|
|
56
|
+
def nil_type?
|
|
57
|
+
@nil_type ||= (name.casecmp('nil') == 0)
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def tuple?
|
|
61
|
+
@tuple_type ||= (name == 'Tuple') || (name == 'Array' && subtypes.length >= 1 && fixed_parameters?)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def void?
|
|
65
|
+
name == 'void'
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
def defined?
|
|
69
|
+
!undefined?
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
def undefined?
|
|
73
|
+
name == 'undefined'
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
# Variance of the type ignoring any type parameters
|
|
77
|
+
# @return [Symbol]
|
|
78
|
+
# @param situation [Symbol] The situation in which the variance is being considered.
|
|
79
|
+
def erased_variance situation = :method_call
|
|
80
|
+
# :nocov:
|
|
81
|
+
unless %i[method_call return_type assignment].include?(situation)
|
|
82
|
+
raise "Unknown situation: #{situation.inspect}"
|
|
83
|
+
end
|
|
84
|
+
# :nocov:
|
|
85
|
+
:covariant
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
# @param generics_to_erase [Enumerable<String>]
|
|
89
|
+
# @return [self]
|
|
90
|
+
def erase_generics(generics_to_erase)
|
|
91
|
+
transform do |type|
|
|
92
|
+
if type.name == ComplexType::GENERIC_TAG_NAME
|
|
93
|
+
if type.all_params.length == 1 && generics_to_erase.include?(type.all_params.first.to_s)
|
|
94
|
+
ComplexType::UNDEFINED
|
|
95
|
+
else
|
|
96
|
+
type
|
|
97
|
+
end
|
|
98
|
+
else
|
|
99
|
+
type
|
|
100
|
+
end
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
# @return [Symbol, nil]
|
|
105
|
+
attr_reader :parameters_type
|
|
106
|
+
|
|
107
|
+
# @type [Hash{String => Symbol}]
|
|
108
|
+
PARAMETERS_TYPE_BY_STARTING_TAG = {
|
|
109
|
+
'{' => :hash,
|
|
110
|
+
'(' => :fixed,
|
|
111
|
+
'<' => :list
|
|
112
|
+
}.freeze
|
|
113
|
+
|
|
114
|
+
# @return [Boolean]
|
|
115
|
+
def list_parameters?
|
|
116
|
+
parameters_type == :list
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# @return [Boolean]
|
|
120
|
+
def fixed_parameters?
|
|
121
|
+
parameters_type == :fixed
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
# @return [Boolean]
|
|
125
|
+
def hash_parameters?
|
|
126
|
+
parameters_type == :hash
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# @return [Array<ComplexType>]
|
|
130
|
+
def value_types
|
|
131
|
+
@subtypes
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
# @return [Array<ComplexType>]
|
|
135
|
+
def key_types
|
|
136
|
+
@key_types
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
# @return [String]
|
|
140
|
+
def namespace
|
|
141
|
+
# if priority higher than ||=, old implements cause unnecessary check
|
|
142
|
+
@namespace ||= lambda do
|
|
143
|
+
return 'Object' if duck_type?
|
|
144
|
+
return 'NilClass' if nil_type?
|
|
145
|
+
return (name == 'Class' || name == 'Module') && !subtypes.empty? ? subtypes.first.name : name
|
|
146
|
+
end.call
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# @return [self]
|
|
150
|
+
def namespace_type
|
|
151
|
+
return ComplexType.parse('::Object') if duck_type?
|
|
152
|
+
return ComplexType.parse('::NilClass') if nil_type?
|
|
153
|
+
return subtypes.first if (name == 'Class' || name == 'Module') && !subtypes.empty?
|
|
154
|
+
self
|
|
155
|
+
end
|
|
156
|
+
|
|
157
|
+
# @return [String]
|
|
158
|
+
def rooted_namespace
|
|
159
|
+
return namespace unless rooted? && can_root_name?(namespace)
|
|
160
|
+
"::#{namespace}"
|
|
161
|
+
end
|
|
162
|
+
|
|
163
|
+
# @return [String]
|
|
164
|
+
def rooted_name
|
|
165
|
+
return name unless @rooted && can_root_name?
|
|
166
|
+
"::#{name}"
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# @return [String]
|
|
170
|
+
def substring
|
|
171
|
+
@substring ||= generate_substring_from(&:tags)
|
|
172
|
+
end
|
|
173
|
+
|
|
174
|
+
# @return [String]
|
|
175
|
+
def rooted_substring
|
|
176
|
+
@rooted_substring = generate_substring_from(&:rooted_tags)
|
|
177
|
+
end
|
|
178
|
+
|
|
179
|
+
# @return [String]
|
|
180
|
+
def generate_substring_from(&to_str)
|
|
181
|
+
key_types_str = key_types.map(&to_str).join(', ')
|
|
182
|
+
subtypes_str = subtypes.map(&to_str).join(', ')
|
|
183
|
+
if key_types.none?(&:defined?) && subtypes.none?(&:defined?)
|
|
184
|
+
''
|
|
185
|
+
elsif key_types.empty? && subtypes.empty?
|
|
186
|
+
''
|
|
187
|
+
elsif hash_parameters?
|
|
188
|
+
"{#{key_types_str} => #{subtypes_str}}"
|
|
189
|
+
elsif fixed_parameters?
|
|
190
|
+
"(#{subtypes_str})"
|
|
191
|
+
else
|
|
192
|
+
if name == 'Hash'
|
|
193
|
+
"<#{key_types_str}, #{subtypes_str}>"
|
|
194
|
+
else
|
|
195
|
+
"<#{key_types_str}#{subtypes_str}>"
|
|
196
|
+
end
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
# @return [::Symbol] :class or :instance
|
|
201
|
+
def scope
|
|
202
|
+
@scope ||= :instance if duck_type? || nil_type?
|
|
203
|
+
@scope ||= (name == 'Class' || name == 'Module') && !subtypes.empty? ? :class : :instance
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
# @param other [Object]
|
|
207
|
+
def == other
|
|
208
|
+
return false unless self.class == other.class
|
|
209
|
+
# @sg-ignore flow sensitive typing should support .class == .class
|
|
210
|
+
tag == other.tag
|
|
211
|
+
end
|
|
212
|
+
|
|
213
|
+
# Generate a ComplexType that fully qualifies this type's namespaces.
|
|
214
|
+
#
|
|
215
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
216
|
+
# @param context [String] The namespace from which to resolve names
|
|
217
|
+
# @return [self, ComplexType, UniqueType] The generated ComplexType
|
|
218
|
+
def qualify api_map, context = ''
|
|
219
|
+
transform do |t|
|
|
220
|
+
next t if t.name == GENERIC_TAG_NAME
|
|
221
|
+
next t if t.duck_type? || t.void? || t.undefined?
|
|
222
|
+
recon = (t.rooted? ? '' : context)
|
|
223
|
+
fqns = api_map.qualify(t.name, recon)
|
|
224
|
+
if fqns.nil?
|
|
225
|
+
next UniqueType::BOOLEAN if t.tag == 'Boolean'
|
|
226
|
+
next UniqueType::UNDEFINED
|
|
227
|
+
end
|
|
228
|
+
t.recreate(new_name: fqns, make_rooted: true)
|
|
229
|
+
end
|
|
230
|
+
end
|
|
231
|
+
|
|
232
|
+
# @yieldparam [UniqueType]
|
|
233
|
+
# @return [void]
|
|
234
|
+
# @overload each_unique_type()
|
|
235
|
+
# @return [Enumerator<UniqueType>]
|
|
236
|
+
def each_unique_type &block
|
|
237
|
+
return enum_for(__method__) unless block_given?
|
|
238
|
+
yield self
|
|
239
|
+
end
|
|
240
|
+
end
|
|
241
|
+
end
|
|
242
|
+
end
|