solargraph 0.25.1 → 0.26.0

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