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.
Files changed (65) hide show
  1. checksums.yaml +4 -4
  2. data/lib/solargraph.rb +18 -16
  3. data/lib/solargraph/api_map.rb +100 -161
  4. data/lib/solargraph/api_map/source_to_yard.rb +9 -9
  5. data/lib/solargraph/api_map/store.rb +50 -13
  6. data/lib/solargraph/basic_type.rb +33 -0
  7. data/lib/solargraph/basic_type_methods.rb +111 -0
  8. data/lib/solargraph/complex_type.rb +51 -89
  9. data/lib/solargraph/core_fills.rb +12 -8
  10. data/lib/solargraph/diagnostics/type_not_defined.rb +2 -2
  11. data/lib/solargraph/language_server.rb +3 -0
  12. data/lib/solargraph/language_server/completion_item_kinds.rb +2 -0
  13. data/lib/solargraph/language_server/error_codes.rb +2 -0
  14. data/lib/solargraph/language_server/host.rb +53 -6
  15. data/lib/solargraph/language_server/message.rb +13 -0
  16. data/lib/solargraph/language_server/message/text_document/definition.rb +4 -6
  17. data/lib/solargraph/language_server/message/text_document/document_symbol.rb +2 -1
  18. data/lib/solargraph/language_server/message/workspace/workspace_symbol.rb +2 -1
  19. data/lib/solargraph/language_server/message_types.rb +2 -0
  20. data/lib/solargraph/language_server/request.rb +4 -0
  21. data/lib/solargraph/language_server/symbol_kinds.rb +28 -26
  22. data/lib/solargraph/language_server/transport.rb +3 -0
  23. data/lib/solargraph/language_server/uri_helpers.rb +2 -0
  24. data/lib/solargraph/library.rb +12 -7
  25. data/lib/solargraph/pin.rb +1 -1
  26. data/lib/solargraph/pin/attribute.rb +5 -5
  27. data/lib/solargraph/pin/base.rb +51 -16
  28. data/lib/solargraph/pin/base_variable.rb +25 -7
  29. data/lib/solargraph/pin/block.rb +18 -1
  30. data/lib/solargraph/pin/block_parameter.rb +42 -5
  31. data/lib/solargraph/pin/conversions.rb +4 -2
  32. data/lib/solargraph/pin/method.rb +6 -6
  33. data/lib/solargraph/pin/method_parameter.rb +6 -6
  34. data/lib/solargraph/pin/namespace.rb +7 -2
  35. data/lib/solargraph/pin/proxy_type.rb +39 -0
  36. data/lib/solargraph/pin/symbol.rb +20 -12
  37. data/lib/solargraph/pin/yard_pin/method.rb +2 -2
  38. data/lib/solargraph/source.rb +89 -38
  39. data/lib/solargraph/source/call_chainer.rb +273 -0
  40. data/lib/solargraph/source/chain.rb +104 -0
  41. data/lib/solargraph/source/chain/call.rb +72 -0
  42. data/lib/solargraph/source/chain/class_variable.rb +11 -0
  43. data/lib/solargraph/source/chain/constant.rb +17 -0
  44. data/lib/solargraph/source/chain/definition.rb +16 -0
  45. data/lib/solargraph/source/chain/global_variable.rb +11 -0
  46. data/lib/solargraph/source/chain/head.rb +20 -0
  47. data/lib/solargraph/source/chain/instance_variable.rb +11 -0
  48. data/lib/solargraph/source/chain/link.rb +33 -0
  49. data/lib/solargraph/source/chain/literal.rb +21 -0
  50. data/lib/solargraph/source/chain/variable.rb +11 -0
  51. data/lib/solargraph/source/change.rb +3 -1
  52. data/lib/solargraph/{api_map → source}/completion.rb +3 -1
  53. data/lib/solargraph/source/encoding_fixes.rb +21 -0
  54. data/lib/solargraph/source/fragment.rb +139 -284
  55. data/lib/solargraph/source/mapper.rb +27 -16
  56. data/lib/solargraph/source/node_chainer.rb +94 -0
  57. data/lib/solargraph/source/node_methods.rb +2 -2
  58. data/lib/solargraph/source/position.rb +4 -0
  59. data/lib/solargraph/source/range.rb +10 -2
  60. data/lib/solargraph/version.rb +1 -1
  61. data/lib/solargraph/yard_map.rb +13 -2
  62. metadata +20 -6
  63. data/lib/solargraph/api_map/probe.rb +0 -251
  64. data/lib/solargraph/api_map/type_methods.rb +0 -40
  65. 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 sources
17
+ def rake_yard store
18
18
  code_object_map.clear
19
- sources.each do |s|
20
- s.namespace_pins.each do |pin|
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
- s.namespace_pins.each do |pin|
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
- s.method_pins.each do |pin|
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 *sources
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 *sources
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
- namespace_pins(fqns).select { |pin|
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
- namespace_pins(fqns).select{ |pin|
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
- namespace_pins(fqns).select{ |pin| pin.kind == Pin::ATTRIBUTE and pin.scope == scope }
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
- namespace_pins(base).select{ |pin| pin.path == path }
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
- namespace_pins(fqns).select{|pin| pin.kind == Pin::INSTANCE_VARIABLE and pin.scope == scope}
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
- namespace_pins(fqns).select{|pin| pin.kind == Pin::CLASS_VARIABLE}
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
- # @todo We probably want to ignore '' namespace here
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
- namespace_pins(base).select{|pin| pin.name == name and pin.kind == Pin::NAMESPACE}
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
- def namespace_pins name
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
- def inner_update *sources
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
- # @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
- # 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
- # @param name [String] The name of the type
20
- # @param substring [String] The substring of the type
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
- # @return [Boolean]
50
- def parameters?
51
- !substring.empty?
9
+ def initialize types = [ComplexType::UNDEFINED]
10
+ super()
11
+ concat types
52
12
  end
53
13
 
54
- # @return [Boolean]
55
- def list_parameters?
56
- substring.start_with?('<')
57
- end
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
- # @return [String]
80
- def namespace
81
- @namespace ||= 'Object' if duck_type?
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
- # @return [Symbol] :class or :instance
87
- def scope
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 == other
93
- return false unless self.class == other.class
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
- # @return [Array<ComplexType>]
100
- def parse *strings
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 base.strip, subtype_string.strip
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