solargraph 0.44.2 → 0.46.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.github/workflows/rspec.yml +41 -0
- data/.gitignore +9 -9
- data/.rspec +2 -2
- data/.travis.yml +19 -19
- data/CHANGELOG.md +1115 -1088
- data/Gemfile +0 -0
- data/LICENSE +0 -0
- data/README.md +128 -120
- data/Rakefile +0 -0
- data/SPONSORS.md +18 -15
- data/bin/solargraph +0 -0
- data/lib/solargraph/api_map/bundler_methods.rb +22 -22
- data/lib/solargraph/api_map/cache.rb +70 -70
- data/lib/solargraph/api_map/source_to_yard.rb +81 -81
- data/lib/solargraph/api_map/store.rb +256 -256
- data/lib/solargraph/api_map.rb +686 -681
- data/lib/solargraph/bench.rb +27 -27
- data/lib/solargraph/compat.rb +37 -37
- data/lib/solargraph/complex_type/type_methods.rb +130 -130
- data/lib/solargraph/complex_type/unique_type.rb +75 -75
- data/lib/solargraph/complex_type.rb +221 -221
- data/lib/solargraph/convention/base.rb +33 -33
- data/lib/solargraph/convention/gemfile.rb +15 -15
- data/lib/solargraph/convention/gemspec.rb +22 -22
- data/lib/solargraph/convention/rspec.rb +30 -21
- data/lib/solargraph/convention.rb +47 -47
- data/lib/solargraph/converters/dd.rb +12 -12
- data/lib/solargraph/converters/dl.rb +12 -12
- data/lib/solargraph/converters/dt.rb +12 -12
- data/lib/solargraph/converters/misc.rb +1 -1
- data/lib/solargraph/diagnostics/base.rb +29 -29
- data/lib/solargraph/diagnostics/require_not_found.rb +53 -37
- data/lib/solargraph/diagnostics/rubocop.rb +98 -98
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +63 -63
- data/lib/solargraph/diagnostics/severities.rb +15 -15
- data/lib/solargraph/diagnostics/type_check.rb +54 -54
- data/lib/solargraph/diagnostics/update_errors.rb +41 -41
- data/lib/solargraph/diagnostics.rb +55 -55
- data/lib/solargraph/documentor.rb +76 -76
- data/lib/solargraph/environ.rb +45 -45
- data/lib/solargraph/language_server/completion_item_kinds.rb +35 -35
- data/lib/solargraph/language_server/error_codes.rb +20 -20
- data/lib/solargraph/language_server/host/cataloger.rb +56 -56
- data/lib/solargraph/language_server/host/diagnoser.rb +89 -89
- data/lib/solargraph/language_server/host/dispatch.rb +111 -111
- data/lib/solargraph/language_server/host/message_worker.rb +59 -59
- data/lib/solargraph/language_server/host/sources.rb +156 -156
- data/lib/solargraph/language_server/host.rb +865 -865
- data/lib/solargraph/language_server/message/base.rb +89 -89
- data/lib/solargraph/language_server/message/cancel_request.rb +13 -13
- data/lib/solargraph/language_server/message/client/register_capability.rb +15 -15
- data/lib/solargraph/language_server/message/client.rb +11 -11
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +58 -58
- data/lib/solargraph/language_server/message/completion_item.rb +11 -11
- data/lib/solargraph/language_server/message/exit_notification.rb +13 -13
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +100 -100
- data/lib/solargraph/language_server/message/extended/document.rb +20 -20
- data/lib/solargraph/language_server/message/extended/document_gems.rb +32 -32
- data/lib/solargraph/language_server/message/extended/download_core.rb +23 -23
- data/lib/solargraph/language_server/message/extended/environment.rb +25 -25
- data/lib/solargraph/language_server/message/extended/search.rb +20 -20
- data/lib/solargraph/language_server/message/extended.rb +21 -21
- data/lib/solargraph/language_server/message/initialize.rb +162 -162
- data/lib/solargraph/language_server/message/initialized.rb +27 -27
- data/lib/solargraph/language_server/message/method_not_found.rb +16 -16
- data/lib/solargraph/language_server/message/method_not_implemented.rb +14 -14
- data/lib/solargraph/language_server/message/shutdown.rb +13 -13
- data/lib/solargraph/language_server/message/text_document/base.rb +19 -19
- data/lib/solargraph/language_server/message/text_document/code_action.rb +17 -17
- data/lib/solargraph/language_server/message/text_document/completion.rb +59 -59
- data/lib/solargraph/language_server/message/text_document/definition.rb +38 -38
- data/lib/solargraph/language_server/message/text_document/did_change.rb +15 -15
- data/lib/solargraph/language_server/message/text_document/did_close.rb +15 -15
- data/lib/solargraph/language_server/message/text_document/did_open.rb +15 -15
- data/lib/solargraph/language_server/message/text_document/did_save.rb +17 -17
- data/lib/solargraph/language_server/message/text_document/document_highlight.rb +16 -16
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +23 -23
- data/lib/solargraph/language_server/message/text_document/folding_range.rb +26 -26
- data/lib/solargraph/language_server/message/text_document/formatting.rb +126 -126
- data/lib/solargraph/language_server/message/text_document/hover.rb +54 -44
- data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +34 -34
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +11 -11
- data/lib/solargraph/language_server/message/text_document/references.rb +16 -16
- data/lib/solargraph/language_server/message/text_document/rename.rb +19 -19
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +29 -29
- data/lib/solargraph/language_server/message/text_document.rb +28 -28
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +30 -30
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +33 -33
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +23 -23
- data/lib/solargraph/language_server/message/workspace.rb +14 -14
- data/lib/solargraph/language_server/message.rb +93 -93
- data/lib/solargraph/language_server/message_types.rb +14 -14
- data/lib/solargraph/language_server/request.rb +24 -24
- data/lib/solargraph/language_server/symbol_kinds.rb +36 -36
- data/lib/solargraph/language_server/transport/adapter.rb +53 -53
- data/lib/solargraph/language_server/transport/data_reader.rb +72 -72
- data/lib/solargraph/language_server/transport.rb +13 -13
- data/lib/solargraph/language_server/uri_helpers.rb +49 -49
- data/lib/solargraph/language_server.rb +19 -19
- data/lib/solargraph/library.rb +546 -546
- data/lib/solargraph/location.rb +37 -37
- data/lib/solargraph/logging.rb +27 -27
- data/lib/solargraph/page.rb +83 -83
- data/lib/solargraph/parser/comment_ripper.rb +52 -52
- data/lib/solargraph/parser/legacy/class_methods.rb +135 -140
- data/lib/solargraph/parser/legacy/flawed_builder.rb +16 -16
- data/lib/solargraph/parser/legacy/node_chainer.rb +148 -148
- data/lib/solargraph/parser/legacy/node_methods.rb +325 -325
- data/lib/solargraph/parser/legacy/node_processors/alias_node.rb +23 -23
- data/lib/solargraph/parser/legacy/node_processors/args_node.rb +35 -35
- data/lib/solargraph/parser/legacy/node_processors/begin_node.rb +15 -15
- data/lib/solargraph/parser/legacy/node_processors/block_node.rb +42 -42
- data/lib/solargraph/parser/legacy/node_processors/casgn_node.rb +25 -25
- data/lib/solargraph/parser/legacy/node_processors/cvasgn_node.rb +23 -23
- data/lib/solargraph/parser/legacy/node_processors/def_node.rb +63 -63
- data/lib/solargraph/parser/legacy/node_processors/defs_node.rb +36 -36
- data/lib/solargraph/parser/legacy/node_processors/gvasgn_node.rb +23 -23
- data/lib/solargraph/parser/legacy/node_processors/ivasgn_node.rb +38 -38
- data/lib/solargraph/parser/legacy/node_processors/lvasgn_node.rb +28 -28
- data/lib/solargraph/parser/legacy/node_processors/namespace_node.rb +39 -39
- data/lib/solargraph/parser/legacy/node_processors/orasgn_node.rb +16 -16
- data/lib/solargraph/parser/legacy/node_processors/resbody_node.rb +36 -36
- data/lib/solargraph/parser/legacy/node_processors/sclass_node.rb +21 -21
- data/lib/solargraph/parser/legacy/node_processors/send_node.rb +257 -257
- data/lib/solargraph/parser/legacy/node_processors/sym_node.rb +18 -18
- data/lib/solargraph/parser/legacy/node_processors.rb +54 -54
- data/lib/solargraph/parser/legacy.rb +12 -12
- data/lib/solargraph/parser/node_methods.rb +43 -43
- data/lib/solargraph/parser/node_processor/base.rb +77 -77
- data/lib/solargraph/parser/node_processor.rb +43 -43
- data/lib/solargraph/parser/region.rb +66 -66
- data/lib/solargraph/parser/rubyvm/class_methods.rb +144 -155
- data/lib/solargraph/parser/rubyvm/node_chainer.rb +160 -160
- data/lib/solargraph/parser/rubyvm/node_methods.rb +315 -315
- data/lib/solargraph/parser/rubyvm/node_processors/alias_node.rb +23 -23
- data/lib/solargraph/parser/rubyvm/node_processors/args_node.rb +85 -85
- data/lib/solargraph/parser/rubyvm/node_processors/begin_node.rb +15 -15
- data/lib/solargraph/parser/rubyvm/node_processors/block_node.rb +42 -42
- data/lib/solargraph/parser/rubyvm/node_processors/casgn_node.rb +22 -22
- data/lib/solargraph/parser/rubyvm/node_processors/cvasgn_node.rb +23 -23
- data/lib/solargraph/parser/rubyvm/node_processors/def_node.rb +63 -64
- data/lib/solargraph/parser/rubyvm/node_processors/defs_node.rb +57 -57
- data/lib/solargraph/parser/rubyvm/node_processors/gvasgn_node.rb +23 -23
- data/lib/solargraph/parser/rubyvm/node_processors/ivasgn_node.rb +38 -38
- data/lib/solargraph/parser/rubyvm/node_processors/kw_arg_node.rb +39 -39
- data/lib/solargraph/parser/rubyvm/node_processors/lit_node.rb +20 -20
- data/lib/solargraph/parser/rubyvm/node_processors/lvasgn_node.rb +27 -27
- data/lib/solargraph/parser/rubyvm/node_processors/namespace_node.rb +39 -39
- data/lib/solargraph/parser/rubyvm/node_processors/opt_arg_node.rb +26 -26
- data/lib/solargraph/parser/rubyvm/node_processors/orasgn_node.rb +15 -15
- data/lib/solargraph/parser/rubyvm/node_processors/resbody_node.rb +45 -45
- data/lib/solargraph/parser/rubyvm/node_processors/sclass_node.rb +21 -21
- data/lib/solargraph/parser/rubyvm/node_processors/scope_node.rb +15 -15
- data/lib/solargraph/parser/rubyvm/node_processors/send_node.rb +277 -277
- data/lib/solargraph/parser/rubyvm/node_processors/sym_node.rb +18 -18
- data/lib/solargraph/parser/rubyvm/node_processors.rb +63 -62
- data/lib/solargraph/parser/rubyvm.rb +40 -40
- data/lib/solargraph/parser/snippet.rb +13 -13
- data/lib/solargraph/parser.rb +26 -26
- data/lib/solargraph/pin/base.rb +296 -296
- data/lib/solargraph/pin/base_variable.rb +84 -84
- data/lib/solargraph/pin/block.rb +72 -72
- data/lib/solargraph/pin/class_variable.rb +8 -8
- data/lib/solargraph/pin/closure.rb +37 -37
- data/lib/solargraph/pin/common.rb +70 -70
- data/lib/solargraph/pin/constant.rb +43 -43
- data/lib/solargraph/pin/conversions.rb +96 -96
- data/lib/solargraph/pin/documenting.rb +105 -105
- data/lib/solargraph/pin/duck_method.rb +16 -16
- data/lib/solargraph/pin/global_variable.rb +8 -8
- data/lib/solargraph/pin/instance_variable.rb +30 -30
- data/lib/solargraph/pin/keyword.rb +15 -15
- data/lib/solargraph/pin/keyword_param.rb +8 -8
- data/lib/solargraph/pin/local_variable.rb +55 -55
- data/lib/solargraph/pin/method.rb +245 -245
- data/lib/solargraph/pin/method_alias.rb +31 -31
- data/lib/solargraph/pin/namespace.rb +91 -91
- data/lib/solargraph/pin/parameter.rb +201 -206
- data/lib/solargraph/pin/proxy_type.rb +29 -29
- data/lib/solargraph/pin/reference/extend.rb +10 -10
- data/lib/solargraph/pin/reference/include.rb +10 -10
- data/lib/solargraph/pin/reference/override.rb +29 -29
- data/lib/solargraph/pin/reference/prepend.rb +10 -10
- data/lib/solargraph/pin/reference/require.rb +14 -14
- data/lib/solargraph/pin/reference/superclass.rb +10 -10
- data/lib/solargraph/pin/reference.rb +14 -14
- data/lib/solargraph/pin/search.rb +56 -0
- data/lib/solargraph/pin/singleton.rb +11 -11
- data/lib/solargraph/pin/symbol.rb +47 -47
- data/lib/solargraph/pin.rb +37 -36
- data/lib/solargraph/position.rb +100 -100
- data/lib/solargraph/range.rb +95 -95
- data/lib/solargraph/server_methods.rb +16 -16
- data/lib/solargraph/shell.rb +226 -226
- data/lib/solargraph/source/chain/block_variable.rb +13 -13
- data/lib/solargraph/source/chain/call.rb +204 -204
- data/lib/solargraph/source/chain/class_variable.rb +13 -13
- data/lib/solargraph/source/chain/constant.rb +75 -75
- data/lib/solargraph/source/chain/global_variable.rb +13 -13
- data/lib/solargraph/source/chain/hash.rb +28 -28
- data/lib/solargraph/source/chain/head.rb +19 -19
- data/lib/solargraph/source/chain/instance_variable.rb +13 -13
- data/lib/solargraph/source/chain/link.rb +71 -71
- data/lib/solargraph/source/chain/literal.rb +23 -23
- data/lib/solargraph/source/chain/or.rb +23 -23
- data/lib/solargraph/source/chain/q_call.rb +11 -11
- data/lib/solargraph/source/chain/variable.rb +13 -13
- data/lib/solargraph/source/chain/z_super.rb +30 -30
- data/lib/solargraph/source/chain.rb +164 -164
- data/lib/solargraph/source/change.rb +79 -79
- data/lib/solargraph/source/cursor.rb +164 -164
- data/lib/solargraph/source/source_chainer.rb +191 -191
- data/lib/solargraph/source/updater.rb +54 -54
- data/lib/solargraph/source.rb +522 -522
- data/lib/solargraph/source_map/clip.rb +224 -224
- data/lib/solargraph/source_map/completion.rb +23 -23
- data/lib/solargraph/source_map/mapper.rb +212 -212
- data/lib/solargraph/source_map.rb +180 -189
- data/lib/solargraph/type_checker/checks.rb +99 -99
- data/lib/solargraph/type_checker/param_def.rb +35 -35
- data/lib/solargraph/type_checker/problem.rb +32 -32
- data/lib/solargraph/type_checker/rules.rb +57 -57
- data/lib/solargraph/type_checker.rb +543 -510
- data/lib/solargraph/version.rb +5 -5
- data/lib/solargraph/views/environment.erb +58 -58
- data/lib/solargraph/workspace/config.rb +231 -231
- data/lib/solargraph/workspace.rb +215 -214
- data/lib/solargraph/yard_map/cache.rb +19 -19
- data/lib/solargraph/yard_map/core_docs.rb +170 -170
- data/lib/solargraph/yard_map/core_fills.rb +208 -203
- data/lib/solargraph/yard_map/core_gen.rb +76 -76
- data/lib/solargraph/yard_map/helpers.rb +16 -16
- data/lib/solargraph/yard_map/mapper/to_constant.rb +25 -25
- data/lib/solargraph/yard_map/mapper/to_method.rb +78 -78
- data/lib/solargraph/yard_map/mapper/to_namespace.rb +27 -27
- data/lib/solargraph/yard_map/mapper.rb +77 -77
- data/lib/solargraph/yard_map/rdoc_to_yard.rb +140 -140
- data/lib/solargraph/yard_map/stdlib_fills.rb +43 -43
- data/lib/solargraph/yard_map/to_method.rb +79 -79
- data/lib/solargraph/yard_map.rb +460 -443
- data/lib/solargraph.rb +69 -69
- data/lib/yard-solargraph.rb +33 -33
- data/solargraph.gemspec +0 -0
- metadata +14 -12
|
@@ -1,164 +1,164 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
# HACK: Fix autoload issue
|
|
4
|
-
require 'solargraph/source/chain/link'
|
|
5
|
-
|
|
6
|
-
module Solargraph
|
|
7
|
-
class Source
|
|
8
|
-
# A chain of constants, variables, and method calls for inferring types of
|
|
9
|
-
# values.
|
|
10
|
-
#
|
|
11
|
-
class Chain
|
|
12
|
-
autoload :Link, 'solargraph/source/chain/link'
|
|
13
|
-
autoload :Call, 'solargraph/source/chain/call'
|
|
14
|
-
autoload :QCall, 'solargraph/source/chain/q_call'
|
|
15
|
-
autoload :Variable, 'solargraph/source/chain/variable'
|
|
16
|
-
autoload :ClassVariable, 'solargraph/source/chain/class_variable'
|
|
17
|
-
autoload :Constant, 'solargraph/source/chain/constant'
|
|
18
|
-
autoload :InstanceVariable, 'solargraph/source/chain/instance_variable'
|
|
19
|
-
autoload :GlobalVariable, 'solargraph/source/chain/global_variable'
|
|
20
|
-
autoload :Literal, 'solargraph/source/chain/literal'
|
|
21
|
-
autoload :Head, 'solargraph/source/chain/head'
|
|
22
|
-
autoload :Or, 'solargraph/source/chain/or'
|
|
23
|
-
autoload :BlockVariable, 'solargraph/source/chain/block_variable'
|
|
24
|
-
autoload :ZSuper, 'solargraph/source/chain/z_super'
|
|
25
|
-
autoload :Hash, 'solargraph/source/chain/hash'
|
|
26
|
-
|
|
27
|
-
@@inference_stack = []
|
|
28
|
-
@@inference_depth = 0
|
|
29
|
-
|
|
30
|
-
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
|
31
|
-
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
|
32
|
-
|
|
33
|
-
# @return [Array<Source::Chain::Link>]
|
|
34
|
-
attr_reader :links
|
|
35
|
-
|
|
36
|
-
attr_reader :node
|
|
37
|
-
|
|
38
|
-
# @param links [Array<Chain::Link>]
|
|
39
|
-
def initialize links, node = nil, splat = false
|
|
40
|
-
@links = links.clone
|
|
41
|
-
@links.push UNDEFINED_CALL if @links.empty?
|
|
42
|
-
head = true
|
|
43
|
-
@links.map! do |link|
|
|
44
|
-
result = (head ? link.clone_head : link.clone_body)
|
|
45
|
-
head = false
|
|
46
|
-
result
|
|
47
|
-
end
|
|
48
|
-
@node = node
|
|
49
|
-
@splat = splat
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# @return [Chain]
|
|
53
|
-
def base
|
|
54
|
-
@base ||= Chain.new(links[0..-2])
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
# @param api_map [ApiMap]
|
|
58
|
-
# @param name_pin [Pin::Base]
|
|
59
|
-
# @param locals [Array<Pin::Base>]
|
|
60
|
-
# @return [Array<Pin::Base>]
|
|
61
|
-
def define api_map, name_pin, locals
|
|
62
|
-
return [] if undefined?
|
|
63
|
-
working_pin = name_pin
|
|
64
|
-
links[0..-2].each do |link|
|
|
65
|
-
pins = link.resolve(api_map, working_pin, locals)
|
|
66
|
-
type = infer_first_defined(pins, working_pin, api_map)
|
|
67
|
-
return [] if type.undefined?
|
|
68
|
-
working_pin = Pin::ProxyType.anonymous(type)
|
|
69
|
-
end
|
|
70
|
-
links.last.last_context = working_pin
|
|
71
|
-
links.last.resolve(api_map, working_pin, locals)
|
|
72
|
-
end
|
|
73
|
-
|
|
74
|
-
# @param api_map [ApiMap]
|
|
75
|
-
# @param name_pin [Pin::Base]
|
|
76
|
-
# @param locals [Array<Pin::Base>]
|
|
77
|
-
# @return [ComplexType]
|
|
78
|
-
def infer api_map, name_pin, locals
|
|
79
|
-
pins = define(api_map, name_pin, locals)
|
|
80
|
-
type = infer_first_defined(pins, links.last.last_context, api_map)
|
|
81
|
-
maybe_nil(type)
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
# @return [Boolean]
|
|
85
|
-
def literal?
|
|
86
|
-
links.last.is_a?(Chain::Literal)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def undefined?
|
|
90
|
-
links.any?(&:undefined?)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def defined?
|
|
94
|
-
!undefined?
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
# @return [Boolean]
|
|
98
|
-
def constant?
|
|
99
|
-
links.last.is_a?(Chain::Constant)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def splat?
|
|
103
|
-
@splat
|
|
104
|
-
end
|
|
105
|
-
|
|
106
|
-
def nullable?
|
|
107
|
-
links.any?(&:nullable?)
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
private
|
|
111
|
-
|
|
112
|
-
# @param pins [Array<Pin::Base>]
|
|
113
|
-
# @param api_map [ApiMap]
|
|
114
|
-
# @return [ComplexType]
|
|
115
|
-
def infer_first_defined pins, context, api_map
|
|
116
|
-
possibles = []
|
|
117
|
-
pins.each do |pin|
|
|
118
|
-
# Avoid infinite recursion
|
|
119
|
-
next if @@inference_stack.include?(pin.identity)
|
|
120
|
-
@@inference_stack.push pin.identity
|
|
121
|
-
type = pin.typify(api_map)
|
|
122
|
-
@@inference_stack.pop
|
|
123
|
-
if type.defined?
|
|
124
|
-
possibles.push type
|
|
125
|
-
break if pin.is_a?(Pin::Method)
|
|
126
|
-
end
|
|
127
|
-
end
|
|
128
|
-
if possibles.empty?
|
|
129
|
-
# Limit method inference recursion
|
|
130
|
-
return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
|
131
|
-
@@inference_depth += 1
|
|
132
|
-
pins.each do |pin|
|
|
133
|
-
# Avoid infinite recursion
|
|
134
|
-
next if @@inference_stack.include?(pin.identity)
|
|
135
|
-
@@inference_stack.push pin.identity
|
|
136
|
-
type = pin.probe(api_map)
|
|
137
|
-
@@inference_stack.pop
|
|
138
|
-
if type.defined?
|
|
139
|
-
possibles.push type
|
|
140
|
-
break if pin.is_a?(Pin::Method)
|
|
141
|
-
end
|
|
142
|
-
end
|
|
143
|
-
@@inference_depth -= 1
|
|
144
|
-
end
|
|
145
|
-
return ComplexType::UNDEFINED if possibles.empty?
|
|
146
|
-
type = if possibles.length > 1
|
|
147
|
-
sorted = possibles.map { |t| t.rooted? ? "::#{t}" : t.to_s }.sort { |a, _| a == 'nil' ? 1 : 0 }
|
|
148
|
-
ComplexType.parse(*sorted)
|
|
149
|
-
else
|
|
150
|
-
possibles.first
|
|
151
|
-
end
|
|
152
|
-
return type if context.nil? || context.return_type.undefined?
|
|
153
|
-
type.self_to(context.return_type.namespace)
|
|
154
|
-
end
|
|
155
|
-
|
|
156
|
-
# @param type [ComplexType]
|
|
157
|
-
def maybe_nil type
|
|
158
|
-
return type if type.undefined? || type.void? || type.nullable?
|
|
159
|
-
return type unless nullable?
|
|
160
|
-
ComplexType.try_parse("#{type}, nil")
|
|
161
|
-
end
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
# HACK: Fix autoload issue
|
|
4
|
+
require 'solargraph/source/chain/link'
|
|
5
|
+
|
|
6
|
+
module Solargraph
|
|
7
|
+
class Source
|
|
8
|
+
# A chain of constants, variables, and method calls for inferring types of
|
|
9
|
+
# values.
|
|
10
|
+
#
|
|
11
|
+
class Chain
|
|
12
|
+
autoload :Link, 'solargraph/source/chain/link'
|
|
13
|
+
autoload :Call, 'solargraph/source/chain/call'
|
|
14
|
+
autoload :QCall, 'solargraph/source/chain/q_call'
|
|
15
|
+
autoload :Variable, 'solargraph/source/chain/variable'
|
|
16
|
+
autoload :ClassVariable, 'solargraph/source/chain/class_variable'
|
|
17
|
+
autoload :Constant, 'solargraph/source/chain/constant'
|
|
18
|
+
autoload :InstanceVariable, 'solargraph/source/chain/instance_variable'
|
|
19
|
+
autoload :GlobalVariable, 'solargraph/source/chain/global_variable'
|
|
20
|
+
autoload :Literal, 'solargraph/source/chain/literal'
|
|
21
|
+
autoload :Head, 'solargraph/source/chain/head'
|
|
22
|
+
autoload :Or, 'solargraph/source/chain/or'
|
|
23
|
+
autoload :BlockVariable, 'solargraph/source/chain/block_variable'
|
|
24
|
+
autoload :ZSuper, 'solargraph/source/chain/z_super'
|
|
25
|
+
autoload :Hash, 'solargraph/source/chain/hash'
|
|
26
|
+
|
|
27
|
+
@@inference_stack = []
|
|
28
|
+
@@inference_depth = 0
|
|
29
|
+
|
|
30
|
+
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
|
31
|
+
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
|
32
|
+
|
|
33
|
+
# @return [Array<Source::Chain::Link>]
|
|
34
|
+
attr_reader :links
|
|
35
|
+
|
|
36
|
+
attr_reader :node
|
|
37
|
+
|
|
38
|
+
# @param links [Array<Chain::Link>]
|
|
39
|
+
def initialize links, node = nil, splat = false
|
|
40
|
+
@links = links.clone
|
|
41
|
+
@links.push UNDEFINED_CALL if @links.empty?
|
|
42
|
+
head = true
|
|
43
|
+
@links.map! do |link|
|
|
44
|
+
result = (head ? link.clone_head : link.clone_body)
|
|
45
|
+
head = false
|
|
46
|
+
result
|
|
47
|
+
end
|
|
48
|
+
@node = node
|
|
49
|
+
@splat = splat
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
# @return [Chain]
|
|
53
|
+
def base
|
|
54
|
+
@base ||= Chain.new(links[0..-2])
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
# @param api_map [ApiMap]
|
|
58
|
+
# @param name_pin [Pin::Base]
|
|
59
|
+
# @param locals [Array<Pin::Base>]
|
|
60
|
+
# @return [Array<Pin::Base>]
|
|
61
|
+
def define api_map, name_pin, locals
|
|
62
|
+
return [] if undefined?
|
|
63
|
+
working_pin = name_pin
|
|
64
|
+
links[0..-2].each do |link|
|
|
65
|
+
pins = link.resolve(api_map, working_pin, locals)
|
|
66
|
+
type = infer_first_defined(pins, working_pin, api_map)
|
|
67
|
+
return [] if type.undefined?
|
|
68
|
+
working_pin = Pin::ProxyType.anonymous(type)
|
|
69
|
+
end
|
|
70
|
+
links.last.last_context = working_pin
|
|
71
|
+
links.last.resolve(api_map, working_pin, locals)
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
# @param api_map [ApiMap]
|
|
75
|
+
# @param name_pin [Pin::Base]
|
|
76
|
+
# @param locals [Array<Pin::Base>]
|
|
77
|
+
# @return [ComplexType]
|
|
78
|
+
def infer api_map, name_pin, locals
|
|
79
|
+
pins = define(api_map, name_pin, locals)
|
|
80
|
+
type = infer_first_defined(pins, links.last.last_context, api_map)
|
|
81
|
+
maybe_nil(type)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
# @return [Boolean]
|
|
85
|
+
def literal?
|
|
86
|
+
links.last.is_a?(Chain::Literal)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def undefined?
|
|
90
|
+
links.any?(&:undefined?)
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def defined?
|
|
94
|
+
!undefined?
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# @return [Boolean]
|
|
98
|
+
def constant?
|
|
99
|
+
links.last.is_a?(Chain::Constant)
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
def splat?
|
|
103
|
+
@splat
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def nullable?
|
|
107
|
+
links.any?(&:nullable?)
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
private
|
|
111
|
+
|
|
112
|
+
# @param pins [Array<Pin::Base>]
|
|
113
|
+
# @param api_map [ApiMap]
|
|
114
|
+
# @return [ComplexType]
|
|
115
|
+
def infer_first_defined pins, context, api_map
|
|
116
|
+
possibles = []
|
|
117
|
+
pins.each do |pin|
|
|
118
|
+
# Avoid infinite recursion
|
|
119
|
+
next if @@inference_stack.include?(pin.identity)
|
|
120
|
+
@@inference_stack.push pin.identity
|
|
121
|
+
type = pin.typify(api_map)
|
|
122
|
+
@@inference_stack.pop
|
|
123
|
+
if type.defined?
|
|
124
|
+
possibles.push type
|
|
125
|
+
break if pin.is_a?(Pin::Method)
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
if possibles.empty?
|
|
129
|
+
# Limit method inference recursion
|
|
130
|
+
return ComplexType::UNDEFINED if @@inference_depth >= 10 && pins.first.is_a?(Pin::Method)
|
|
131
|
+
@@inference_depth += 1
|
|
132
|
+
pins.each do |pin|
|
|
133
|
+
# Avoid infinite recursion
|
|
134
|
+
next if @@inference_stack.include?(pin.identity)
|
|
135
|
+
@@inference_stack.push pin.identity
|
|
136
|
+
type = pin.probe(api_map)
|
|
137
|
+
@@inference_stack.pop
|
|
138
|
+
if type.defined?
|
|
139
|
+
possibles.push type
|
|
140
|
+
break if pin.is_a?(Pin::Method)
|
|
141
|
+
end
|
|
142
|
+
end
|
|
143
|
+
@@inference_depth -= 1
|
|
144
|
+
end
|
|
145
|
+
return ComplexType::UNDEFINED if possibles.empty?
|
|
146
|
+
type = if possibles.length > 1
|
|
147
|
+
sorted = possibles.map { |t| t.rooted? ? "::#{t}" : t.to_s }.sort { |a, _| a == 'nil' ? 1 : 0 }
|
|
148
|
+
ComplexType.parse(*sorted)
|
|
149
|
+
else
|
|
150
|
+
possibles.first
|
|
151
|
+
end
|
|
152
|
+
return type if context.nil? || context.return_type.undefined?
|
|
153
|
+
type.self_to(context.return_type.namespace)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
# @param type [ComplexType]
|
|
157
|
+
def maybe_nil type
|
|
158
|
+
return type if type.undefined? || type.void? || type.nullable?
|
|
159
|
+
return type unless nullable?
|
|
160
|
+
ComplexType.try_parse("#{type}, nil")
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
end
|
|
@@ -1,79 +1,79 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module Solargraph
|
|
4
|
-
class Source
|
|
5
|
-
# A change to be applied to text.
|
|
6
|
-
#
|
|
7
|
-
class Change
|
|
8
|
-
include EncodingFixes
|
|
9
|
-
|
|
10
|
-
# @return [Range]
|
|
11
|
-
attr_reader :range
|
|
12
|
-
|
|
13
|
-
# @return [String]
|
|
14
|
-
attr_reader :new_text
|
|
15
|
-
|
|
16
|
-
# @param range [Range] The starting and ending positions of the change.
|
|
17
|
-
# If nil, the original text will be overwritten.
|
|
18
|
-
# @param new_text [String] The text to be changed.
|
|
19
|
-
def initialize range, new_text
|
|
20
|
-
@range = range
|
|
21
|
-
@new_text = new_text
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# Write the change to the specified text.
|
|
25
|
-
#
|
|
26
|
-
# @param text [String] The text to be changed.
|
|
27
|
-
# @param nullable [Boolean] If true, minor changes that could generate
|
|
28
|
-
# syntax errors will be repaired.
|
|
29
|
-
# @return [String] The updated text.
|
|
30
|
-
def write text, nullable = false
|
|
31
|
-
if nullable and !range.nil? and new_text.match(/[\.\[\{\(@\$:]$/)
|
|
32
|
-
[':', '@'].each do |dupable|
|
|
33
|
-
next unless new_text == dupable
|
|
34
|
-
offset = Position.to_offset(text, range.start)
|
|
35
|
-
if text[offset - 1] == dupable
|
|
36
|
-
p = Position.from_offset(text, offset - 1)
|
|
37
|
-
r = Change.new(Range.new(p, range.start), ' ')
|
|
38
|
-
text = r.write(text)
|
|
39
|
-
end
|
|
40
|
-
break
|
|
41
|
-
end
|
|
42
|
-
commit text, "#{new_text[0..-2]} "
|
|
43
|
-
elsif range.nil?
|
|
44
|
-
new_text
|
|
45
|
-
else
|
|
46
|
-
commit text, new_text
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
|
|
50
|
-
# Repair an update by replacing the new text with similarly formatted
|
|
51
|
-
# whitespace.
|
|
52
|
-
#
|
|
53
|
-
# @param text [String] The text to be changed.
|
|
54
|
-
# @return [String] The updated text.
|
|
55
|
-
def repair text
|
|
56
|
-
fixed = new_text.gsub(/[^\s]/, ' ')
|
|
57
|
-
if range.nil?
|
|
58
|
-
fixed
|
|
59
|
-
else
|
|
60
|
-
result = commit text, fixed
|
|
61
|
-
off = Position.to_offset(text, range.start)
|
|
62
|
-
match = result[0, off].match(/[\.:]+\z/)
|
|
63
|
-
if match
|
|
64
|
-
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
|
|
65
|
-
end
|
|
66
|
-
result
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
private
|
|
71
|
-
|
|
72
|
-
def commit text, insert
|
|
73
|
-
start_offset = Position.to_offset(text, range.start)
|
|
74
|
-
end_offset = Position.to_offset(text, range.ending)
|
|
75
|
-
(start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|
|
79
|
-
end
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Solargraph
|
|
4
|
+
class Source
|
|
5
|
+
# A change to be applied to text.
|
|
6
|
+
#
|
|
7
|
+
class Change
|
|
8
|
+
include EncodingFixes
|
|
9
|
+
|
|
10
|
+
# @return [Range]
|
|
11
|
+
attr_reader :range
|
|
12
|
+
|
|
13
|
+
# @return [String]
|
|
14
|
+
attr_reader :new_text
|
|
15
|
+
|
|
16
|
+
# @param range [Range] The starting and ending positions of the change.
|
|
17
|
+
# If nil, the original text will be overwritten.
|
|
18
|
+
# @param new_text [String] The text to be changed.
|
|
19
|
+
def initialize range, new_text
|
|
20
|
+
@range = range
|
|
21
|
+
@new_text = new_text
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# Write the change to the specified text.
|
|
25
|
+
#
|
|
26
|
+
# @param text [String] The text to be changed.
|
|
27
|
+
# @param nullable [Boolean] If true, minor changes that could generate
|
|
28
|
+
# syntax errors will be repaired.
|
|
29
|
+
# @return [String] The updated text.
|
|
30
|
+
def write text, nullable = false
|
|
31
|
+
if nullable and !range.nil? and new_text.match(/[\.\[\{\(@\$:]$/)
|
|
32
|
+
[':', '@'].each do |dupable|
|
|
33
|
+
next unless new_text == dupable
|
|
34
|
+
offset = Position.to_offset(text, range.start)
|
|
35
|
+
if text[offset - 1] == dupable
|
|
36
|
+
p = Position.from_offset(text, offset - 1)
|
|
37
|
+
r = Change.new(Range.new(p, range.start), ' ')
|
|
38
|
+
text = r.write(text)
|
|
39
|
+
end
|
|
40
|
+
break
|
|
41
|
+
end
|
|
42
|
+
commit text, "#{new_text[0..-2]} "
|
|
43
|
+
elsif range.nil?
|
|
44
|
+
new_text
|
|
45
|
+
else
|
|
46
|
+
commit text, new_text
|
|
47
|
+
end
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
# Repair an update by replacing the new text with similarly formatted
|
|
51
|
+
# whitespace.
|
|
52
|
+
#
|
|
53
|
+
# @param text [String] The text to be changed.
|
|
54
|
+
# @return [String] The updated text.
|
|
55
|
+
def repair text
|
|
56
|
+
fixed = new_text.gsub(/[^\s]/, ' ')
|
|
57
|
+
if range.nil?
|
|
58
|
+
fixed
|
|
59
|
+
else
|
|
60
|
+
result = commit text, fixed
|
|
61
|
+
off = Position.to_offset(text, range.start)
|
|
62
|
+
match = result[0, off].match(/[\.:]+\z/)
|
|
63
|
+
if match
|
|
64
|
+
result = result[0, off].sub(/#{match[0]}\z/, ' ' * match[0].length) + result[off..-1]
|
|
65
|
+
end
|
|
66
|
+
result
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
private
|
|
71
|
+
|
|
72
|
+
def commit text, insert
|
|
73
|
+
start_offset = Position.to_offset(text, range.start)
|
|
74
|
+
end_offset = Position.to_offset(text, range.ending)
|
|
75
|
+
(start_offset == 0 ? '' : text[0..start_offset-1].to_s) + normalize(insert) + text[end_offset..-1].to_s
|
|
76
|
+
end
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|