solargraph 0.58.3 → 0.60.4
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 +53 -37
- data/.github/workflows/rspec.yml +18 -28
- data/.github/workflows/typecheck.yml +6 -3
- data/.rubocop.yml +39 -6
- data/.rubocop_todo.yml +53 -966
- data/CHANGELOG.md +67 -0
- data/Gemfile +6 -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 +13 -4
- data/lib/solargraph/api_map/index.rb +42 -20
- data/lib/solargraph/api_map/source_to_yard.rb +22 -9
- data/lib/solargraph/api_map/store.rb +61 -36
- data/lib/solargraph/api_map.rb +191 -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 +225 -63
- data/lib/solargraph/complex_type.rb +190 -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 +39 -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 +63 -40
- 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 +222 -72
- 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 +73 -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 +157 -85
- 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 +67 -23
- data/lib/solargraph/pin/closure.rb +7 -10
- data/lib/solargraph/pin/common.rb +36 -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 +208 -113
- 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 +227 -238
- 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/rbs_translator.rb +206 -0
- data/lib/solargraph/server_methods.rb +1 -1
- data/lib/solargraph/shell.rb +330 -71
- 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 +159 -89
- 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 +19 -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 +87 -43
- 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 +71 -43
- 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 +30 -133
- data/lib/solargraph/source_map.rb +35 -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 +208 -125
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/workspace/config.rb +14 -11
- data/lib/solargraph/workspace/gemspecs.rb +373 -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/directives/attribute_directive.rb +65 -0
- data/lib/solargraph/yard_map/directives/domain_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/method_directive.rb +51 -0
- data/lib/solargraph/yard_map/directives/override_directive.rb +30 -0
- data/lib/solargraph/yard_map/directives/parse_directive.rb +53 -0
- data/lib/solargraph/yard_map/directives/visibility_directive.rb +70 -0
- data/lib/solargraph/yard_map/directives.rb +35 -0
- data/lib/solargraph/yard_map/helpers.rb +8 -3
- data/lib/solargraph/yard_map/macro.rb +113 -0
- 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 +65 -9
- data/lib/solargraph/yard_map.rb +19 -18
- data/lib/solargraph/yard_tags.rb +2 -2
- data/lib/solargraph/yardoc.rb +7 -4
- data/lib/solargraph.rb +34 -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 +39 -35
- metadata +77 -41
- 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,78 @@ 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, rules) 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
|
+
# @param rules [Array<Symbol>]
|
|
249
|
+
# @return [Boolean]
|
|
250
|
+
def duck_types_match? api_map, expected, inferred, rules = []
|
|
251
|
+
raise ArgumentError, 'Expected type must be duck type' unless expected.duck_type?
|
|
252
|
+
allow_any_match = rules.include?(:allow_any_match)
|
|
253
|
+
expected.each do |exp|
|
|
254
|
+
next unless exp.duck_type?
|
|
255
|
+
quack = exp.to_s[1..] || ''
|
|
256
|
+
matched = allow_any_match ? inferred.any? { |inf| duck_type_provides?(api_map, inf, quack) } : inferred.all? { |inf| duck_type_provides?(api_map, inf, quack) }
|
|
257
|
+
return false unless matched
|
|
258
|
+
end
|
|
259
|
+
true
|
|
260
|
+
end
|
|
261
|
+
|
|
262
|
+
# @param api_map [ApiMap]
|
|
263
|
+
# @param inf [UniqueType]
|
|
264
|
+
# @param quack [String]
|
|
265
|
+
# @return [Boolean]
|
|
266
|
+
def duck_type_provides? api_map, inf, quack
|
|
267
|
+
return true if inf.duck_type? && inf.to_s[1..] == quack
|
|
268
|
+
|
|
269
|
+
!api_map.get_method_stack(inf.namespace, quack, scope: inf.scope).empty?
|
|
270
|
+
end
|
|
271
|
+
private :duck_type_provides?
|
|
272
|
+
|
|
197
273
|
# @return [String]
|
|
198
274
|
def rooted_tags
|
|
199
275
|
map(&:rooted_tag).join(', ')
|
|
@@ -201,14 +277,14 @@ module Solargraph
|
|
|
201
277
|
|
|
202
278
|
# @yieldparam [UniqueType]
|
|
203
279
|
def all? &block
|
|
204
|
-
@items.all?
|
|
280
|
+
@items.all?(&block)
|
|
205
281
|
end
|
|
206
282
|
|
|
207
283
|
# @yieldparam [UniqueType]
|
|
208
284
|
# @yieldreturn [Boolean]
|
|
209
285
|
# @return [Boolean]
|
|
210
286
|
def any? &block
|
|
211
|
-
@items.compact.any?
|
|
287
|
+
@items.compact.any?(&block)
|
|
212
288
|
end
|
|
213
289
|
|
|
214
290
|
def selfy?
|
|
@@ -228,11 +304,17 @@ module Solargraph
|
|
|
228
304
|
# @yieldparam t [UniqueType]
|
|
229
305
|
# @yieldreturn [UniqueType]
|
|
230
306
|
# @return [ComplexType]
|
|
231
|
-
def transform
|
|
232
|
-
|
|
307
|
+
def transform new_name = nil, &transform_type
|
|
308
|
+
if new_name&.start_with?('::')
|
|
309
|
+
raise "Please remove leading :: and set rooted with recreate() instead - #{new_name}"
|
|
310
|
+
end
|
|
233
311
|
ComplexType.new(map { |ut| ut.transform(new_name, &transform_type) })
|
|
234
312
|
end
|
|
235
313
|
|
|
314
|
+
def expand named_types
|
|
315
|
+
ComplexType.new(map { |ut| ut.expand(named_types) })
|
|
316
|
+
end
|
|
317
|
+
|
|
236
318
|
# @return [self]
|
|
237
319
|
def force_rooted
|
|
238
320
|
transform do |t|
|
|
@@ -252,6 +334,13 @@ module Solargraph
|
|
|
252
334
|
@items.any?(&:nil_type?)
|
|
253
335
|
end
|
|
254
336
|
|
|
337
|
+
# @return [ComplexType]
|
|
338
|
+
def without_nil
|
|
339
|
+
new_items = @items.reject(&:nil_type?)
|
|
340
|
+
return ComplexType::UNDEFINED if new_items.empty?
|
|
341
|
+
ComplexType.new(new_items)
|
|
342
|
+
end
|
|
343
|
+
|
|
255
344
|
# @return [Array<ComplexType>]
|
|
256
345
|
def all_params
|
|
257
346
|
@items.first.all_params || []
|
|
@@ -260,7 +349,7 @@ module Solargraph
|
|
|
260
349
|
# @return [ComplexType]
|
|
261
350
|
def reduce_class_type
|
|
262
351
|
new_items = items.flat_map do |type|
|
|
263
|
-
next type unless [
|
|
352
|
+
next type unless %w[Module Class].include?(type.name)
|
|
264
353
|
next type if type.all_params.empty?
|
|
265
354
|
|
|
266
355
|
type.all_params
|
|
@@ -274,6 +363,13 @@ module Solargraph
|
|
|
274
363
|
all?(&:all_rooted?)
|
|
275
364
|
end
|
|
276
365
|
|
|
366
|
+
# @param other [ComplexType, UniqueType]
|
|
367
|
+
def erased_version_of? other
|
|
368
|
+
return false if items.length != 1 || other.items.length != 1
|
|
369
|
+
|
|
370
|
+
@items.first.erased_version_of?(other.items.first)
|
|
371
|
+
end
|
|
372
|
+
|
|
277
373
|
# every top-level type has resolved to be fully qualified; see
|
|
278
374
|
# #all_rooted? to check their subtypes as well
|
|
279
375
|
def rooted?
|
|
@@ -282,12 +378,46 @@ module Solargraph
|
|
|
282
378
|
|
|
283
379
|
attr_reader :items
|
|
284
380
|
|
|
285
|
-
|
|
286
|
-
|
|
381
|
+
# @param exclude_types [ComplexType, nil]
|
|
382
|
+
# @param api_map [ApiMap]
|
|
383
|
+
# @return [ComplexType, self]
|
|
384
|
+
def exclude exclude_types, api_map
|
|
385
|
+
return self if exclude_types.nil?
|
|
386
|
+
|
|
387
|
+
types = items - exclude_types.items
|
|
388
|
+
types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
|
|
389
|
+
ComplexType.new(types)
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# @see https://en.wikipedia.org/wiki/Intersection_type
|
|
393
|
+
#
|
|
394
|
+
# @param intersection_type [ComplexType, ComplexType::UniqueType, nil]
|
|
395
|
+
# @param api_map [ApiMap]
|
|
396
|
+
# @return [self, ComplexType::UniqueType]
|
|
397
|
+
def intersect_with intersection_type, api_map
|
|
398
|
+
return self if intersection_type.nil?
|
|
399
|
+
return intersection_type if undefined?
|
|
400
|
+
types = []
|
|
401
|
+
# try to find common types via conformance
|
|
402
|
+
items.each do |ut|
|
|
403
|
+
intersection_type.each do |int_type|
|
|
404
|
+
if int_type.conforms_to?(api_map, ut, :assignment)
|
|
405
|
+
types << int_type
|
|
406
|
+
elsif ut.conforms_to?(api_map, int_type, :assignment)
|
|
407
|
+
types << ut
|
|
408
|
+
end
|
|
409
|
+
end
|
|
410
|
+
end
|
|
411
|
+
types = [ComplexType::UniqueType::UNDEFINED] if types.empty?
|
|
412
|
+
ComplexType.new(types)
|
|
287
413
|
end
|
|
288
414
|
|
|
289
415
|
protected
|
|
290
416
|
|
|
417
|
+
def equality_fields
|
|
418
|
+
[self.class, items]
|
|
419
|
+
end
|
|
420
|
+
|
|
291
421
|
# @return [ComplexType]
|
|
292
422
|
def reduce_object
|
|
293
423
|
new_items = items.flat_map do |ut|
|
|
@@ -307,30 +437,29 @@ module Solargraph
|
|
|
307
437
|
# @example
|
|
308
438
|
# ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
|
|
309
439
|
#
|
|
310
|
-
# @
|
|
311
|
-
#
|
|
312
|
-
#
|
|
313
|
-
#
|
|
314
|
-
#
|
|
315
|
-
# used internally.
|
|
316
|
-
#
|
|
440
|
+
# @param partial [Boolean] if true, method is receiving a string
|
|
441
|
+
# that will be used inside another ComplexType. It returns
|
|
442
|
+
# arrays of ComplexTypes instead of a single cohesive one.
|
|
443
|
+
# Consumers should not need to use this parameter; it should
|
|
444
|
+
# only be used internally.
|
|
317
445
|
# @param strings [Array<String>] The type definitions to parse
|
|
318
446
|
# @return [ComplexType]
|
|
319
447
|
# # @overload parse(*strings, partial: false)
|
|
320
448
|
# # @todo Need ability to use a literal true as a type below
|
|
321
449
|
# # @param partial [Boolean] True if the string is part of a another type
|
|
322
450
|
# # @return [Array<UniqueType>]
|
|
323
|
-
# @
|
|
451
|
+
# @sg-ignore To be able to select the right signature above,
|
|
324
452
|
# Chain::Call needs to know the decl type (:arg, :optarg,
|
|
325
453
|
# :kwarg, etc) of the arguments given, instead of just having
|
|
326
454
|
# an array of Chains as the arguments.
|
|
327
455
|
def parse *strings, partial: false
|
|
328
|
-
# @type [Hash{Array<String> => ComplexType}]
|
|
456
|
+
# @type [Hash{Array<String> => ComplexType, Array<ComplexType::UniqueType>}]
|
|
329
457
|
@cache ||= {}
|
|
330
458
|
unless partial
|
|
331
459
|
cached = @cache[strings]
|
|
332
460
|
return cached unless cached.nil?
|
|
333
461
|
end
|
|
462
|
+
# @types [Array<ComplexType::UniqueType>]
|
|
334
463
|
types = []
|
|
335
464
|
key_types = nil
|
|
336
465
|
strings.each do |type_string|
|
|
@@ -342,15 +471,16 @@ module Solargraph
|
|
|
342
471
|
# @param char [String]
|
|
343
472
|
type_string&.each_char do |char|
|
|
344
473
|
if char == '='
|
|
345
|
-
#raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
474
|
+
# raise ComplexTypeError, "Invalid = in type #{type_string}" unless curly_stack > 0
|
|
346
475
|
elsif char == '<'
|
|
347
476
|
point_stack += 1
|
|
348
477
|
elsif char == '>'
|
|
349
|
-
if subtype_string.end_with?('=') && curly_stack
|
|
478
|
+
if subtype_string.end_with?('=') && curly_stack.positive?
|
|
350
479
|
subtype_string += char
|
|
351
480
|
elsif base.end_with?('=')
|
|
352
|
-
raise ComplexTypeError,
|
|
481
|
+
raise ComplexTypeError, 'Invalid hash thing' unless key_types.nil?
|
|
353
482
|
# types.push ComplexType.new([UniqueType.new(base[0..-2].strip)])
|
|
483
|
+
# @sg-ignore Need to add nil check here
|
|
354
484
|
types.push UniqueType.parse(base[0..-2].strip, subtype_string)
|
|
355
485
|
# @todo this should either expand key_type's type
|
|
356
486
|
# automatically or complain about not being
|
|
@@ -361,7 +491,7 @@ module Solargraph
|
|
|
361
491
|
subtype_string.clear
|
|
362
492
|
next
|
|
363
493
|
else
|
|
364
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack
|
|
494
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if point_stack.zero?
|
|
365
495
|
point_stack -= 1
|
|
366
496
|
subtype_string += char
|
|
367
497
|
end
|
|
@@ -371,34 +501,37 @@ module Solargraph
|
|
|
371
501
|
elsif char == '}'
|
|
372
502
|
curly_stack -= 1
|
|
373
503
|
subtype_string += char
|
|
374
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack
|
|
504
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if curly_stack.negative?
|
|
375
505
|
next
|
|
376
506
|
elsif char == '('
|
|
377
507
|
paren_stack += 1
|
|
378
508
|
elsif char == ')'
|
|
379
509
|
paren_stack -= 1
|
|
380
510
|
subtype_string += char
|
|
381
|
-
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack
|
|
511
|
+
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack.negative?
|
|
382
512
|
next
|
|
383
|
-
elsif char == ',' && point_stack
|
|
513
|
+
elsif char == ',' && point_stack.zero? && curly_stack.zero? && paren_stack.zero?
|
|
384
514
|
# types.push ComplexType.new([UniqueType.new(base.strip, subtype_string.strip)])
|
|
385
515
|
types.push UniqueType.parse(base.strip, subtype_string.strip)
|
|
386
516
|
base.clear
|
|
387
517
|
subtype_string.clear
|
|
388
518
|
next
|
|
389
519
|
end
|
|
390
|
-
if point_stack
|
|
520
|
+
if point_stack.zero? && curly_stack.zero? && paren_stack.zero?
|
|
391
521
|
base.concat char
|
|
392
522
|
else
|
|
393
523
|
subtype_string.concat char
|
|
394
524
|
end
|
|
395
525
|
end
|
|
396
|
-
|
|
526
|
+
if point_stack != 0 || curly_stack != 0 || paren_stack != 0
|
|
527
|
+
raise ComplexTypeError,
|
|
528
|
+
"Unclosed subtype in #{type_string}"
|
|
529
|
+
end
|
|
397
530
|
# types.push ComplexType.new([UniqueType.new(base, subtype_string)])
|
|
398
531
|
types.push UniqueType.parse(base.strip, subtype_string.strip)
|
|
399
532
|
end
|
|
400
533
|
unless key_types.nil?
|
|
401
|
-
raise ComplexTypeError,
|
|
534
|
+
raise ComplexTypeError, 'Invalid use of key/value parameters' unless partial
|
|
402
535
|
return key_types if types.empty?
|
|
403
536
|
return [key_types, types]
|
|
404
537
|
end
|
|
@@ -410,7 +543,7 @@ module Solargraph
|
|
|
410
543
|
# @param strings [Array<String>]
|
|
411
544
|
# @return [ComplexType]
|
|
412
545
|
def try_parse *strings
|
|
413
|
-
parse
|
|
546
|
+
parse(*strings)
|
|
414
547
|
rescue ComplexTypeError => e
|
|
415
548
|
Solargraph.logger.info "Error parsing complex type `#{strings.join(', ')}`: #{e.message}"
|
|
416
549
|
ComplexType::UNDEFINED
|
|
@@ -435,9 +568,7 @@ module Solargraph
|
|
|
435
568
|
# @param dst [String]
|
|
436
569
|
# @return [String]
|
|
437
570
|
def reduce_class dst
|
|
438
|
-
while dst =~ /^(Class|Module)
|
|
439
|
-
dst = dst.sub(/^(Class|Module)\</, '').sub(/\>$/, '')
|
|
440
|
-
end
|
|
571
|
+
dst = dst.sub(/^(Class|Module)</, '').sub(/>$/, '') while dst =~ /^(Class|Module)<(.*?)>$/
|
|
441
572
|
dst
|
|
442
573
|
end
|
|
443
574
|
end
|