solargraph 0.58.3 → 0.59.2
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 +12 -5
- data/.github/workflows/plugins.yml +54 -34
- data/.github/workflows/rspec.yml +15 -28
- data/.github/workflows/typecheck.yml +6 -3
- data/.rubocop.yml +38 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +24 -0
- data/Gemfile +3 -1
- data/README.md +3 -3
- data/Rakefile +26 -23
- data/bin/solargraph +2 -1
- data/lib/solargraph/api_map/cache.rb +3 -3
- data/lib/solargraph/api_map/constants.rb +12 -3
- data/lib/solargraph/api_map/index.rb +29 -18
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +40 -30
- data/lib/solargraph/api_map.rb +160 -78
- data/lib/solargraph/bench.rb +2 -3
- data/lib/solargraph/complex_type/conformance.rb +176 -0
- data/lib/solargraph/complex_type/type_methods.rb +31 -18
- data/lib/solargraph/complex_type/unique_type.rb +221 -63
- data/lib/solargraph/complex_type.rb +173 -59
- data/lib/solargraph/convention/active_support_concern.rb +111 -111
- data/lib/solargraph/convention/base.rb +50 -50
- data/lib/solargraph/convention/data_definition/data_assignment_node.rb +1 -1
- data/lib/solargraph/convention/data_definition/data_definition_node.rb +7 -5
- data/lib/solargraph/convention/data_definition.rb +5 -2
- data/lib/solargraph/convention/gemfile.rb +1 -1
- data/lib/solargraph/convention/gemspec.rb +1 -1
- data/lib/solargraph/convention/rakefile.rb +1 -1
- data/lib/solargraph/convention/struct_definition/struct_assignment_node.rb +2 -1
- data/lib/solargraph/convention/struct_definition/struct_definition_node.rb +4 -3
- data/lib/solargraph/convention/struct_definition.rb +8 -4
- data/lib/solargraph/convention.rb +2 -2
- data/lib/solargraph/converters/dd.rb +2 -0
- data/lib/solargraph/converters/dl.rb +2 -0
- data/lib/solargraph/converters/dt.rb +2 -0
- data/lib/solargraph/converters/misc.rb +2 -0
- data/lib/solargraph/diagnostics/require_not_found.rb +1 -0
- data/lib/solargraph/diagnostics/rubocop.rb +11 -10
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +5 -3
- data/lib/solargraph/diagnostics/type_check.rb +11 -10
- data/lib/solargraph/diagnostics/update_errors.rb +4 -8
- data/lib/solargraph/diagnostics.rb +55 -55
- data/lib/solargraph/doc_map.rb +38 -39
- data/lib/solargraph/environ.rb +52 -52
- data/lib/solargraph/equality.rb +4 -4
- data/lib/solargraph/gem_pins.rb +4 -15
- data/lib/solargraph/language_server/error_codes.rb +10 -10
- data/lib/solargraph/language_server/host/diagnoser.rb +1 -1
- data/lib/solargraph/language_server/host/dispatch.rb +3 -3
- data/lib/solargraph/language_server/host/message_worker.rb +4 -3
- data/lib/solargraph/language_server/host/sources.rb +2 -1
- data/lib/solargraph/language_server/host.rb +35 -28
- data/lib/solargraph/language_server/message/base.rb +1 -1
- data/lib/solargraph/language_server/message/client/register_capability.rb +1 -3
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +6 -8
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +12 -18
- data/lib/solargraph/language_server/message/extended/document.rb +1 -0
- data/lib/solargraph/language_server/message/extended/document_gems.rb +7 -7
- data/lib/solargraph/language_server/message/extended/download_core.rb +2 -1
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
- data/lib/solargraph/language_server/message/extended/search.rb +1 -1
- data/lib/solargraph/language_server/message/initialize.rb +20 -14
- data/lib/solargraph/language_server/message/initialized.rb +28 -28
- data/lib/solargraph/language_server/message/text_document/completion.rb +10 -8
- data/lib/solargraph/language_server/message/text_document/definition.rb +41 -32
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +29 -19
- data/lib/solargraph/language_server/message/text_document/formatting.rb +8 -6
- data/lib/solargraph/language_server/message/text_document/hover.rb +5 -5
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +13 -6
- data/lib/solargraph/language_server/message/text_document/references.rb +17 -10
- data/lib/solargraph/language_server/message/text_document/rename.rb +20 -13
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +3 -2
- data/lib/solargraph/language_server/message/text_document/type_definition.rb +25 -17
- data/lib/solargraph/language_server/message/text_document.rb +28 -28
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +34 -28
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +38 -30
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +23 -17
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +27 -17
- data/lib/solargraph/language_server/message.rb +1 -1
- data/lib/solargraph/language_server/progress.rb +143 -143
- data/lib/solargraph/language_server/request.rb +4 -2
- data/lib/solargraph/language_server/transport/adapter.rb +68 -68
- data/lib/solargraph/language_server/transport/data_reader.rb +11 -13
- data/lib/solargraph/language_server/uri_helpers.rb +2 -2
- data/lib/solargraph/language_server.rb +20 -20
- data/lib/solargraph/library.rb +57 -38
- data/lib/solargraph/location.rb +17 -14
- data/lib/solargraph/logging.rb +22 -4
- data/lib/solargraph/page.rb +1 -1
- data/lib/solargraph/parser/comment_ripper.rb +19 -4
- data/lib/solargraph/parser/flow_sensitive_typing.rb +324 -108
- data/lib/solargraph/parser/node_processor/base.rb +34 -4
- data/lib/solargraph/parser/node_processor.rb +8 -7
- data/lib/solargraph/parser/parser_gem/class_methods.rb +30 -14
- data/lib/solargraph/parser/parser_gem/flawed_builder.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_chainer.rb +51 -25
- data/lib/solargraph/parser/parser_gem/node_methods.rb +181 -73
- data/lib/solargraph/parser/parser_gem/node_processors/alias_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/and_node.rb +4 -4
- data/lib/solargraph/parser/parser_gem/node_processors/args_node.rb +13 -11
- data/lib/solargraph/parser/parser_gem/node_processors/begin_node.rb +9 -0
- data/lib/solargraph/parser/parser_gem/node_processors/block_node.rb +11 -12
- data/lib/solargraph/parser/parser_gem/node_processors/casgn_node.rb +36 -36
- data/lib/solargraph/parser/parser_gem/node_processors/cvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/def_node.rb +10 -3
- data/lib/solargraph/parser/parser_gem/node_processors/defs_node.rb +9 -8
- data/lib/solargraph/parser/parser_gem/node_processors/gvasgn_node.rb +24 -24
- data/lib/solargraph/parser/parser_gem/node_processors/if_node.rb +36 -6
- data/lib/solargraph/parser/parser_gem/node_processors/ivasgn_node.rb +5 -3
- data/lib/solargraph/parser/parser_gem/node_processors/lvasgn_node.rb +1 -0
- data/lib/solargraph/parser/parser_gem/node_processors/masgn_node.rb +3 -1
- data/lib/solargraph/parser/parser_gem/node_processors/namespace_node.rb +40 -40
- data/lib/solargraph/parser/parser_gem/node_processors/opasgn_node.rb +3 -3
- data/lib/solargraph/parser/parser_gem/node_processors/or_node.rb +22 -0
- data/lib/solargraph/parser/parser_gem/node_processors/orasgn_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/resbody_node.rb +2 -1
- data/lib/solargraph/parser/parser_gem/node_processors/sclass_node.rb +4 -5
- data/lib/solargraph/parser/parser_gem/node_processors/send_node.rb +124 -113
- data/lib/solargraph/parser/parser_gem/node_processors/sym_node.rb +20 -20
- data/lib/solargraph/parser/parser_gem/node_processors/until_node.rb +1 -1
- data/lib/solargraph/parser/parser_gem/node_processors/when_node.rb +23 -0
- data/lib/solargraph/parser/parser_gem/node_processors/while_node.rb +6 -2
- data/lib/solargraph/parser/parser_gem/node_processors.rb +4 -0
- data/lib/solargraph/parser/parser_gem.rb +2 -0
- data/lib/solargraph/parser/region.rb +9 -3
- data/lib/solargraph/parser/snippet.rb +3 -1
- data/lib/solargraph/parser.rb +2 -0
- data/lib/solargraph/pin/base.rb +126 -82
- data/lib/solargraph/pin/base_variable.rb +273 -24
- data/lib/solargraph/pin/block.rb +29 -6
- data/lib/solargraph/pin/breakable.rb +7 -1
- data/lib/solargraph/pin/callable.rb +65 -21
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +24 -6
- data/lib/solargraph/pin/compound_statement.rb +55 -0
- data/lib/solargraph/pin/constant.rb +3 -5
- data/lib/solargraph/pin/conversions.rb +10 -4
- data/lib/solargraph/pin/delegated_method.rb +19 -8
- data/lib/solargraph/pin/documenting.rb +4 -2
- data/lib/solargraph/pin/instance_variable.rb +5 -1
- data/lib/solargraph/pin/keyword.rb +0 -4
- data/lib/solargraph/pin/local_variable.rb +15 -59
- data/lib/solargraph/pin/method.rb +158 -104
- data/lib/solargraph/pin/method_alias.rb +8 -0
- data/lib/solargraph/pin/namespace.rb +19 -12
- data/lib/solargraph/pin/parameter.rb +102 -36
- data/lib/solargraph/pin/proxy_type.rb +4 -1
- data/lib/solargraph/pin/reference/override.rb +1 -1
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/reference/superclass.rb +2 -0
- data/lib/solargraph/pin/reference/type_alias.rb +16 -0
- data/lib/solargraph/pin/reference.rb +20 -0
- data/lib/solargraph/pin/search.rb +8 -7
- data/lib/solargraph/pin/signature.rb +15 -12
- data/lib/solargraph/pin/singleton.rb +11 -11
- data/lib/solargraph/pin/symbol.rb +2 -1
- data/lib/solargraph/pin/until.rb +2 -4
- data/lib/solargraph/pin/while.rb +2 -4
- data/lib/solargraph/pin.rb +2 -0
- data/lib/solargraph/pin_cache.rb +22 -19
- data/lib/solargraph/position.rb +17 -10
- data/lib/solargraph/range.rb +16 -15
- data/lib/solargraph/rbs_map/conversions.rb +367 -231
- data/lib/solargraph/rbs_map/core_fills.rb +18 -11
- data/lib/solargraph/rbs_map/core_map.rb +24 -17
- data/lib/solargraph/rbs_map/stdlib_map.rb +33 -5
- data/lib/solargraph/rbs_map.rb +76 -32
- data/lib/solargraph/server_methods.rb +1 -1
- data/lib/solargraph/shell.rb +258 -66
- data/lib/solargraph/source/chain/array.rb +3 -12
- data/lib/solargraph/source/chain/block_symbol.rb +13 -13
- data/lib/solargraph/source/chain/block_variable.rb +13 -13
- data/lib/solargraph/source/chain/call.rb +96 -56
- data/lib/solargraph/source/chain/class_variable.rb +1 -1
- data/lib/solargraph/source/chain/constant.rb +5 -1
- data/lib/solargraph/source/chain/global_variable.rb +1 -1
- data/lib/solargraph/source/chain/hash.rb +8 -5
- data/lib/solargraph/source/chain/head.rb +19 -19
- data/lib/solargraph/source/chain/if.rb +12 -10
- data/lib/solargraph/source/chain/instance_variable.rb +24 -1
- data/lib/solargraph/source/chain/link.rb +12 -22
- data/lib/solargraph/source/chain/literal.rb +22 -15
- data/lib/solargraph/source/chain/or.rb +10 -4
- data/lib/solargraph/source/chain/q_call.rb +2 -0
- data/lib/solargraph/source/chain/variable.rb +3 -1
- data/lib/solargraph/source/chain/z_super.rb +1 -3
- data/lib/solargraph/source/chain.rb +51 -38
- data/lib/solargraph/source/change.rb +12 -5
- data/lib/solargraph/source/cursor.rb +33 -18
- data/lib/solargraph/source/encoding_fixes.rb +6 -7
- data/lib/solargraph/source/source_chainer.rb +56 -32
- data/lib/solargraph/source/updater.rb +5 -1
- data/lib/solargraph/source.rb +59 -35
- data/lib/solargraph/source_map/clip.rb +54 -30
- data/lib/solargraph/source_map/data.rb +4 -1
- data/lib/solargraph/source_map/mapper.rb +69 -42
- data/lib/solargraph/source_map.rb +21 -9
- data/lib/solargraph/type_checker/problem.rb +3 -1
- data/lib/solargraph/type_checker/rules.rb +81 -8
- data/lib/solargraph/type_checker.rb +196 -122
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +14 -11
- data/lib/solargraph/workspace/gemspecs.rb +367 -0
- data/lib/solargraph/workspace/require_paths.rb +1 -0
- data/lib/solargraph/workspace.rb +50 -28
- data/lib/solargraph/yard_map/cache.rb +25 -25
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/mapper/to_constant.rb +28 -28
- data/lib/solargraph/yard_map/mapper/to_method.rb +13 -7
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +2 -1
- data/lib/solargraph/yard_map/mapper.rb +13 -8
- data/lib/solargraph/yard_map.rb +17 -18
- data/lib/solargraph/yard_tags.rb +2 -2
- data/lib/solargraph/yardoc.rb +7 -4
- data/lib/solargraph.rb +33 -10
- data/rbs/fills/rubygems/0/dependency.rbs +193 -0
- data/rbs/shims/ast/0/node.rbs +1 -1
- data/rbs/shims/diff-lcs/1.5/diff-lcs.rbs +11 -0
- data/solargraph.gemspec +37 -35
- metadata +41 -42
- 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/rbs/fills/tuple/tuple.rbs +0 -149
|
@@ -4,11 +4,12 @@ module Solargraph
|
|
|
4
4
|
# A container for type data based on YARD type tags.
|
|
5
5
|
#
|
|
6
6
|
class ComplexType
|
|
7
|
-
GENERIC_TAG_NAME = 'generic'
|
|
7
|
+
GENERIC_TAG_NAME = 'generic'
|
|
8
8
|
# @!parse
|
|
9
9
|
# include TypeMethods
|
|
10
10
|
include Equality
|
|
11
11
|
|
|
12
|
+
autoload :Conformance, 'solargraph/complex_type/conformance'
|
|
12
13
|
autoload :TypeMethods, 'solargraph/complex_type/type_methods'
|
|
13
14
|
autoload :UniqueType, 'solargraph/complex_type/unique_type'
|
|
14
15
|
|
|
@@ -18,39 +19,41 @@ module Solargraph
|
|
|
18
19
|
# @type [Array<UniqueType>]
|
|
19
20
|
items = types.flat_map(&:items).uniq(&:to_s)
|
|
20
21
|
if items.any? { |i| i.name == 'false' } && items.any? { |i| i.name == 'true' }
|
|
21
|
-
items.delete_if { |i|
|
|
22
|
-
items.unshift(
|
|
22
|
+
items.delete_if { |i| %w[false true].include?(i.name) }
|
|
23
|
+
items.unshift(UniqueType::BOOLEAN)
|
|
23
24
|
end
|
|
25
|
+
# @type [Array<UniqueType>]
|
|
24
26
|
items = [UniqueType::UNDEFINED] if items.any?(&:undefined?)
|
|
27
|
+
# @todo shouldn't need this cast - if statement above adds an 'Array' type
|
|
28
|
+
# @type [Array<UniqueType>]
|
|
25
29
|
@items = items
|
|
26
30
|
end
|
|
27
31
|
|
|
28
|
-
# @sg-ignore Fix "Not enough arguments to Module#protected"
|
|
29
|
-
protected def equality_fields
|
|
30
|
-
[self.class, items]
|
|
31
|
-
end
|
|
32
|
-
|
|
33
32
|
# @param api_map [ApiMap]
|
|
34
|
-
# @param
|
|
33
|
+
# @param gates [Array<String>]
|
|
34
|
+
#
|
|
35
35
|
# @return [ComplexType]
|
|
36
36
|
def qualify api_map, *gates
|
|
37
37
|
red = reduce_object
|
|
38
38
|
types = red.items.map do |t|
|
|
39
|
-
next t if [
|
|
39
|
+
next t if %w[nil void undefined].include?(t.name)
|
|
40
40
|
next t if ['::Boolean'].include?(t.rooted_name)
|
|
41
|
-
t.qualify
|
|
41
|
+
api_map.unalias(t.name) || t.qualify(api_map, *gates)
|
|
42
42
|
end
|
|
43
43
|
ComplexType.new(types).reduce_object
|
|
44
44
|
end
|
|
45
45
|
|
|
46
46
|
# @param generics_to_resolve [Enumerable<String>]]
|
|
47
|
-
# @param context_type [UniqueType, nil]
|
|
47
|
+
# @param context_type [ComplexType, ComplexType::UniqueType, nil]
|
|
48
48
|
# @param resolved_generic_values [Hash{String => ComplexType}] Added to as types are encountered or resolved
|
|
49
49
|
# @return [self]
|
|
50
50
|
def resolve_generics_from_context generics_to_resolve, context_type, resolved_generic_values: {}
|
|
51
51
|
return self unless generic?
|
|
52
52
|
|
|
53
|
-
ComplexType.new(@items.map
|
|
53
|
+
ComplexType.new(@items.map do |i|
|
|
54
|
+
i.resolve_generics_from_context(generics_to_resolve, context_type,
|
|
55
|
+
resolved_generic_values: resolved_generic_values)
|
|
56
|
+
end)
|
|
54
57
|
end
|
|
55
58
|
|
|
56
59
|
# @return [UniqueType]
|
|
@@ -65,7 +68,7 @@ module Solargraph
|
|
|
65
68
|
(@items.length > 1 ? ')' : ''))
|
|
66
69
|
end
|
|
67
70
|
|
|
68
|
-
# @param dst [ComplexType]
|
|
71
|
+
# @param dst [ComplexType, ComplexType::UniqueType]
|
|
69
72
|
# @return [ComplexType]
|
|
70
73
|
def self_to_type dst
|
|
71
74
|
object_type_dst = dst.reduce_class_type
|
|
@@ -76,15 +79,19 @@ module Solargraph
|
|
|
76
79
|
end
|
|
77
80
|
|
|
78
81
|
# @yieldparam [UniqueType]
|
|
82
|
+
# @yieldreturn [UniqueType]
|
|
79
83
|
# @return [Array<UniqueType>]
|
|
84
|
+
# @sg-ignore Declared return type
|
|
85
|
+
# ::Array<::Solargraph::ComplexType::UniqueType> does not match
|
|
86
|
+
# inferred type ::Array<::Proc> for Solargraph::ComplexType#map
|
|
80
87
|
def map &block
|
|
81
|
-
@items.map
|
|
88
|
+
@items.map(&block)
|
|
82
89
|
end
|
|
83
90
|
|
|
84
91
|
# @yieldparam [UniqueType]
|
|
85
92
|
# @return [Enumerable<UniqueType>]
|
|
86
93
|
def each &block
|
|
87
|
-
@items.each
|
|
94
|
+
@items.each(&block)
|
|
88
95
|
end
|
|
89
96
|
|
|
90
97
|
# @yieldparam [UniqueType]
|
|
@@ -95,23 +102,17 @@ module Solargraph
|
|
|
95
102
|
return enum_for(__method__) unless block_given?
|
|
96
103
|
|
|
97
104
|
@items.each do |item|
|
|
98
|
-
item.each_unique_type
|
|
105
|
+
item.each_unique_type(&block)
|
|
99
106
|
end
|
|
100
107
|
end
|
|
101
108
|
|
|
102
|
-
# @param atype [ComplexType] type which may be assigned to this type
|
|
103
|
-
# @param api_map [ApiMap] The ApiMap that performs qualification
|
|
104
|
-
def can_assign?(api_map, atype)
|
|
105
|
-
any? { |ut| ut.can_assign?(api_map, atype) }
|
|
106
|
-
end
|
|
107
|
-
|
|
108
109
|
# @param new_name [String, nil]
|
|
109
110
|
# @param make_rooted [Boolean, nil]
|
|
110
111
|
# @param new_key_types [Array<ComplexType>, nil]
|
|
111
|
-
# @param
|
|
112
|
+
# @param make_rooted [Boolean, nil]
|
|
112
113
|
# @param new_subtypes [Array<ComplexType>, nil]
|
|
113
114
|
# @return [self]
|
|
114
|
-
def recreate
|
|
115
|
+
def recreate new_name: nil, make_rooted: nil, new_key_types: nil, new_subtypes: nil
|
|
115
116
|
ComplexType.new(map do |ut|
|
|
116
117
|
ut.recreate(new_name: new_name,
|
|
117
118
|
make_rooted: make_rooted,
|
|
@@ -132,13 +133,13 @@ module Solargraph
|
|
|
132
133
|
|
|
133
134
|
# @param index [Integer]
|
|
134
135
|
# @return [UniqueType]
|
|
135
|
-
def []
|
|
136
|
+
def [] index
|
|
136
137
|
@items[index]
|
|
137
138
|
end
|
|
138
139
|
|
|
139
140
|
# @return [Array<UniqueType>]
|
|
140
141
|
def select &block
|
|
141
|
-
@items.select
|
|
142
|
+
@items.select(&block)
|
|
142
143
|
end
|
|
143
144
|
|
|
144
145
|
# @return [String]
|
|
@@ -153,7 +154,9 @@ module Solargraph
|
|
|
153
154
|
end
|
|
154
155
|
|
|
155
156
|
# @param name [Symbol]
|
|
157
|
+
#
|
|
156
158
|
# @return [Object, nil]
|
|
159
|
+
# @param [Array<Object>] args
|
|
157
160
|
def method_missing name, *args, &block
|
|
158
161
|
return if @items.first.nil?
|
|
159
162
|
return @items.first.send(name, *args, &block) if respond_to_missing?(name)
|
|
@@ -162,8 +165,8 @@ module Solargraph
|
|
|
162
165
|
|
|
163
166
|
# @param name [Symbol]
|
|
164
167
|
# @param include_private [Boolean]
|
|
165
|
-
def respond_to_missing?
|
|
166
|
-
TypeMethods.
|
|
168
|
+
def respond_to_missing? name, include_private = false
|
|
169
|
+
TypeMethods.public_method_defined?(name) || super
|
|
167
170
|
end
|
|
168
171
|
|
|
169
172
|
def to_s
|
|
@@ -186,6 +189,7 @@ module Solargraph
|
|
|
186
189
|
|
|
187
190
|
# @return [ComplexType]
|
|
188
191
|
def downcast_to_literal_if_possible
|
|
192
|
+
return self
|
|
189
193
|
ComplexType.new(items.map(&:downcast_to_literal_if_possible))
|
|
190
194
|
end
|
|
191
195
|
|
|
@@ -194,6 +198,65 @@ module Solargraph
|
|
|
194
198
|
rooted_tags
|
|
195
199
|
end
|
|
196
200
|
|
|
201
|
+
# @param api_map [ApiMap]
|
|
202
|
+
# @param expected [ComplexType, ComplexType::UniqueType]
|
|
203
|
+
# @param situation [:method_call, :return_type, :assignment]
|
|
204
|
+
# @param rules [Array<:allow_subtype_skew, :allow_empty_params, :allow_reverse_match, :allow_any_match, :allow_undefined, :allow_unresolved_generic, :allow_unmatched_interface>]
|
|
205
|
+
#
|
|
206
|
+
# allow_subtype_skew: if not provided, check if any subtypes of
|
|
207
|
+
# the expected type match the inferred type
|
|
208
|
+
#
|
|
209
|
+
# allow_reverse_match: check if any subtypes
|
|
210
|
+
# of the expected type match the inferred type
|
|
211
|
+
#
|
|
212
|
+
# allow_empty_params: allow a general inferred type without
|
|
213
|
+
# parameters to conform to a more specific expected type
|
|
214
|
+
#
|
|
215
|
+
# allow_any_match: any unique type matched in the inferred
|
|
216
|
+
# qualifies as a match
|
|
217
|
+
#
|
|
218
|
+
# allow_undefined: treat undefined as a wildcard that matches
|
|
219
|
+
# anything
|
|
220
|
+
#
|
|
221
|
+
# @param variance [:invariant, :covariant, :contravariant]
|
|
222
|
+
# @return [Boolean]
|
|
223
|
+
def conforms_to? api_map, expected,
|
|
224
|
+
situation,
|
|
225
|
+
rules = [],
|
|
226
|
+
variance: erased_variance(situation)
|
|
227
|
+
expected = expected.downcast_to_literal_if_possible
|
|
228
|
+
inferred = downcast_to_literal_if_possible
|
|
229
|
+
|
|
230
|
+
return duck_types_match?(api_map, expected, inferred) if expected.duck_type?
|
|
231
|
+
|
|
232
|
+
if rules.include? :allow_any_match
|
|
233
|
+
inferred.any? do |inf|
|
|
234
|
+
inf.conforms_to?(api_map, expected, situation, rules,
|
|
235
|
+
variance: variance)
|
|
236
|
+
end
|
|
237
|
+
else
|
|
238
|
+
inferred.all? do |inf|
|
|
239
|
+
inf.conforms_to?(api_map, expected, situation, rules,
|
|
240
|
+
variance: variance)
|
|
241
|
+
end
|
|
242
|
+
end
|
|
243
|
+
end
|
|
244
|
+
|
|
245
|
+
# @param api_map [ApiMap]
|
|
246
|
+
# @param expected [ComplexType, UniqueType]
|
|
247
|
+
# @param inferred [ComplexType, UniqueType]
|
|
248
|
+
# @return [Boolean]
|
|
249
|
+
def duck_types_match? api_map, expected, inferred
|
|
250
|
+
raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
|
|
251
|
+
expected.each do |exp|
|
|
252
|
+
next unless exp.duck_type?
|
|
253
|
+
quack = exp.to_s[1..]
|
|
254
|
+
# @sg-ignore Need to add nil check here
|
|
255
|
+
return false if api_map.get_method_stack(inferred.namespace, quack, scope: inferred.scope).empty?
|
|
256
|
+
end
|
|
257
|
+
true
|
|
258
|
+
end
|
|
259
|
+
|
|
197
260
|
# @return [String]
|
|
198
261
|
def rooted_tags
|
|
199
262
|
map(&:rooted_tag).join(', ')
|
|
@@ -201,14 +264,14 @@ module Solargraph
|
|
|
201
264
|
|
|
202
265
|
# @yieldparam [UniqueType]
|
|
203
266
|
def all? &block
|
|
204
|
-
@items.all?
|
|
267
|
+
@items.all?(&block)
|
|
205
268
|
end
|
|
206
269
|
|
|
207
270
|
# @yieldparam [UniqueType]
|
|
208
271
|
# @yieldreturn [Boolean]
|
|
209
272
|
# @return [Boolean]
|
|
210
273
|
def any? &block
|
|
211
|
-
@items.compact.any?
|
|
274
|
+
@items.compact.any?(&block)
|
|
212
275
|
end
|
|
213
276
|
|
|
214
277
|
def selfy?
|
|
@@ -228,8 +291,10 @@ module Solargraph
|
|
|
228
291
|
# @yieldparam t [UniqueType]
|
|
229
292
|
# @yieldreturn [UniqueType]
|
|
230
293
|
# @return [ComplexType]
|
|
231
|
-
def transform
|
|
232
|
-
|
|
294
|
+
def transform new_name = nil, &transform_type
|
|
295
|
+
if new_name&.start_with?('::')
|
|
296
|
+
raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}"
|
|
297
|
+
end
|
|
233
298
|
ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
|
|
234
299
|
end
|
|
235
300
|
|
|
@@ -252,6 +317,13 @@ module Solargraph
|
|
|
252
317
|
@items.any?(&:nil_type?)
|
|
253
318
|
end
|
|
254
319
|
|
|
320
|
+
# @return [ComplexType]
|
|
321
|
+
def without_nil
|
|
322
|
+
new_items = @items.reject(&:nil_type?)
|
|
323
|
+
return ComplexType::UNDEFINED if new_items.empty?
|
|
324
|
+
ComplexType.new(new_items)
|
|
325
|
+
end
|
|
326
|
+
|
|
255
327
|
# @return [Array<ComplexType>]
|
|
256
328
|
def all_params
|
|
257
329
|
@items.first.all_params || []
|
|
@@ -260,7 +332,7 @@ module Solargraph
|
|
|
260
332
|
# @return [ComplexType]
|
|
261
333
|
def reduce_class_type
|
|
262
334
|
new_items = items.flat_map do |type|
|
|
263
|
-
next type unless [
|
|
335
|
+
next type unless %w[Module Class].include?(type.name)
|
|
264
336
|
next type if type.all_params.empty?
|
|
265
337
|
|
|
266
338
|
type.all_params
|
|
@@ -274,6 +346,13 @@ module Solargraph
|
|
|
274
346
|
all?(&:all_rooted?)
|
|
275
347
|
end
|
|
276
348
|
|
|
349
|
+
# @param other [ComplexType, UniqueType]
|
|
350
|
+
def erased_version_of? other
|
|
351
|
+
return false if items.length != 1 || other.items.length != 1
|
|
352
|
+
|
|
353
|
+
@items.first.erased_version_of?(other.items.first)
|
|
354
|
+
end
|
|
355
|
+
|
|
277
356
|
# every top-level type has resolved to be fully qualified; see
|
|
278
357
|
# #all_rooted? to check their subtypes as well
|
|
279
358
|
def rooted?
|
|
@@ -282,12 +361,46 @@ module Solargraph
|
|
|
282
361
|
|
|
283
362
|
attr_reader :items
|
|
284
363
|
|
|
285
|
-
|
|
286
|
-
|
|
364
|
+
# @param exclude_types [ComplexType, nil]
|
|
365
|
+
# @param api_map [ApiMap]
|
|
366
|
+
# @return [ComplexType, self]
|
|
367
|
+
def exclude exclude_types, api_map
|
|
368
|
+
return self if exclude_types.nil?
|
|
369
|
+
|
|
370
|
+
types = items - exclude_types.items
|
|
371
|
+
types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
|
|
372
|
+
ComplexType.new(types)
|
|
373
|
+
end
|
|
374
|
+
|
|
375
|
+
# @see https://en.wikipedia.org/wiki/Intersection_type
|
|
376
|
+
#
|
|
377
|
+
# @param intersection_type [ComplexType, ComplexType::UniqueType, nil]
|
|
378
|
+
# @param api_map [ApiMap]
|
|
379
|
+
# @return [self, ComplexType::UniqueType]
|
|
380
|
+
def intersect_with intersection_type, api_map
|
|
381
|
+
return self if intersection_type.nil?
|
|
382
|
+
return intersection_type if undefined?
|
|
383
|
+
types = []
|
|
384
|
+
# try to find common types via conformance
|
|
385
|
+
items.each do |ut|
|
|
386
|
+
intersection_type.each do |int_type|
|
|
387
|
+
if int_type.conforms_to?(api_map, ut, :assignment)
|
|
388
|
+
types << int_type
|
|
389
|
+
elsif ut.conforms_to?(api_map, int_type, :assignment)
|
|
390
|
+
types << ut
|
|
391
|
+
end
|
|
392
|
+
end
|
|
393
|
+
end
|
|
394
|
+
types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
|
|
395
|
+
ComplexType.new(types)
|
|
287
396
|
end
|
|
288
397
|
|
|
289
398
|
protected
|
|
290
399
|
|
|
400
|
+
def equality_fields
|
|
401
|
+
[self.class, items]
|
|
402
|
+
end
|
|
403
|
+
|
|
291
404
|
# @return [ComplexType]
|
|
292
405
|
def reduce_object
|
|
293
406
|
new_items = items.flat_map do |ut|
|
|
@@ -307,30 +420,29 @@ module Solargraph
|
|
|
307
420
|
# @example
|
|
308
421
|
# ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
|
|
309
422
|
#
|
|
310
|
-
# @
|
|
311
|
-
#
|
|
312
|
-
#
|
|
313
|
-
#
|
|
314
|
-
#
|
|
315
|
-
# used internally.
|
|
316
|
-
#
|
|
423
|
+
# @param partial [Boolean] if true, method is receiving a string
|
|
424
|
+
# that will be used inside another ComplexType. It returns
|
|
425
|
+
# arrays of ComplexTypes instead of a single cohesive one.
|
|
426
|
+
# Consumers should not need to use this parameter; it should
|
|
427
|
+
# only be used internally.
|
|
317
428
|
# @param strings [Array<String>] The type definitions to parse
|
|
318
429
|
# @return [ComplexType]
|
|
319
430
|
# # @overload parse(*strings, partial: false)
|
|
320
431
|
# # @todo Need ability to use a literal true as a type below
|
|
321
432
|
# # @param partial [Boolean] True if the string is part of a another type
|
|
322
433
|
# # @return [Array<UniqueType>]
|
|
323
|
-
# @
|
|
434
|
+
# @sg-ignore To be able to select the right signature above,
|
|
324
435
|
# Chain::Call needs to know the decl type (:arg, :optarg,
|
|
325
436
|
# :kwarg, etc) of the arguments given, instead of just having
|
|
326
437
|
# an array of Chains as the arguments.
|
|
327
438
|
def parse *strings, partial: false
|
|
328
|
-
# @type [Hash{Array<String> => ComplexType}]
|
|
439
|
+
# @type [Hash{Array<String> => ComplexType, Array<ComplexType::UniqueType>}]
|
|
329
440
|
@cache ||= {}
|
|
330
441
|
unless partial
|
|
331
442
|
cached = @cache[strings]
|
|
332
443
|
return cached unless cached.nil?
|
|
333
444
|
end
|
|
445
|
+
# @types [Array<ComplexType::UniqueType>]
|
|
334
446
|
types = []
|
|
335
447
|
key_types = nil
|
|
336
448
|
strings.each do |type_string|
|
|
@@ -342,15 +454,16 @@ module Solargraph
|
|
|
342
454
|
# @param char [String]
|
|
343
455
|
type_string&.each_char do |char|
|
|
344
456
|
if char == '='
|
|
345
|
-
#raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
457
|
+
# raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
346
458
|
elsif char == '<'
|
|
347
459
|
point_stack += 1
|
|
348
460
|
elsif char == '>'
|
|
349
|
-
if subtype_string.end_with?('=') && curly_stack
|
|
461
|
+
if subtype_string.end_with?('=') && curly_stack.positive?
|
|
350
462
|
subtype_string += char
|
|
351
463
|
elsif base.end_with?('=')
|
|
352
|
-
raise ComplexTypeError,
|
|
464
|
+
raise ComplexTypeError, 'Invalid hash thing' unless key_types.nil?
|
|
353
465
|
# types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
|
|
466
|
+
# @sg-ignore Need to add nil check here
|
|
354
467
|
types.push UniqueType.parse(base[0..-2].strip, subtype_string)
|
|
355
468
|
# @todo this should either expand key_type's type
|
|
356
469
|
# automatically or complain about not being
|
|
@@ -361,7 +474,7 @@ module Solargraph
|
|
|
361
474
|
subtype_string.clear
|
|
362
475
|
next
|
|
363
476
|
else
|
|
364
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack
|
|
477
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack.zero?
|
|
365
478
|
point_stack -= 1
|
|
366
479
|
subtype_string += char
|
|
367
480
|
end
|
|
@@ -371,34 +484,37 @@ module Solargraph
|
|
|
371
484
|
elsif char == '}'
|
|
372
485
|
curly_stack -= 1
|
|
373
486
|
subtype_string += char
|
|
374
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack
|
|
487
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack.negative?
|
|
375
488
|
next
|
|
376
489
|
elsif char == '('
|
|
377
490
|
paren_stack += 1
|
|
378
491
|
elsif char == ')'
|
|
379
492
|
paren_stack -= 1
|
|
380
493
|
subtype_string += char
|
|
381
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack
|
|
494
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack.negative?
|
|
382
495
|
next
|
|
383
|
-
elsif char == ',' && point_stack
|
|
496
|
+
elsif char == ',' && point_stack.zero? && curly_stack.zero? && paren_stack.zero?
|
|
384
497
|
# types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
|
385
498
|
types.push UniqueType.parse(base.strip, subtype_string.strip)
|
|
386
499
|
base.clear
|
|
387
500
|
subtype_string.clear
|
|
388
501
|
next
|
|
389
502
|
end
|
|
390
|
-
if point_stack
|
|
503
|
+
if point_stack.zero? && curly_stack.zero? && paren_stack.zero?
|
|
391
504
|
base.concat char
|
|
392
505
|
else
|
|
393
506
|
subtype_string.concat char
|
|
394
507
|
end
|
|
395
508
|
end
|
|
396
|
-
|
|
509
|
+
if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
|
510
|
+
raise ComplexTypeError,
|
|
511
|
+
"Unclosed subtype in #{type_string}"
|
|
512
|
+
end
|
|
397
513
|
# types.push ComplexType.new([UniqueType.new(base, subtype_string)])
|
|
398
514
|
types.push UniqueType.parse(base.strip, subtype_string.strip)
|
|
399
515
|
end
|
|
400
516
|
unless key_types.nil?
|
|
401
|
-
raise ComplexTypeError,
|
|
517
|
+
raise ComplexTypeError, 'Invalid use of key/value parameters' unless partial
|
|
402
518
|
return key_types if types.empty?
|
|
403
519
|
return [key_types, types]
|
|
404
520
|
end
|
|
@@ -410,7 +526,7 @@ module Solargraph
|
|
|
410
526
|
# @param strings [Array<String>]
|
|
411
527
|
# @return [ComplexType]
|
|
412
528
|
def try_parse *strings
|
|
413
|
-
parse
|
|
529
|
+
parse(*strings)
|
|
414
530
|
rescue ComplexTypeError => e
|
|
415
531
|
Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
|
|
416
532
|
ComplexType::UNDEFINED
|
|
@@ -435,9 +551,7 @@ module Solargraph
|
|
|
435
551
|
# @param dst [String]
|
|
436
552
|
# @return [String]
|
|
437
553
|
def reduce_class dst
|
|
438
|
-
while dst =~ /^(Class|Module)
|
|
439
|
-
dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
|
|
440
|
-
end
|
|
554
|
+
dst = dst.sub(/^(Class|Module)</, '').sub(/>$/, '') while dst =~ /^(Class|Module)<(.*?)>$/
|
|
441
555
|
dst
|
|
442
556
|
end
|
|
443
557
|
end
|