solargraph 0.25.1 → 0.26.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|