solargraph 0.25.1 → 0.26.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/lib/solargraph.rb +18 -16
- data/lib/solargraph/api_map.rb +100 -161
- data/lib/solargraph/api_map/source_to_yard.rb +9 -9
- data/lib/solargraph/api_map/store.rb +50 -13
- data/lib/solargraph/basic_type.rb +33 -0
- data/lib/solargraph/basic_type_methods.rb +111 -0
- data/lib/solargraph/complex_type.rb +51 -89
- data/lib/solargraph/core_fills.rb +12 -8
- data/lib/solargraph/diagnostics/type_not_defined.rb +2 -2
- data/lib/solargraph/language_server.rb +3 -0
- data/lib/solargraph/language_server/completion_item_kinds.rb +2 -0
- data/lib/solargraph/language_server/error_codes.rb +2 -0
- data/lib/solargraph/language_server/host.rb +53 -6
- data/lib/solargraph/language_server/message.rb +13 -0
- data/lib/solargraph/language_server/message/text_document/definition.rb +4 -6
- data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -1
- data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -1
- data/lib/solargraph/language_server/message_types.rb +2 -0
- data/lib/solargraph/language_server/request.rb +4 -0
- data/lib/solargraph/language_server/symbol_kinds.rb +28 -26
- data/lib/solargraph/language_server/transport.rb +3 -0
- data/lib/solargraph/language_server/uri_helpers.rb +2 -0
- data/lib/solargraph/library.rb +12 -7
- data/lib/solargraph/pin.rb +1 -1
- data/lib/solargraph/pin/attribute.rb +5 -5
- data/lib/solargraph/pin/base.rb +51 -16
- data/lib/solargraph/pin/base_variable.rb +25 -7
- data/lib/solargraph/pin/block.rb +18 -1
- data/lib/solargraph/pin/block_parameter.rb +42 -5
- data/lib/solargraph/pin/conversions.rb +4 -2
- data/lib/solargraph/pin/method.rb +6 -6
- data/lib/solargraph/pin/method_parameter.rb +6 -6
- data/lib/solargraph/pin/namespace.rb +7 -2
- data/lib/solargraph/pin/proxy_type.rb +39 -0
- data/lib/solargraph/pin/symbol.rb +20 -12
- data/lib/solargraph/pin/yard_pin/method.rb +2 -2
- data/lib/solargraph/source.rb +89 -38
- data/lib/solargraph/source/call_chainer.rb +273 -0
- data/lib/solargraph/source/chain.rb +104 -0
- data/lib/solargraph/source/chain/call.rb +72 -0
- data/lib/solargraph/source/chain/class_variable.rb +11 -0
- data/lib/solargraph/source/chain/constant.rb +17 -0
- data/lib/solargraph/source/chain/definition.rb +16 -0
- data/lib/solargraph/source/chain/global_variable.rb +11 -0
- data/lib/solargraph/source/chain/head.rb +20 -0
- data/lib/solargraph/source/chain/instance_variable.rb +11 -0
- data/lib/solargraph/source/chain/link.rb +33 -0
- data/lib/solargraph/source/chain/literal.rb +21 -0
- data/lib/solargraph/source/chain/variable.rb +11 -0
- data/lib/solargraph/source/change.rb +3 -1
- data/lib/solargraph/{api_map → source}/completion.rb +3 -1
- data/lib/solargraph/source/encoding_fixes.rb +21 -0
- data/lib/solargraph/source/fragment.rb +139 -284
- data/lib/solargraph/source/mapper.rb +27 -16
- data/lib/solargraph/source/node_chainer.rb +94 -0
- data/lib/solargraph/source/node_methods.rb +2 -2
- data/lib/solargraph/source/position.rb +4 -0
- data/lib/solargraph/source/range.rb +10 -2
- data/lib/solargraph/version.rb +1 -1
- data/lib/solargraph/yard_map.rb +13 -2
- metadata +20 -6
- data/lib/solargraph/api_map/probe.rb +0 -251
- data/lib/solargraph/api_map/type_methods.rb +0 -40
- data/lib/solargraph/pin/proxy_method.rb +0 -30
@@ -14,29 +14,29 @@ module Solargraph
|
|
14
14
|
end
|
15
15
|
|
16
16
|
# @param sources [Array<Solargraph::Source>] Sources for code objects
|
17
|
-
def rake_yard
|
17
|
+
def rake_yard store
|
18
18
|
code_object_map.clear
|
19
|
-
sources.each do |s|
|
20
|
-
|
21
|
-
next if pin.path.empty?
|
19
|
+
#sources.each do |s|
|
20
|
+
store.namespace_pins.each do |pin|
|
21
|
+
next if pin.path.nil? or pin.path.empty?
|
22
22
|
if pin.type == :class
|
23
23
|
code_object_map[pin.path] ||= YARD::CodeObjects::ClassObject.new(root_code_object, pin.path)
|
24
24
|
else
|
25
25
|
code_object_map[pin.path] ||= YARD::CodeObjects::ModuleObject.new(root_code_object, pin.path)
|
26
26
|
end
|
27
27
|
code_object_map[pin.path].docstring = pin.docstring
|
28
|
-
code_object_map[pin.path].files.push pin.location.filename
|
28
|
+
code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
|
29
29
|
end
|
30
|
-
|
30
|
+
store.namespace_pins.each do |pin|
|
31
31
|
pin.include_references.each do |ref|
|
32
32
|
code_object_map[pin.path].instance_mixins.push code_object_map[ref.name] unless code_object_map[ref.name].nil? or code_object_map[pin.path].nil?
|
33
33
|
end
|
34
34
|
end
|
35
|
-
|
35
|
+
store.method_pins.each do |pin|
|
36
36
|
code_object_map[pin.path] ||= YARD::CodeObjects::MethodObject.new(code_object_at(pin.namespace), pin.name, pin.scope)
|
37
37
|
code_object_map[pin.path].docstring = pin.docstring
|
38
38
|
code_object_map[pin.path].visibility = pin.visibility || :public
|
39
|
-
code_object_map[pin.path].files.push pin.location.filename
|
39
|
+
code_object_map[pin.path].files.push pin.location.filename unless pin.location.nil?
|
40
40
|
code_object_map[pin.path].parameters = pin.parameters.map do |p|
|
41
41
|
n = p.match(/^[a-z0-9_]*:?/i)[0]
|
42
42
|
v = nil
|
@@ -46,7 +46,7 @@ module Solargraph
|
|
46
46
|
[n, v]
|
47
47
|
end
|
48
48
|
end
|
49
|
-
end
|
49
|
+
#end
|
50
50
|
end
|
51
51
|
|
52
52
|
private
|
@@ -4,8 +4,9 @@ module Solargraph
|
|
4
4
|
class ApiMap
|
5
5
|
class Store
|
6
6
|
# @param sources [Array<Solargraph::Source>]
|
7
|
+
# @param yard_pins [Array<Solargraph::Pin::Base>]
|
7
8
|
def initialize sources, yard_pins
|
8
|
-
inner_update
|
9
|
+
inner_update sources
|
9
10
|
pins.concat yard_pins
|
10
11
|
index
|
11
12
|
end
|
@@ -15,6 +16,8 @@ module Solargraph
|
|
15
16
|
@pins ||= []
|
16
17
|
end
|
17
18
|
|
19
|
+
# @param *sources [Array<Solargraph::Source>]
|
20
|
+
# @return [void]
|
18
21
|
def remove *sources
|
19
22
|
sources.each do |source|
|
20
23
|
pins.delete_if { |pin| !pin.yard_pin? and pin.filename == source.filename }
|
@@ -23,33 +26,45 @@ module Solargraph
|
|
23
26
|
index
|
24
27
|
end
|
25
28
|
|
29
|
+
# @param *sources [Array<Solargraph::Source>]
|
30
|
+
# @return [void]
|
26
31
|
def update *sources
|
27
|
-
inner_update
|
32
|
+
inner_update sources
|
28
33
|
index
|
29
34
|
end
|
30
35
|
|
36
|
+
# @param yard_pins [Array<Solargraph::Pin::Base>]
|
37
|
+
# @return [void]
|
31
38
|
def update_yard yard_pins
|
32
39
|
pins.delete_if(&:yard_pin?)
|
33
40
|
pins.concat yard_pins
|
34
41
|
index
|
35
42
|
end
|
36
43
|
|
44
|
+
# @param fqns [String]
|
45
|
+
# @param visibility [Array<Symbol>]
|
37
46
|
# @return [Array<Solargraph::Pin::Base>]
|
38
47
|
def get_constants fqns, visibility = [:public]
|
39
|
-
|
48
|
+
namespace_children(fqns).select { |pin|
|
40
49
|
!pin.name.empty? and (pin.kind == Pin::NAMESPACE or pin.kind == Pin::CONSTANT) and visibility.include?(pin.visibility)
|
41
50
|
}
|
42
51
|
end
|
43
52
|
|
53
|
+
# @param fqns [String]
|
54
|
+
# @param scope [Symbol]
|
55
|
+
# @param visibility [Array<Symbol>]
|
56
|
+
# @return [Array<Solargraph::Pin::Base>]
|
44
57
|
def get_methods fqns, scope: :instance, visibility: [:public]
|
45
|
-
|
58
|
+
namespace_children(fqns).select{ |pin|
|
46
59
|
pin.kind == Pin::METHOD and (pin.scope == scope or fqns == '') and visibility.include?(pin.visibility)
|
47
60
|
}
|
48
61
|
end
|
49
62
|
|
63
|
+
# @param fqns [String]
|
64
|
+
# @param scope [Symbol]
|
50
65
|
# @return [Array<Solargraph::Pin::Base>]
|
51
66
|
def get_attrs fqns, scope
|
52
|
-
|
67
|
+
namespace_children(fqns).select{ |pin| pin.kind == Pin::ATTRIBUTE and pin.scope == scope }
|
53
68
|
end
|
54
69
|
|
55
70
|
# @param fqns [String]
|
@@ -84,22 +99,24 @@ module Solargraph
|
|
84
99
|
# @param path [String]
|
85
100
|
# @return [Array<Solargraph::Pin::Base>]
|
86
101
|
def get_path_pins path
|
102
|
+
# return [] if path.nil? # @todo Should be '' instead?
|
103
|
+
path ||= ''
|
87
104
|
base = path.sub(/(#|\.|::)[a-z0-9_]*(\?|\!)?$/i, '')
|
88
105
|
base = '' if base == path
|
89
|
-
|
106
|
+
namespace_children(base).select{ |pin| pin.path == path }
|
90
107
|
end
|
91
108
|
|
92
109
|
# @param fqns [String]
|
93
110
|
# @param scope [Symbol] :class or :instance
|
94
111
|
# @return [Array<Solargraph::Pin::Base>]
|
95
112
|
def get_instance_variables(fqns, scope = :instance)
|
96
|
-
|
113
|
+
namespace_children(fqns).select{|pin| pin.kind == Pin::INSTANCE_VARIABLE and pin.scope == scope}
|
97
114
|
end
|
98
115
|
|
99
116
|
# @param fqns [String]
|
100
117
|
# @return [Array<Solargraph::Pin::Base>]
|
101
118
|
def get_class_variables(fqns)
|
102
|
-
|
119
|
+
namespace_children(fqns).select{|pin| pin.kind == Pin::CLASS_VARIABLE}
|
103
120
|
end
|
104
121
|
|
105
122
|
# @return [Array<Solargraph::Pin::Base>]
|
@@ -118,11 +135,22 @@ module Solargraph
|
|
118
135
|
@namespaces ||= Set.new
|
119
136
|
end
|
120
137
|
|
138
|
+
# @return [Array<Solargraph::Pin::Base>]
|
139
|
+
def namespace_pins
|
140
|
+
@namespace_pins ||= pins.select{|p| p.kind == Pin::NAMESPACE}
|
141
|
+
end
|
142
|
+
|
143
|
+
# @return [Array<Solargraph::Pin::Base>]
|
144
|
+
def method_pins
|
145
|
+
@method_pins ||= pins.select{|p| p.kind == Pin::METHOD or p.kind == Pin::ATTRIBUTE}
|
146
|
+
end
|
147
|
+
|
121
148
|
private
|
122
149
|
|
150
|
+
# @param fqns [String]
|
151
|
+
# @return [Array<Solargraph::Pin::Namespace>]
|
123
152
|
def fqns_pins fqns
|
124
|
-
|
125
|
-
return [] if fqns.nil? #or fqns.empty?
|
153
|
+
return [] if fqns.nil?
|
126
154
|
if fqns.include?('::')
|
127
155
|
parts = fqns.split('::')
|
128
156
|
name = parts.pop
|
@@ -131,21 +159,26 @@ module Solargraph
|
|
131
159
|
base = ''
|
132
160
|
name = fqns
|
133
161
|
end
|
134
|
-
|
162
|
+
namespace_children(base).select{|pin| pin.name == name and pin.kind == Pin::NAMESPACE}
|
135
163
|
end
|
136
164
|
|
165
|
+
# @return [Array<Solargraph::Pin::Symbol>]
|
137
166
|
def symbols
|
138
167
|
@symbols ||= []
|
139
168
|
end
|
140
169
|
|
141
|
-
|
170
|
+
# @param name [String]
|
171
|
+
# @return [Array<Solargraph::Pin::Namespace>]
|
172
|
+
def namespace_children name
|
142
173
|
namespace_map[name] || []
|
143
174
|
end
|
144
175
|
|
176
|
+
# @return [Hash]
|
145
177
|
def namespace_map
|
146
178
|
@namespace_map ||= {}
|
147
179
|
end
|
148
180
|
|
181
|
+
# @return [void]
|
149
182
|
def index
|
150
183
|
namespace_map.clear
|
151
184
|
namespaces.clear
|
@@ -155,9 +188,13 @@ module Solargraph
|
|
155
188
|
namespace_map[pin.namespace].push pin
|
156
189
|
namespaces.add pin.path if pin.kind == Pin::NAMESPACE and !pin.path.empty?
|
157
190
|
end
|
191
|
+
@namespace_pins = nil
|
192
|
+
@method_pins = nil
|
158
193
|
end
|
159
194
|
|
160
|
-
|
195
|
+
# @param sources [Array<Solargraph::Source>]
|
196
|
+
# @return [void]
|
197
|
+
def inner_update sources
|
161
198
|
sources.each do |source|
|
162
199
|
pins.delete_if { |pin| !pin.yard_pin? and pin.filename == source.filename }
|
163
200
|
symbols.delete_if { |pin| pin.filename == source.filename }
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Solargraph
|
2
|
+
class BasicType
|
3
|
+
include BasicTypeMethods
|
4
|
+
|
5
|
+
# Create a BasicType with the specified name and an optional substring.
|
6
|
+
# The substring is the parameter section of a parametrized type, e.g., for
|
7
|
+
# the type `Array<String>`, the name is `Array` and the substring is
|
8
|
+
# `<String>`.
|
9
|
+
#
|
10
|
+
# @param name [String] The name of the type
|
11
|
+
# @param substring [String] The substring of the type
|
12
|
+
def initialize name, substring = ''
|
13
|
+
@name = name
|
14
|
+
@substring = substring
|
15
|
+
@tag = name + substring
|
16
|
+
@key_types = []
|
17
|
+
@subtypes = []
|
18
|
+
return unless parameters?
|
19
|
+
subs = ComplexType.parse(substring[1..-2], partial: true)
|
20
|
+
if hash_parameters?
|
21
|
+
raise ComplexTypeError, "Bad hash type" unless !subs.is_a?(ComplexType) and subs.length == 2 and !subs[0].is_a?(ComplexType) and !subs[1].is_a?(ComplexType)
|
22
|
+
@key_types.concat subs[0]
|
23
|
+
@subtypes.concat subs[1]
|
24
|
+
else
|
25
|
+
@subtypes.concat subs
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def to_s
|
30
|
+
tag
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
module Solargraph
|
2
|
+
module BasicTypeMethods
|
3
|
+
# @return [String]
|
4
|
+
attr_reader :name
|
5
|
+
|
6
|
+
# @return [String]
|
7
|
+
attr_reader :substring
|
8
|
+
|
9
|
+
# @return [String]
|
10
|
+
attr_reader :tag
|
11
|
+
|
12
|
+
# @return [Array<ComplexType>]
|
13
|
+
attr_reader :subtypes
|
14
|
+
|
15
|
+
# @return [Boolean]
|
16
|
+
def duck_type?
|
17
|
+
@duck_type ||= name.start_with?('#')
|
18
|
+
end
|
19
|
+
|
20
|
+
# @return [Boolean]
|
21
|
+
def nil_type?
|
22
|
+
@nil_type ||= (name.downcase == 'nil')
|
23
|
+
end
|
24
|
+
|
25
|
+
# @return [Boolean]
|
26
|
+
def parameters?
|
27
|
+
!substring.empty?
|
28
|
+
end
|
29
|
+
|
30
|
+
def void?
|
31
|
+
name == 'void'
|
32
|
+
end
|
33
|
+
|
34
|
+
def defined?
|
35
|
+
!undefined?
|
36
|
+
end
|
37
|
+
|
38
|
+
def undefined?
|
39
|
+
name == 'undefined'
|
40
|
+
end
|
41
|
+
|
42
|
+
# @return [Boolean]
|
43
|
+
def list_parameters?
|
44
|
+
substring.start_with?('<')
|
45
|
+
end
|
46
|
+
|
47
|
+
# @return [Boolean]
|
48
|
+
def fixed_parameters?
|
49
|
+
substring.start_with?('(')
|
50
|
+
end
|
51
|
+
|
52
|
+
# @return [Boolean]
|
53
|
+
def hash_parameters?
|
54
|
+
substring.start_with?('{')
|
55
|
+
end
|
56
|
+
|
57
|
+
# @return [Array<ComplexType>]
|
58
|
+
def value_types
|
59
|
+
@subtypes
|
60
|
+
end
|
61
|
+
|
62
|
+
# @return [Array<ComplexType>]
|
63
|
+
def key_types
|
64
|
+
@key_types
|
65
|
+
end
|
66
|
+
|
67
|
+
# @return [String]
|
68
|
+
def namespace
|
69
|
+
@namespace ||= 'Object' if duck_type?
|
70
|
+
@namespace ||= 'NilClass' if nil_type?
|
71
|
+
@namespace ||= ((name == 'Class' or name == 'Module') and !subtypes.empty?) ? subtypes.first.name : name
|
72
|
+
end
|
73
|
+
|
74
|
+
# @return [Symbol] :class or :instance
|
75
|
+
def scope
|
76
|
+
@scope ||= :instance if duck_type? or nil_type?
|
77
|
+
@scope ||= ((name == 'Class' or name == 'Module') and !subtypes.empty?) ? :class : :instance
|
78
|
+
end
|
79
|
+
|
80
|
+
def == other
|
81
|
+
return false unless self.class == other.class
|
82
|
+
tag == other.tag
|
83
|
+
end
|
84
|
+
|
85
|
+
# Generate a ComplexType that fully qualifies this type's namespaces.
|
86
|
+
#
|
87
|
+
# @param api_map [ApiMap] The ApiMap that performs qualification
|
88
|
+
# @param context [String] The namespace from which to resolve names
|
89
|
+
# @return [ComplexType] The generated ComplexType
|
90
|
+
def qualify api_map, context = ''
|
91
|
+
return ComplexType.parse(tag) if duck_type? or void? or undefined?
|
92
|
+
fqns = api_map.qualify(name, context)
|
93
|
+
return ComplexType::UNDEFINED if fqns.nil?
|
94
|
+
ltypes = key_types.map do |t|
|
95
|
+
t.qualify api_map, context
|
96
|
+
end
|
97
|
+
rtypes = value_types.map do |t|
|
98
|
+
t.qualify api_map, context
|
99
|
+
end
|
100
|
+
if list_parameters?
|
101
|
+
Solargraph::ComplexType.parse("#{fqns}<#{rtypes.map(&:tag).join(', ')}>").first
|
102
|
+
elsif fixed_parameters?
|
103
|
+
Solargraph::ComplexType.parse("#{fqns}(#{rtypes.map(&:tag).join(', ')})").first
|
104
|
+
elsif hash_parameters?
|
105
|
+
Solargraph::ComplexType.parse("#{fqns}{#{ltypes.map(&:tag).join(', ')} => #{rtypes.map(&:tag).join(', ')}}").first
|
106
|
+
else
|
107
|
+
Solargraph::ComplexType.parse(fqns).first
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
@@ -1,103 +1,58 @@
|
|
1
1
|
module Solargraph
|
2
|
-
class ComplexType
|
3
|
-
# @
|
4
|
-
|
5
|
-
|
6
|
-
# @return [String]
|
7
|
-
attr_reader :substring
|
8
|
-
|
9
|
-
# @return [String]
|
10
|
-
attr_reader :tag
|
11
|
-
|
12
|
-
# @return [Array<ComplexType>]
|
13
|
-
attr_reader :subtypes
|
14
|
-
|
15
|
-
# Create a ComplexType with the specified name and an optional substring.
|
16
|
-
# The substring is parameter of a parameterized type, e.g., for the type
|
17
|
-
# `Array<String>`, the name is `Array` and the substring is `String`.
|
2
|
+
class ComplexType < Array
|
3
|
+
# @todo Figure out how to add the basic type methods here without actually
|
4
|
+
# including the module. One possibility:
|
18
5
|
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
def initialize name, substring = ''
|
22
|
-
@name = name
|
23
|
-
@substring = substring
|
24
|
-
@tag = name + substring
|
25
|
-
@key_types = []
|
26
|
-
@subtypes = []
|
27
|
-
if parameters?
|
28
|
-
subs = ComplexType.parse(substring[1..-2])
|
29
|
-
if hash_parameters?
|
30
|
-
raise ComplexTypeError, "Bad hash type" unless subs.length == 2 and subs[0].is_a?(Array) and subs[1].is_a?(Array)
|
31
|
-
@key_types.concat subs[0]
|
32
|
-
@subtypes.concat subs[1]
|
33
|
-
else
|
34
|
-
@subtypes.concat subs
|
35
|
-
end
|
36
|
-
end
|
37
|
-
end
|
38
|
-
|
39
|
-
# @return [Boolean]
|
40
|
-
def duck_type?
|
41
|
-
@duck_type ||= name.start_with?('#')
|
42
|
-
end
|
43
|
-
|
44
|
-
# @return [Boolean]
|
45
|
-
def nil_type?
|
46
|
-
@nil_type ||= (name.downcase == 'nil')
|
47
|
-
end
|
6
|
+
# @!parse
|
7
|
+
# include BasicTypeMethods
|
48
8
|
|
49
|
-
|
50
|
-
|
51
|
-
|
9
|
+
def initialize types = [ComplexType::UNDEFINED]
|
10
|
+
super()
|
11
|
+
concat types
|
52
12
|
end
|
53
13
|
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
# @return [Boolean]
|
60
|
-
def fixed_parameters?
|
61
|
-
substring.start_with?('(')
|
62
|
-
end
|
63
|
-
|
64
|
-
# @return [Boolean]
|
65
|
-
def hash_parameters?
|
66
|
-
substring.start_with?('{')
|
67
|
-
end
|
68
|
-
|
69
|
-
# @return [Array<ComplexType>]
|
70
|
-
def value_types
|
71
|
-
@subtypes
|
72
|
-
end
|
73
|
-
|
74
|
-
# @return [Array<ComplexType>]
|
75
|
-
def key_types
|
76
|
-
@key_types
|
14
|
+
def qualify api_map, context = ''
|
15
|
+
types = map do |t|
|
16
|
+
t.qualify api_map, context
|
17
|
+
end
|
18
|
+
ComplexType.new(types)
|
77
19
|
end
|
78
20
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
@namespace ||= 'NilClass' if nil_type?
|
83
|
-
@namespace ||= ((name == 'Class' or name == 'Module') and !subtypes.empty?) ? subtypes.first.name : name
|
21
|
+
def method_missing name, *args, &block
|
22
|
+
return first.send(name, *args, &block) if respond_to_missing?(name)
|
23
|
+
super
|
84
24
|
end
|
85
25
|
|
86
|
-
|
87
|
-
|
88
|
-
@scope ||= :instance if duck_type? or nil_type?
|
89
|
-
@scope ||= ((name == 'Class' or name == 'Module') and !subtypes.empty?) ? :class : :instance
|
26
|
+
def respond_to_missing?(name, include_private = false)
|
27
|
+
BasicTypeMethods.public_instance_methods.include?(name) || super
|
90
28
|
end
|
91
29
|
|
92
|
-
def
|
93
|
-
|
94
|
-
tag == other.tag
|
30
|
+
def to_s
|
31
|
+
map(&:tag).join(', ')
|
95
32
|
end
|
96
33
|
|
97
34
|
class << self
|
35
|
+
# Parse type strings into a ComplexType.
|
36
|
+
#
|
37
|
+
# @example
|
38
|
+
# ComplexType.parse 'String', 'Foo', 'nil' #=> [String, Foo, nil]
|
39
|
+
#
|
40
|
+
# @note
|
41
|
+
# The `partial` parameter is used to indicate that the method is
|
42
|
+
# receiving a string that will be used inside another ComplexType.
|
43
|
+
# It returns arrays of ComplexTypes instead of a single cohesive one.
|
44
|
+
# Consumers should not need to use this parameter; it should only be
|
45
|
+
# used internally.
|
46
|
+
#
|
98
47
|
# @param *strings [Array<String>] The type definitions to parse
|
99
|
-
# @
|
100
|
-
|
48
|
+
# @param partial [Boolean] True if the string is part of a another type
|
49
|
+
# @return [ComplexType]
|
50
|
+
def parse *strings, partial: false
|
51
|
+
@cache ||= {}
|
52
|
+
unless partial
|
53
|
+
cached = @cache[strings]
|
54
|
+
return cached unless cached.nil?
|
55
|
+
end
|
101
56
|
types = []
|
102
57
|
key_types = nil
|
103
58
|
strings.each do |type_string|
|
@@ -116,7 +71,7 @@ module Solargraph
|
|
116
71
|
subtype_string += char
|
117
72
|
elsif base.end_with?('=')
|
118
73
|
raise ComplexTypeError, "Invalid hash thing" unless key_types.nil?
|
119
|
-
types.push ComplexType.new(base[0..-2].strip)
|
74
|
+
types.push ComplexType.new([BasicType.new(base[0..-2].strip)])
|
120
75
|
key_types = types
|
121
76
|
types = []
|
122
77
|
base = ''
|
@@ -144,7 +99,7 @@ module Solargraph
|
|
144
99
|
raise ComplexTypeError, "Invalid close in type #{type_string}" if paren_stack < 0
|
145
100
|
next
|
146
101
|
elsif char == ',' and point_stack == 0 and curly_stack == 0 and paren_stack == 0
|
147
|
-
types.push ComplexType.new
|
102
|
+
types.push ComplexType.new([BasicType.new(base.strip, subtype_string.strip)])
|
148
103
|
base = ''
|
149
104
|
subtype_string = ''
|
150
105
|
next
|
@@ -158,14 +113,21 @@ module Solargraph
|
|
158
113
|
base.strip!
|
159
114
|
subtype_string.strip!
|
160
115
|
raise ComplexTypeError, "Unclosed subtype in #{type_string}" if point_stack != 0 or curly_stack != 0 or paren_stack != 0
|
161
|
-
types.push ComplexType.new(base, subtype_string)
|
116
|
+
types.push ComplexType.new([BasicType.new(base, subtype_string)])
|
162
117
|
end
|
163
118
|
unless key_types.nil?
|
119
|
+
raise ComplexTypeError, "Invalid use of key/value parameters" unless partial
|
164
120
|
return key_types if types.empty?
|
165
121
|
return [key_types, types]
|
166
122
|
end
|
167
|
-
types
|
123
|
+
result = partial ? types : ComplexType.new(types)
|
124
|
+
@cache[strings] = result unless partial
|
125
|
+
result
|
168
126
|
end
|
169
127
|
end
|
128
|
+
|
129
|
+
VOID = ComplexType.parse('void')
|
130
|
+
UNDEFINED = ComplexType.parse('undefined')
|
131
|
+
SYMBOL = ComplexType.parse('Symbol')
|
170
132
|
end
|
171
133
|
end
|