solargraph 0.32.1 → 0.32.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/.gitignore +9 -0
- data/.rspec +2 -0
- data/.rubocop.yml +6 -0
- data/.travis.yml +25 -0
- data/EXAMPLES.md +76 -0
- data/Gemfile +3 -0
- data/LANGUAGE_SERVER.md +51 -0
- data/LICENSE +21 -0
- data/OVERVIEW.md +37 -0
- data/README.md +106 -0
- data/Rakefile +14 -0
- data/SERVER.md +95 -0
- data/bin/solargraph +0 -0
- data/bin/solargraph-runtime +5 -5
- data/lib/solargraph.rb +54 -54
- data/lib/solargraph/api_map.rb +659 -659
- data/lib/solargraph/api_map/cache.rb +49 -49
- data/lib/solargraph/api_map/source_to_yard.rb +67 -67
- data/lib/solargraph/api_map/store.rb +201 -201
- data/lib/solargraph/bundle.rb +24 -24
- data/lib/solargraph/complex_type.rb +150 -150
- data/lib/solargraph/complex_type/type_methods.rb +124 -124
- data/lib/solargraph/complex_type/unique_type.rb +44 -44
- data/lib/solargraph/core_fills.rb +37 -37
- data/lib/solargraph/diagnostics.rb +52 -52
- data/lib/solargraph/diagnostics/base.rb +20 -20
- data/lib/solargraph/diagnostics/require_not_found.rb +28 -28
- data/lib/solargraph/diagnostics/rubocop.rb +98 -98
- data/lib/solargraph/diagnostics/rubocop_helpers.rb +46 -46
- data/lib/solargraph/diagnostics/type_not_defined.rb +108 -108
- data/lib/solargraph/diagnostics/update_errors.rb +38 -38
- data/lib/solargraph/language_server/completion_item_kinds.rb +33 -33
- data/lib/solargraph/language_server/error_codes.rb +18 -18
- data/lib/solargraph/language_server/host.rb +684 -681
- data/lib/solargraph/language_server/host/cataloger.rb +54 -79
- data/lib/solargraph/language_server/host/diagnoser.rb +80 -80
- data/lib/solargraph/language_server/host/dispatch.rb +112 -113
- data/lib/solargraph/language_server/host/sources.rb +138 -138
- data/lib/solargraph/language_server/message.rb +90 -90
- data/lib/solargraph/language_server/message/base.rb +83 -83
- data/lib/solargraph/language_server/message/completion_item/resolve.rb +40 -40
- data/lib/solargraph/language_server/message/exit_notification.rb +11 -11
- data/lib/solargraph/language_server/message/extended.rb +19 -19
- data/lib/solargraph/language_server/message/extended/check_gem_version.rb +86 -86
- data/lib/solargraph/language_server/message/extended/document.rb +18 -18
- data/lib/solargraph/language_server/message/extended/document_gems.rb +30 -30
- data/lib/solargraph/language_server/message/extended/environment.rb +20 -20
- data/lib/solargraph/language_server/message/extended/search.rb +18 -18
- data/lib/solargraph/language_server/message/initialize.rb +141 -141
- data/lib/solargraph/language_server/message/initialized.rb +23 -23
- data/lib/solargraph/language_server/message/shutdown.rb +11 -11
- data/lib/solargraph/language_server/message/text_document.rb +25 -25
- data/lib/solargraph/language_server/message/text_document/completion.rb +51 -51
- data/lib/solargraph/language_server/message/text_document/definition.rb +18 -18
- data/lib/solargraph/language_server/message/text_document/did_change.rb +13 -13
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +21 -21
- data/lib/solargraph/language_server/message/text_document/folding_range.rb +24 -24
- data/lib/solargraph/language_server/message/text_document/formatting.rb +50 -50
- data/lib/solargraph/language_server/message/text_document/hover.rb +31 -31
- data/lib/solargraph/language_server/message/text_document/on_type_formatting.rb +32 -32
- data/lib/solargraph/language_server/message/text_document/prepare_rename.rb +9 -9
- data/lib/solargraph/language_server/message/text_document/references.rb +14 -14
- data/lib/solargraph/language_server/message/text_document/rename.rb +17 -17
- data/lib/solargraph/language_server/message/text_document/signature_help.rb +19 -19
- data/lib/solargraph/language_server/message/workspace.rb +12 -12
- data/lib/solargraph/language_server/message/workspace/did_change_configuration.rb +29 -29
- data/lib/solargraph/language_server/message/workspace/did_change_watched_files.rb +29 -27
- data/lib/solargraph/language_server/message/workspace/did_change_workspace_folders.rb +24 -24
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +21 -21
- data/lib/solargraph/language_server/request.rb +22 -22
- data/lib/solargraph/language_server/symbol_kinds.rb +34 -34
- data/lib/solargraph/language_server/transport.rb +11 -11
- data/lib/solargraph/language_server/transport/adapter.rb +60 -60
- data/lib/solargraph/language_server/transport/data_reader.rb +66 -66
- data/lib/solargraph/language_server/uri_helpers.rb +25 -25
- data/lib/solargraph/library.rb +421 -419
- data/lib/solargraph/live_map.rb +126 -126
- data/lib/solargraph/live_map/cache.rb +38 -38
- data/lib/solargraph/location.rb +31 -31
- data/lib/solargraph/logging.rb +25 -25
- data/lib/solargraph/page.rb +68 -68
- data/lib/solargraph/pin.rb +50 -50
- data/lib/solargraph/pin/attribute.rb +41 -41
- data/lib/solargraph/pin/base.rb +280 -280
- data/lib/solargraph/pin/base_method.rb +76 -76
- data/lib/solargraph/pin/base_variable.rb +72 -72
- data/lib/solargraph/pin/block.rb +32 -32
- data/lib/solargraph/pin/block_parameter.rb +103 -103
- data/lib/solargraph/pin/class_variable.rb +9 -9
- data/lib/solargraph/pin/constant.rb +30 -30
- data/lib/solargraph/pin/conversions.rb +79 -79
- data/lib/solargraph/pin/documenting.rb +41 -41
- data/lib/solargraph/pin/duck_method.rb +14 -14
- data/lib/solargraph/pin/global_variable.rb +9 -9
- data/lib/solargraph/pin/instance_variable.rb +9 -9
- data/lib/solargraph/pin/keyword.rb +17 -17
- data/lib/solargraph/pin/local_variable.rb +23 -23
- data/lib/solargraph/pin/localized.rb +22 -22
- data/lib/solargraph/pin/method.rb +126 -126
- data/lib/solargraph/pin/method_alias.rb +30 -30
- data/lib/solargraph/pin/method_parameter.rb +40 -40
- data/lib/solargraph/pin/namespace.rb +54 -54
- data/lib/solargraph/pin/plugin/method.rb +25 -25
- data/lib/solargraph/pin/proxy_type.rb +35 -35
- data/lib/solargraph/pin/reference.rb +22 -22
- data/lib/solargraph/pin/reference/extend.rb +11 -11
- data/lib/solargraph/pin/reference/include.rb +11 -11
- data/lib/solargraph/pin/reference/require.rb +15 -15
- data/lib/solargraph/pin/reference/superclass.rb +11 -11
- data/lib/solargraph/pin/symbol.rb +44 -44
- data/lib/solargraph/pin/yard_pin.rb +10 -10
- data/lib/solargraph/pin/yard_pin/constant.rb +14 -14
- data/lib/solargraph/pin/yard_pin/method.rb +35 -35
- data/lib/solargraph/pin/yard_pin/namespace.rb +19 -19
- data/lib/solargraph/pin/yard_pin/yard_mixin.rb +14 -14
- data/lib/solargraph/plugin.rb +8 -8
- data/lib/solargraph/plugin/base.rb +41 -41
- data/lib/solargraph/plugin/canceler.rb +11 -11
- data/lib/solargraph/plugin/process.rb +172 -172
- data/lib/solargraph/plugin/runtime.rb +134 -134
- data/lib/solargraph/position.rb +110 -110
- data/lib/solargraph/range.rb +83 -83
- data/lib/solargraph/server_methods.rb +14 -14
- data/lib/solargraph/shell.rb +102 -102
- data/lib/solargraph/source.rb +521 -521
- data/lib/solargraph/source/chain.rb +120 -120
- data/lib/solargraph/source/chain/call.rb +107 -107
- data/lib/solargraph/source/chain/class_variable.rb +11 -11
- data/lib/solargraph/source/chain/constant.rb +30 -30
- data/lib/solargraph/source/chain/global_variable.rb +11 -11
- data/lib/solargraph/source/chain/head.rb +33 -33
- data/lib/solargraph/source/chain/instance_variable.rb +11 -11
- data/lib/solargraph/source/chain/link.rb +33 -33
- data/lib/solargraph/source/chain/literal.rb +21 -21
- data/lib/solargraph/source/chain/variable.rb +11 -11
- data/lib/solargraph/source/change.rb +77 -77
- data/lib/solargraph/source/cursor.rb +157 -157
- data/lib/solargraph/source/node_chainer.rb +96 -96
- data/lib/solargraph/source/node_methods.rb +225 -225
- data/lib/solargraph/source/source_chainer.rb +183 -183
- data/lib/solargraph/source_map.rb +169 -169
- data/lib/solargraph/source_map/clip.rb +145 -145
- data/lib/solargraph/source_map/completion.rb +21 -21
- data/lib/solargraph/source_map/mapper.rb +149 -149
- data/lib/solargraph/source_map/node_processor.rb +78 -78
- data/lib/solargraph/source_map/node_processor/alias_node.rb +19 -19
- data/lib/solargraph/source_map/node_processor/args_node.rb +28 -28
- data/lib/solargraph/source_map/node_processor/base.rb +68 -68
- data/lib/solargraph/source_map/node_processor/begin_node.rb +11 -11
- data/lib/solargraph/source_map/node_processor/block_node.rb +14 -14
- data/lib/solargraph/source_map/node_processor/casgn_node.rb +14 -14
- data/lib/solargraph/source_map/node_processor/cvasgn_node.rb +14 -14
- data/lib/solargraph/source_map/node_processor/def_node.rb +54 -54
- data/lib/solargraph/source_map/node_processor/defs_node.rb +21 -21
- data/lib/solargraph/source_map/node_processor/gvasgn_node.rb +12 -12
- data/lib/solargraph/source_map/node_processor/ivasgn_node.rb +18 -18
- data/lib/solargraph/source_map/node_processor/lvasgn_node.rb +16 -16
- data/lib/solargraph/source_map/node_processor/namespace_node.rb +26 -26
- data/lib/solargraph/source_map/node_processor/orasgn_node.rb +12 -12
- data/lib/solargraph/source_map/node_processor/sclass_node.rb +11 -11
- data/lib/solargraph/source_map/node_processor/send_node.rb +162 -162
- data/lib/solargraph/source_map/node_processor/sym_node.rb +11 -11
- data/lib/solargraph/source_map/region.rb +58 -58
- data/lib/solargraph/version.rb +3 -3
- data/lib/solargraph/views/environment.erb +53 -53
- data/lib/solargraph/workspace.rb +183 -183
- data/lib/solargraph/workspace/config.rb +170 -170
- data/lib/solargraph/yard_map.rb +298 -298
- data/lib/solargraph/yard_map/cache.rb +17 -17
- data/lib/solargraph/yard_map/core_docs.rb +163 -163
- data/lib/solargraph/yard_map/core_gen.rb +76 -76
- data/lib/yard-coregen.rb +16 -16
- data/lib/yard-solargraph.rb +18 -18
- data/solargraph.gemspec +37 -0
- data/travis-bundler.rb +10 -0
- metadata +19 -6
|
@@ -1,120 +1,120 @@
|
|
|
1
|
-
# HACK: Fix autoload issue
|
|
2
|
-
require 'solargraph/source/chain/link'
|
|
3
|
-
|
|
4
|
-
module Solargraph
|
|
5
|
-
class Source
|
|
6
|
-
# A chain of constants, variables, and method calls for inferring types of
|
|
7
|
-
# values.
|
|
8
|
-
#
|
|
9
|
-
class Chain
|
|
10
|
-
autoload :Link, 'solargraph/source/chain/link'
|
|
11
|
-
autoload :Call, 'solargraph/source/chain/call'
|
|
12
|
-
autoload :Variable, 'solargraph/source/chain/variable'
|
|
13
|
-
autoload :ClassVariable, 'solargraph/source/chain/class_variable'
|
|
14
|
-
autoload :Constant, 'solargraph/source/chain/constant'
|
|
15
|
-
autoload :InstanceVariable, 'solargraph/source/chain/instance_variable'
|
|
16
|
-
autoload :GlobalVariable, 'solargraph/source/chain/global_variable'
|
|
17
|
-
autoload :Literal, 'solargraph/source/chain/literal'
|
|
18
|
-
autoload :Head, 'solargraph/source/chain/head'
|
|
19
|
-
|
|
20
|
-
# Chain#infer uses the inference stack to avoid recursing into itself.
|
|
21
|
-
# See Chain#active_signature for more information.
|
|
22
|
-
@@inference_stack = []
|
|
23
|
-
|
|
24
|
-
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
|
25
|
-
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
|
26
|
-
|
|
27
|
-
# @return [Array<Source::Chain::Link>]
|
|
28
|
-
attr_reader :links
|
|
29
|
-
|
|
30
|
-
# @param links [Array<Chain::Link>]
|
|
31
|
-
def initialize links
|
|
32
|
-
@links = links
|
|
33
|
-
@links.push UNDEFINED_CALL if @links.empty?
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
# @return [Chain]
|
|
37
|
-
def base
|
|
38
|
-
@base ||= Chain.new(links[0..-2])
|
|
39
|
-
end
|
|
40
|
-
|
|
41
|
-
# @param api_map [ApiMap]
|
|
42
|
-
# @param name_pin [Pin::Base]
|
|
43
|
-
# @param locals [Array<Pin::Base>]
|
|
44
|
-
# @return [Array<Pin::Base>]
|
|
45
|
-
def define api_map, name_pin, locals
|
|
46
|
-
return [] if undefined?
|
|
47
|
-
working_pin = name_pin
|
|
48
|
-
links[0..-2].each do |link|
|
|
49
|
-
pins = link.resolve(api_map, working_pin, locals)
|
|
50
|
-
# Locals are only used when resolving the first link
|
|
51
|
-
locals = []
|
|
52
|
-
type = infer_first_defined(pins, api_map)
|
|
53
|
-
return [] if type.undefined?
|
|
54
|
-
working_pin = Pin::ProxyType.anonymous(type)
|
|
55
|
-
end
|
|
56
|
-
links.last.resolve(api_map, working_pin, locals)
|
|
57
|
-
end
|
|
58
|
-
|
|
59
|
-
# @param api_map [ApiMap]
|
|
60
|
-
# @param name_pin [Pin::Base]
|
|
61
|
-
# @param locals [Array<Pin::Base>]
|
|
62
|
-
# @return [ComplexType]
|
|
63
|
-
def infer api_map, name_pin, locals
|
|
64
|
-
return ComplexType::UNDEFINED if undefined? || @@inference_stack.include?(active_signature(name_pin))
|
|
65
|
-
@@inference_stack.push active_signature(name_pin)
|
|
66
|
-
type = ComplexType::UNDEFINED
|
|
67
|
-
pins = define(api_map, name_pin, locals)
|
|
68
|
-
pins.each do |pin|
|
|
69
|
-
type = pin.typify(api_map)
|
|
70
|
-
break unless type.undefined?
|
|
71
|
-
end
|
|
72
|
-
type = pins.first.probe(api_map) unless type.defined? || pins.empty?
|
|
73
|
-
@@inference_stack.pop
|
|
74
|
-
type
|
|
75
|
-
end
|
|
76
|
-
|
|
77
|
-
# @return [Boolean]
|
|
78
|
-
def literal?
|
|
79
|
-
links.last.is_a?(Chain::Literal)
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
# @return [Boolean]
|
|
83
|
-
def undefined?
|
|
84
|
-
links.any?(&:undefined?)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
# @return [Boolean]
|
|
88
|
-
def constant?
|
|
89
|
-
links.last.is_a?(Chain::Constant)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
private
|
|
93
|
-
|
|
94
|
-
# Get a signature for this chain that includes the current context
|
|
95
|
-
# where it's being analyzed. Chain#infer uses this value to detect
|
|
96
|
-
# recursive inference into the same chain, e.g., when two variables
|
|
97
|
-
# reference each other in their assignments.
|
|
98
|
-
#
|
|
99
|
-
# @param pin [Pin::Base] The named pin context
|
|
100
|
-
# @return [String]
|
|
101
|
-
def active_signature(pin)
|
|
102
|
-
"#{pin.path}|#{links.map(&:word).join('.')}"
|
|
103
|
-
end
|
|
104
|
-
|
|
105
|
-
# @param pins [Array<Pin::Base>]
|
|
106
|
-
# @param api_map [ApiMap]
|
|
107
|
-
# @return [ComplexType]
|
|
108
|
-
def infer_first_defined pins, api_map
|
|
109
|
-
type = ComplexType::UNDEFINED
|
|
110
|
-
pins.each do |pin|
|
|
111
|
-
# type = pin.infer(api_map)
|
|
112
|
-
type = pin.typify(api_map)
|
|
113
|
-
break unless type.undefined?
|
|
114
|
-
end
|
|
115
|
-
type = pins.first.probe(api_map) unless type.defined? || pins.empty?
|
|
116
|
-
type
|
|
117
|
-
end
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
1
|
+
# HACK: Fix autoload issue
|
|
2
|
+
require 'solargraph/source/chain/link'
|
|
3
|
+
|
|
4
|
+
module Solargraph
|
|
5
|
+
class Source
|
|
6
|
+
# A chain of constants, variables, and method calls for inferring types of
|
|
7
|
+
# values.
|
|
8
|
+
#
|
|
9
|
+
class Chain
|
|
10
|
+
autoload :Link, 'solargraph/source/chain/link'
|
|
11
|
+
autoload :Call, 'solargraph/source/chain/call'
|
|
12
|
+
autoload :Variable, 'solargraph/source/chain/variable'
|
|
13
|
+
autoload :ClassVariable, 'solargraph/source/chain/class_variable'
|
|
14
|
+
autoload :Constant, 'solargraph/source/chain/constant'
|
|
15
|
+
autoload :InstanceVariable, 'solargraph/source/chain/instance_variable'
|
|
16
|
+
autoload :GlobalVariable, 'solargraph/source/chain/global_variable'
|
|
17
|
+
autoload :Literal, 'solargraph/source/chain/literal'
|
|
18
|
+
autoload :Head, 'solargraph/source/chain/head'
|
|
19
|
+
|
|
20
|
+
# Chain#infer uses the inference stack to avoid recursing into itself.
|
|
21
|
+
# See Chain#active_signature for more information.
|
|
22
|
+
@@inference_stack = []
|
|
23
|
+
|
|
24
|
+
UNDEFINED_CALL = Chain::Call.new('<undefined>')
|
|
25
|
+
UNDEFINED_CONSTANT = Chain::Constant.new('<undefined>')
|
|
26
|
+
|
|
27
|
+
# @return [Array<Source::Chain::Link>]
|
|
28
|
+
attr_reader :links
|
|
29
|
+
|
|
30
|
+
# @param links [Array<Chain::Link>]
|
|
31
|
+
def initialize links
|
|
32
|
+
@links = links
|
|
33
|
+
@links.push UNDEFINED_CALL if @links.empty?
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
# @return [Chain]
|
|
37
|
+
def base
|
|
38
|
+
@base ||= Chain.new(links[0..-2])
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# @param api_map [ApiMap]
|
|
42
|
+
# @param name_pin [Pin::Base]
|
|
43
|
+
# @param locals [Array<Pin::Base>]
|
|
44
|
+
# @return [Array<Pin::Base>]
|
|
45
|
+
def define api_map, name_pin, locals
|
|
46
|
+
return [] if undefined?
|
|
47
|
+
working_pin = name_pin
|
|
48
|
+
links[0..-2].each do |link|
|
|
49
|
+
pins = link.resolve(api_map, working_pin, locals)
|
|
50
|
+
# Locals are only used when resolving the first link
|
|
51
|
+
locals = []
|
|
52
|
+
type = infer_first_defined(pins, api_map)
|
|
53
|
+
return [] if type.undefined?
|
|
54
|
+
working_pin = Pin::ProxyType.anonymous(type)
|
|
55
|
+
end
|
|
56
|
+
links.last.resolve(api_map, working_pin, locals)
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
# @param api_map [ApiMap]
|
|
60
|
+
# @param name_pin [Pin::Base]
|
|
61
|
+
# @param locals [Array<Pin::Base>]
|
|
62
|
+
# @return [ComplexType]
|
|
63
|
+
def infer api_map, name_pin, locals
|
|
64
|
+
return ComplexType::UNDEFINED if undefined? || @@inference_stack.include?(active_signature(name_pin))
|
|
65
|
+
@@inference_stack.push active_signature(name_pin)
|
|
66
|
+
type = ComplexType::UNDEFINED
|
|
67
|
+
pins = define(api_map, name_pin, locals)
|
|
68
|
+
pins.each do |pin|
|
|
69
|
+
type = pin.typify(api_map)
|
|
70
|
+
break unless type.undefined?
|
|
71
|
+
end
|
|
72
|
+
type = pins.first.probe(api_map) unless type.defined? || pins.empty?
|
|
73
|
+
@@inference_stack.pop
|
|
74
|
+
type
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# @return [Boolean]
|
|
78
|
+
def literal?
|
|
79
|
+
links.last.is_a?(Chain::Literal)
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# @return [Boolean]
|
|
83
|
+
def undefined?
|
|
84
|
+
links.any?(&:undefined?)
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# @return [Boolean]
|
|
88
|
+
def constant?
|
|
89
|
+
links.last.is_a?(Chain::Constant)
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
private
|
|
93
|
+
|
|
94
|
+
# Get a signature for this chain that includes the current context
|
|
95
|
+
# where it's being analyzed. Chain#infer uses this value to detect
|
|
96
|
+
# recursive inference into the same chain, e.g., when two variables
|
|
97
|
+
# reference each other in their assignments.
|
|
98
|
+
#
|
|
99
|
+
# @param pin [Pin::Base] The named pin context
|
|
100
|
+
# @return [String]
|
|
101
|
+
def active_signature(pin)
|
|
102
|
+
"#{pin.path}|#{links.map(&:word).join('.')}"
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
# @param pins [Array<Pin::Base>]
|
|
106
|
+
# @param api_map [ApiMap]
|
|
107
|
+
# @return [ComplexType]
|
|
108
|
+
def infer_first_defined pins, api_map
|
|
109
|
+
type = ComplexType::UNDEFINED
|
|
110
|
+
pins.each do |pin|
|
|
111
|
+
# type = pin.infer(api_map)
|
|
112
|
+
type = pin.typify(api_map)
|
|
113
|
+
break unless type.undefined?
|
|
114
|
+
end
|
|
115
|
+
type = pins.first.probe(api_map) unless type.defined? || pins.empty?
|
|
116
|
+
type
|
|
117
|
+
end
|
|
118
|
+
end
|
|
119
|
+
end
|
|
120
|
+
end
|
|
@@ -1,107 +1,107 @@
|
|
|
1
|
-
module Solargraph
|
|
2
|
-
class Source
|
|
3
|
-
class Chain
|
|
4
|
-
class Call < Link
|
|
5
|
-
# @return [String]
|
|
6
|
-
attr_reader :word
|
|
7
|
-
|
|
8
|
-
# @return [Array<Chain>]
|
|
9
|
-
attr_reader :arguments
|
|
10
|
-
|
|
11
|
-
def initialize word, arguments = []
|
|
12
|
-
@word = word
|
|
13
|
-
@arguments = arguments
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
def resolve api_map, name_pin, locals
|
|
17
|
-
found = locals.select{|p| p.name == word}
|
|
18
|
-
return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
|
|
19
|
-
pins = api_map.get_method_stack(name_pin.context.namespace, word, scope: name_pin.context.scope)
|
|
20
|
-
return [] if pins.empty?
|
|
21
|
-
pins.unshift virtual_new_pin(pins.first, name_pin.context) if external_constructor?(pins.first, name_pin.context)
|
|
22
|
-
inferred_pins(pins, api_map, name_pin.context, locals)
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
private
|
|
26
|
-
|
|
27
|
-
# Create a `new` pin to facilitate type inference. This is necessary for
|
|
28
|
-
# classes from YARD and classes in the namespace that do not have an
|
|
29
|
-
# `initialize` method.
|
|
30
|
-
#
|
|
31
|
-
# @param new_pin [Solargraph::Pin::Base]
|
|
32
|
-
# @param context [Solargraph::ComplexType]
|
|
33
|
-
# @return [Pin::Method]
|
|
34
|
-
def virtual_new_pin new_pin, context
|
|
35
|
-
Pin::ProxyType.anonymous(ComplexType.try_parse(context.namespace))
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
def inferred_pins pins, api_map, context, locals
|
|
39
|
-
result = pins.map do |p|
|
|
40
|
-
if CoreFills::METHODS_RETURNING_SELF.include?(p.path)
|
|
41
|
-
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
|
42
|
-
end
|
|
43
|
-
if CoreFills::METHODS_RETURNING_SUBTYPES.include?(p.path) && !context.subtypes.empty?
|
|
44
|
-
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.subtypes.first.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
|
45
|
-
end
|
|
46
|
-
if p.kind == Pin::METHOD && !p.macros.empty?
|
|
47
|
-
result = process_macro(p, api_map, context, locals)
|
|
48
|
-
next result unless result.return_type.undefined?
|
|
49
|
-
elsif !p.directives.empty?
|
|
50
|
-
result = process_directive(p, api_map, context, locals)
|
|
51
|
-
next result unless result.return_type.undefined?
|
|
52
|
-
end
|
|
53
|
-
next p if p.kind == Pin::METHOD || p.kind == Pin::ATTRIBUTE || p.kind == Pin::NAMESPACE
|
|
54
|
-
# type = p.infer(api_map)
|
|
55
|
-
type = p.typify(api_map)
|
|
56
|
-
type = p.probe(api_map) if type.undefined?
|
|
57
|
-
next p if p.return_complex_type == type
|
|
58
|
-
p.proxy type
|
|
59
|
-
end
|
|
60
|
-
result
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def external_constructor? pin, context
|
|
64
|
-
pin.path == 'Class#new' || (pin.name == 'new' && pin.scope == :class && pin.return_type != context)
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
# @param pin [Pin::Method]
|
|
68
|
-
# @param api_map [ApiMap]
|
|
69
|
-
# @param context [ComplexType]
|
|
70
|
-
# @return [Pin::Base]
|
|
71
|
-
def process_macro pin, api_map, context, locals
|
|
72
|
-
pin.macros.each do |macro|
|
|
73
|
-
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
74
|
-
return result unless result.return_type.undefined?
|
|
75
|
-
end
|
|
76
|
-
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
def process_directive pin, api_map, context, locals
|
|
80
|
-
pin.directives.each do |dir|
|
|
81
|
-
macro = api_map.named_macro(dir.tag.name)
|
|
82
|
-
next if macro.nil?
|
|
83
|
-
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
84
|
-
return result unless result.return_type.undefined?
|
|
85
|
-
end
|
|
86
|
-
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
87
|
-
end
|
|
88
|
-
|
|
89
|
-
def inner_process_macro pin, macro, api_map, context, locals
|
|
90
|
-
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
|
91
|
-
txt = macro.tag.text.clone
|
|
92
|
-
i = 1
|
|
93
|
-
vals.each do |v|
|
|
94
|
-
txt.gsub!(/\$#{i}/, v.context.namespace)
|
|
95
|
-
i += 1
|
|
96
|
-
end
|
|
97
|
-
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
|
98
|
-
tag = docstring.tag(:return)
|
|
99
|
-
unless tag.nil? || tag.types.nil?
|
|
100
|
-
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
|
|
101
|
-
end
|
|
102
|
-
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
103
|
-
end
|
|
104
|
-
end
|
|
105
|
-
end
|
|
106
|
-
end
|
|
107
|
-
end
|
|
1
|
+
module Solargraph
|
|
2
|
+
class Source
|
|
3
|
+
class Chain
|
|
4
|
+
class Call < Link
|
|
5
|
+
# @return [String]
|
|
6
|
+
attr_reader :word
|
|
7
|
+
|
|
8
|
+
# @return [Array<Chain>]
|
|
9
|
+
attr_reader :arguments
|
|
10
|
+
|
|
11
|
+
def initialize word, arguments = []
|
|
12
|
+
@word = word
|
|
13
|
+
@arguments = arguments
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def resolve api_map, name_pin, locals
|
|
17
|
+
found = locals.select{|p| p.name == word}
|
|
18
|
+
return inferred_pins(found, api_map, name_pin.context, locals) unless found.empty?
|
|
19
|
+
pins = api_map.get_method_stack(name_pin.context.namespace, word, scope: name_pin.context.scope)
|
|
20
|
+
return [] if pins.empty?
|
|
21
|
+
pins.unshift virtual_new_pin(pins.first, name_pin.context) if external_constructor?(pins.first, name_pin.context)
|
|
22
|
+
inferred_pins(pins, api_map, name_pin.context, locals)
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
private
|
|
26
|
+
|
|
27
|
+
# Create a `new` pin to facilitate type inference. This is necessary for
|
|
28
|
+
# classes from YARD and classes in the namespace that do not have an
|
|
29
|
+
# `initialize` method.
|
|
30
|
+
#
|
|
31
|
+
# @param new_pin [Solargraph::Pin::Base]
|
|
32
|
+
# @param context [Solargraph::ComplexType]
|
|
33
|
+
# @return [Pin::Method]
|
|
34
|
+
def virtual_new_pin new_pin, context
|
|
35
|
+
Pin::ProxyType.anonymous(ComplexType.try_parse(context.namespace))
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def inferred_pins pins, api_map, context, locals
|
|
39
|
+
result = pins.map do |p|
|
|
40
|
+
if CoreFills::METHODS_RETURNING_SELF.include?(p.path)
|
|
41
|
+
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
|
42
|
+
end
|
|
43
|
+
if CoreFills::METHODS_RETURNING_SUBTYPES.include?(p.path) && !context.subtypes.empty?
|
|
44
|
+
next Solargraph::Pin::Method.new(p.location, p.namespace, p.name, "@return [#{context.subtypes.first.tag}]", p.scope, p.visibility, p.parameters, p.node)
|
|
45
|
+
end
|
|
46
|
+
if p.kind == Pin::METHOD && !p.macros.empty?
|
|
47
|
+
result = process_macro(p, api_map, context, locals)
|
|
48
|
+
next result unless result.return_type.undefined?
|
|
49
|
+
elsif !p.directives.empty?
|
|
50
|
+
result = process_directive(p, api_map, context, locals)
|
|
51
|
+
next result unless result.return_type.undefined?
|
|
52
|
+
end
|
|
53
|
+
next p if p.kind == Pin::METHOD || p.kind == Pin::ATTRIBUTE || p.kind == Pin::NAMESPACE
|
|
54
|
+
# type = p.infer(api_map)
|
|
55
|
+
type = p.typify(api_map)
|
|
56
|
+
type = p.probe(api_map) if type.undefined?
|
|
57
|
+
next p if p.return_complex_type == type
|
|
58
|
+
p.proxy type
|
|
59
|
+
end
|
|
60
|
+
result
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def external_constructor? pin, context
|
|
64
|
+
pin.path == 'Class#new' || (pin.name == 'new' && pin.scope == :class && pin.return_type != context)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# @param pin [Pin::Method]
|
|
68
|
+
# @param api_map [ApiMap]
|
|
69
|
+
# @param context [ComplexType]
|
|
70
|
+
# @return [Pin::Base]
|
|
71
|
+
def process_macro pin, api_map, context, locals
|
|
72
|
+
pin.macros.each do |macro|
|
|
73
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
74
|
+
return result unless result.return_type.undefined?
|
|
75
|
+
end
|
|
76
|
+
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
def process_directive pin, api_map, context, locals
|
|
80
|
+
pin.directives.each do |dir|
|
|
81
|
+
macro = api_map.named_macro(dir.tag.name)
|
|
82
|
+
next if macro.nil?
|
|
83
|
+
result = inner_process_macro(pin, macro, api_map, context, locals)
|
|
84
|
+
return result unless result.return_type.undefined?
|
|
85
|
+
end
|
|
86
|
+
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
def inner_process_macro pin, macro, api_map, context, locals
|
|
90
|
+
vals = arguments.map{ |c| Pin::ProxyType.anonymous(c.infer(api_map, pin, locals)) }
|
|
91
|
+
txt = macro.tag.text.clone
|
|
92
|
+
i = 1
|
|
93
|
+
vals.each do |v|
|
|
94
|
+
txt.gsub!(/\$#{i}/, v.context.namespace)
|
|
95
|
+
i += 1
|
|
96
|
+
end
|
|
97
|
+
docstring = Solargraph::Source.parse_docstring(txt).to_docstring
|
|
98
|
+
tag = docstring.tag(:return)
|
|
99
|
+
unless tag.nil? || tag.types.nil?
|
|
100
|
+
return Pin::ProxyType.anonymous(ComplexType.try_parse(*tag.types))
|
|
101
|
+
end
|
|
102
|
+
Pin::ProxyType.new(nil, nil, nil, ComplexType::UNDEFINED)
|
|
103
|
+
end
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|