actionview 5.2.3

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 (108) hide show
  1. checksums.yaml +7 -0
  2. data/CHANGELOG.md +142 -0
  3. data/MIT-LICENSE +21 -0
  4. data/README.rdoc +38 -0
  5. data/lib/action_view.rb +97 -0
  6. data/lib/action_view/base.rb +215 -0
  7. data/lib/action_view/buffers.rb +52 -0
  8. data/lib/action_view/context.rb +36 -0
  9. data/lib/action_view/dependency_tracker.rb +175 -0
  10. data/lib/action_view/digestor.rb +134 -0
  11. data/lib/action_view/flows.rb +76 -0
  12. data/lib/action_view/gem_version.rb +17 -0
  13. data/lib/action_view/helpers.rb +68 -0
  14. data/lib/action_view/helpers/active_model_helper.rb +55 -0
  15. data/lib/action_view/helpers/asset_tag_helper.rb +511 -0
  16. data/lib/action_view/helpers/asset_url_helper.rb +469 -0
  17. data/lib/action_view/helpers/atom_feed_helper.rb +205 -0
  18. data/lib/action_view/helpers/cache_helper.rb +263 -0
  19. data/lib/action_view/helpers/capture_helper.rb +212 -0
  20. data/lib/action_view/helpers/controller_helper.rb +36 -0
  21. data/lib/action_view/helpers/csp_helper.rb +24 -0
  22. data/lib/action_view/helpers/csrf_helper.rb +35 -0
  23. data/lib/action_view/helpers/date_helper.rb +1156 -0
  24. data/lib/action_view/helpers/debug_helper.rb +36 -0
  25. data/lib/action_view/helpers/form_helper.rb +2337 -0
  26. data/lib/action_view/helpers/form_options_helper.rb +887 -0
  27. data/lib/action_view/helpers/form_tag_helper.rb +917 -0
  28. data/lib/action_view/helpers/javascript_helper.rb +94 -0
  29. data/lib/action_view/helpers/number_helper.rb +451 -0
  30. data/lib/action_view/helpers/output_safety_helper.rb +70 -0
  31. data/lib/action_view/helpers/record_tag_helper.rb +23 -0
  32. data/lib/action_view/helpers/rendering_helper.rb +99 -0
  33. data/lib/action_view/helpers/sanitize_helper.rb +177 -0
  34. data/lib/action_view/helpers/tag_helper.rb +313 -0
  35. data/lib/action_view/helpers/tags.rb +44 -0
  36. data/lib/action_view/helpers/tags/base.rb +192 -0
  37. data/lib/action_view/helpers/tags/check_box.rb +66 -0
  38. data/lib/action_view/helpers/tags/checkable.rb +18 -0
  39. data/lib/action_view/helpers/tags/collection_check_boxes.rb +36 -0
  40. data/lib/action_view/helpers/tags/collection_helpers.rb +119 -0
  41. data/lib/action_view/helpers/tags/collection_radio_buttons.rb +31 -0
  42. data/lib/action_view/helpers/tags/collection_select.rb +30 -0
  43. data/lib/action_view/helpers/tags/color_field.rb +27 -0
  44. data/lib/action_view/helpers/tags/date_field.rb +15 -0
  45. data/lib/action_view/helpers/tags/date_select.rb +74 -0
  46. data/lib/action_view/helpers/tags/datetime_field.rb +32 -0
  47. data/lib/action_view/helpers/tags/datetime_local_field.rb +21 -0
  48. data/lib/action_view/helpers/tags/datetime_select.rb +10 -0
  49. data/lib/action_view/helpers/tags/email_field.rb +10 -0
  50. data/lib/action_view/helpers/tags/file_field.rb +10 -0
  51. data/lib/action_view/helpers/tags/grouped_collection_select.rb +31 -0
  52. data/lib/action_view/helpers/tags/hidden_field.rb +10 -0
  53. data/lib/action_view/helpers/tags/label.rb +81 -0
  54. data/lib/action_view/helpers/tags/month_field.rb +15 -0
  55. data/lib/action_view/helpers/tags/number_field.rb +20 -0
  56. data/lib/action_view/helpers/tags/password_field.rb +14 -0
  57. data/lib/action_view/helpers/tags/placeholderable.rb +24 -0
  58. data/lib/action_view/helpers/tags/radio_button.rb +33 -0
  59. data/lib/action_view/helpers/tags/range_field.rb +10 -0
  60. data/lib/action_view/helpers/tags/search_field.rb +27 -0
  61. data/lib/action_view/helpers/tags/select.rb +43 -0
  62. data/lib/action_view/helpers/tags/tel_field.rb +10 -0
  63. data/lib/action_view/helpers/tags/text_area.rb +24 -0
  64. data/lib/action_view/helpers/tags/text_field.rb +34 -0
  65. data/lib/action_view/helpers/tags/time_field.rb +15 -0
  66. data/lib/action_view/helpers/tags/time_select.rb +10 -0
  67. data/lib/action_view/helpers/tags/time_zone_select.rb +22 -0
  68. data/lib/action_view/helpers/tags/translator.rb +44 -0
  69. data/lib/action_view/helpers/tags/url_field.rb +10 -0
  70. data/lib/action_view/helpers/tags/week_field.rb +15 -0
  71. data/lib/action_view/helpers/text_helper.rb +486 -0
  72. data/lib/action_view/helpers/translation_helper.rb +141 -0
  73. data/lib/action_view/helpers/url_helper.rb +676 -0
  74. data/lib/action_view/layouts.rb +433 -0
  75. data/lib/action_view/locale/en.yml +56 -0
  76. data/lib/action_view/log_subscriber.rb +96 -0
  77. data/lib/action_view/lookup_context.rb +274 -0
  78. data/lib/action_view/model_naming.rb +14 -0
  79. data/lib/action_view/path_set.rb +100 -0
  80. data/lib/action_view/railtie.rb +82 -0
  81. data/lib/action_view/record_identifier.rb +112 -0
  82. data/lib/action_view/renderer/abstract_renderer.rb +55 -0
  83. data/lib/action_view/renderer/partial_renderer.rb +552 -0
  84. data/lib/action_view/renderer/partial_renderer/collection_caching.rb +57 -0
  85. data/lib/action_view/renderer/renderer.rb +56 -0
  86. data/lib/action_view/renderer/streaming_template_renderer.rb +105 -0
  87. data/lib/action_view/renderer/template_renderer.rb +102 -0
  88. data/lib/action_view/rendering.rb +151 -0
  89. data/lib/action_view/routing_url_for.rb +145 -0
  90. data/lib/action_view/tasks/cache_digests.rake +25 -0
  91. data/lib/action_view/template.rb +361 -0
  92. data/lib/action_view/template/error.rb +141 -0
  93. data/lib/action_view/template/handlers.rb +66 -0
  94. data/lib/action_view/template/handlers/builder.rb +25 -0
  95. data/lib/action_view/template/handlers/erb.rb +74 -0
  96. data/lib/action_view/template/handlers/erb/erubi.rb +83 -0
  97. data/lib/action_view/template/handlers/html.rb +11 -0
  98. data/lib/action_view/template/handlers/raw.rb +11 -0
  99. data/lib/action_view/template/html.rb +34 -0
  100. data/lib/action_view/template/resolver.rb +391 -0
  101. data/lib/action_view/template/text.rb +33 -0
  102. data/lib/action_view/template/types.rb +57 -0
  103. data/lib/action_view/test_case.rb +300 -0
  104. data/lib/action_view/testing/resolvers.rb +54 -0
  105. data/lib/action_view/version.rb +10 -0
  106. data/lib/action_view/view_paths.rb +105 -0
  107. data/lib/assets/compiled/rails-ujs.js +720 -0
  108. metadata +255 -0
@@ -0,0 +1,391 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "pathname"
4
+ require "active_support/core_ext/class"
5
+ require "active_support/core_ext/module/attribute_accessors"
6
+ require "action_view/template"
7
+ require "thread"
8
+ require "concurrent/map"
9
+
10
+ module ActionView
11
+ # = Action View Resolver
12
+ class Resolver
13
+ # Keeps all information about view path and builds virtual path.
14
+ class Path
15
+ attr_reader :name, :prefix, :partial, :virtual
16
+ alias_method :partial?, :partial
17
+
18
+ def self.build(name, prefix, partial)
19
+ virtual = "".dup
20
+ virtual << "#{prefix}/" unless prefix.empty?
21
+ virtual << (partial ? "_#{name}" : name)
22
+ new name, prefix, partial, virtual
23
+ end
24
+
25
+ def initialize(name, prefix, partial, virtual)
26
+ @name = name
27
+ @prefix = prefix
28
+ @partial = partial
29
+ @virtual = virtual
30
+ end
31
+
32
+ def to_str
33
+ @virtual
34
+ end
35
+ alias :to_s :to_str
36
+ end
37
+
38
+ # Threadsafe template cache
39
+ class Cache #:nodoc:
40
+ class SmallCache < Concurrent::Map
41
+ def initialize(options = {})
42
+ super(options.merge(initial_capacity: 2))
43
+ end
44
+ end
45
+
46
+ # preallocate all the default blocks for performance/memory consumption reasons
47
+ PARTIAL_BLOCK = lambda { |cache, partial| cache[partial] = SmallCache.new }
48
+ PREFIX_BLOCK = lambda { |cache, prefix| cache[prefix] = SmallCache.new(&PARTIAL_BLOCK) }
49
+ NAME_BLOCK = lambda { |cache, name| cache[name] = SmallCache.new(&PREFIX_BLOCK) }
50
+ KEY_BLOCK = lambda { |cache, key| cache[key] = SmallCache.new(&NAME_BLOCK) }
51
+
52
+ # usually a majority of template look ups return nothing, use this canonical preallocated array to save memory
53
+ NO_TEMPLATES = [].freeze
54
+
55
+ def initialize
56
+ @data = SmallCache.new(&KEY_BLOCK)
57
+ @query_cache = SmallCache.new
58
+ end
59
+
60
+ def inspect
61
+ "#<#{self.class.name}:0x#{(object_id << 1).to_s(16)} keys=#{@data.size} queries=#{@query_cache.size}>"
62
+ end
63
+
64
+ # Cache the templates returned by the block
65
+ def cache(key, name, prefix, partial, locals)
66
+ if Resolver.caching?
67
+ @data[key][name][prefix][partial][locals] ||= canonical_no_templates(yield)
68
+ else
69
+ fresh_templates = yield
70
+ cached_templates = @data[key][name][prefix][partial][locals]
71
+
72
+ if templates_have_changed?(cached_templates, fresh_templates)
73
+ @data[key][name][prefix][partial][locals] = canonical_no_templates(fresh_templates)
74
+ else
75
+ cached_templates || NO_TEMPLATES
76
+ end
77
+ end
78
+ end
79
+
80
+ def cache_query(query) # :nodoc:
81
+ if Resolver.caching?
82
+ @query_cache[query] ||= canonical_no_templates(yield)
83
+ else
84
+ yield
85
+ end
86
+ end
87
+
88
+ def clear
89
+ @data.clear
90
+ @query_cache.clear
91
+ end
92
+
93
+ # Get the cache size. Do not call this
94
+ # method. This method is not guaranteed to be here ever.
95
+ def size # :nodoc:
96
+ size = 0
97
+ @data.each_value do |v1|
98
+ v1.each_value do |v2|
99
+ v2.each_value do |v3|
100
+ v3.each_value do |v4|
101
+ size += v4.size
102
+ end
103
+ end
104
+ end
105
+ end
106
+
107
+ size + @query_cache.size
108
+ end
109
+
110
+ private
111
+
112
+ def canonical_no_templates(templates)
113
+ templates.empty? ? NO_TEMPLATES : templates
114
+ end
115
+
116
+ def templates_have_changed?(cached_templates, fresh_templates)
117
+ # if either the old or new template list is empty, we don't need to (and can't)
118
+ # compare modification times, and instead just check whether the lists are different
119
+ if cached_templates.blank? || fresh_templates.blank?
120
+ return fresh_templates.blank? != cached_templates.blank?
121
+ end
122
+
123
+ cached_templates_max_updated_at = cached_templates.map(&:updated_at).max
124
+
125
+ # if a template has changed, it will be now be newer than all the cached templates
126
+ fresh_templates.any? { |t| t.updated_at > cached_templates_max_updated_at }
127
+ end
128
+ end
129
+
130
+ cattr_accessor :caching, default: true
131
+
132
+ class << self
133
+ alias :caching? :caching
134
+ end
135
+
136
+ def initialize
137
+ @cache = Cache.new
138
+ end
139
+
140
+ def clear_cache
141
+ @cache.clear
142
+ end
143
+
144
+ # Normalizes the arguments and passes it on to find_templates.
145
+ def find_all(name, prefix = nil, partial = false, details = {}, key = nil, locals = [])
146
+ cached(key, [name, prefix, partial], details, locals) do
147
+ find_templates(name, prefix, partial, details)
148
+ end
149
+ end
150
+
151
+ def find_all_anywhere(name, prefix, partial = false, details = {}, key = nil, locals = [])
152
+ cached(key, [name, prefix, partial], details, locals) do
153
+ find_templates(name, prefix, partial, details, true)
154
+ end
155
+ end
156
+
157
+ def find_all_with_query(query) # :nodoc:
158
+ @cache.cache_query(query) { find_template_paths(File.join(@path, query)) }
159
+ end
160
+
161
+ private
162
+
163
+ delegate :caching?, to: :class
164
+
165
+ # This is what child classes implement. No defaults are needed
166
+ # because Resolver guarantees that the arguments are present and
167
+ # normalized.
168
+ def find_templates(name, prefix, partial, details, outside_app_allowed = false)
169
+ raise NotImplementedError, "Subclasses must implement a find_templates(name, prefix, partial, details, outside_app_allowed = false) method"
170
+ end
171
+
172
+ # Helpers that builds a path. Useful for building virtual paths.
173
+ def build_path(name, prefix, partial)
174
+ Path.build(name, prefix, partial)
175
+ end
176
+
177
+ # Handles templates caching. If a key is given and caching is on
178
+ # always check the cache before hitting the resolver. Otherwise,
179
+ # it always hits the resolver but if the key is present, check if the
180
+ # resolver is fresher before returning it.
181
+ def cached(key, path_info, details, locals)
182
+ name, prefix, partial = path_info
183
+ locals = locals.map(&:to_s).sort!
184
+
185
+ if key
186
+ @cache.cache(key, name, prefix, partial, locals) do
187
+ decorate(yield, path_info, details, locals)
188
+ end
189
+ else
190
+ decorate(yield, path_info, details, locals)
191
+ end
192
+ end
193
+
194
+ # Ensures all the resolver information is set in the template.
195
+ def decorate(templates, path_info, details, locals)
196
+ cached = nil
197
+ templates.each do |t|
198
+ t.locals = locals
199
+ t.formats = details[:formats] || [:html] if t.formats.empty?
200
+ t.variants = details[:variants] || [] if t.variants.empty?
201
+ t.virtual_path ||= (cached ||= build_path(*path_info))
202
+ end
203
+ end
204
+ end
205
+
206
+ # An abstract class that implements a Resolver with path semantics.
207
+ class PathResolver < Resolver #:nodoc:
208
+ EXTENSIONS = { locale: ".", formats: ".", variants: "+", handlers: "." }
209
+ DEFAULT_PATTERN = ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}"
210
+
211
+ def initialize(pattern = nil)
212
+ @pattern = pattern || DEFAULT_PATTERN
213
+ super()
214
+ end
215
+
216
+ private
217
+
218
+ def find_templates(name, prefix, partial, details, outside_app_allowed = false)
219
+ path = Path.build(name, prefix, partial)
220
+ query(path, details, details[:formats], outside_app_allowed)
221
+ end
222
+
223
+ def query(path, details, formats, outside_app_allowed)
224
+ query = build_query(path, details)
225
+
226
+ template_paths = find_template_paths(query)
227
+ template_paths = reject_files_external_to_app(template_paths) unless outside_app_allowed
228
+
229
+ template_paths.map do |template|
230
+ handler, format, variant = extract_handler_and_format_and_variant(template)
231
+ contents = File.binread(template)
232
+
233
+ Template.new(contents, File.expand_path(template), handler,
234
+ virtual_path: path.virtual,
235
+ format: format,
236
+ variant: variant,
237
+ updated_at: mtime(template)
238
+ )
239
+ end
240
+ end
241
+
242
+ def reject_files_external_to_app(files)
243
+ files.reject { |filename| !inside_path?(@path, filename) }
244
+ end
245
+
246
+ def find_template_paths(query)
247
+ Dir[query].uniq.reject do |filename|
248
+ File.directory?(filename) ||
249
+ # deals with case-insensitive file systems.
250
+ !File.fnmatch(query, filename, File::FNM_EXTGLOB)
251
+ end
252
+ end
253
+
254
+ def inside_path?(path, filename)
255
+ filename = File.expand_path(filename)
256
+ path = File.join(path, "")
257
+ filename.start_with?(path)
258
+ end
259
+
260
+ # Helper for building query glob string based on resolver's pattern.
261
+ def build_query(path, details)
262
+ query = @pattern.dup
263
+
264
+ prefix = path.prefix.empty? ? "" : "#{escape_entry(path.prefix)}\\1"
265
+ query.gsub!(/:prefix(\/)?/, prefix)
266
+
267
+ partial = escape_entry(path.partial? ? "_#{path.name}" : path.name)
268
+ query.gsub!(/:action/, partial)
269
+
270
+ details.each do |ext, candidates|
271
+ if ext == :variants && candidates == :any
272
+ query.gsub!(/:#{ext}/, "*")
273
+ else
274
+ query.gsub!(/:#{ext}/, "{#{candidates.compact.uniq.join(',')}}")
275
+ end
276
+ end
277
+
278
+ File.expand_path(query, @path)
279
+ end
280
+
281
+ def escape_entry(entry)
282
+ entry.gsub(/[*?{}\[\]]/, '\\\\\\&'.freeze)
283
+ end
284
+
285
+ # Returns the file mtime from the filesystem.
286
+ def mtime(p)
287
+ File.mtime(p)
288
+ end
289
+
290
+ # Extract handler, formats and variant from path. If a format cannot be found neither
291
+ # from the path, or the handler, we should return the array of formats given
292
+ # to the resolver.
293
+ def extract_handler_and_format_and_variant(path)
294
+ pieces = File.basename(path).split(".".freeze)
295
+ pieces.shift
296
+
297
+ extension = pieces.pop
298
+
299
+ handler = Template.handler_for_extension(extension)
300
+ format, variant = pieces.last.split(EXTENSIONS[:variants], 2) if pieces.last
301
+ format &&= Template::Types[format]
302
+
303
+ [handler, format, variant]
304
+ end
305
+ end
306
+
307
+ # A resolver that loads files from the filesystem. It allows setting your own
308
+ # resolving pattern. Such pattern can be a glob string supported by some variables.
309
+ #
310
+ # ==== Examples
311
+ #
312
+ # Default pattern, loads views the same way as previous versions of rails, eg. when you're
313
+ # looking for <tt>users/new</tt> it will produce query glob: <tt>users/new{.{en},}{.{html,js},}{.{erb,haml},}</tt>
314
+ #
315
+ # FileSystemResolver.new("/path/to/views", ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
316
+ #
317
+ # This one allows you to keep files with different formats in separate subdirectories,
318
+ # eg. <tt>users/new.html</tt> will be loaded from <tt>users/html/new.erb</tt> or <tt>users/new.html.erb</tt>,
319
+ # <tt>users/new.js</tt> from <tt>users/js/new.erb</tt> or <tt>users/new.js.erb</tt>, etc.
320
+ #
321
+ # FileSystemResolver.new("/path/to/views", ":prefix/{:formats/,}:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}")
322
+ #
323
+ # If you don't specify a pattern then the default will be used.
324
+ #
325
+ # In order to use any of the customized resolvers above in a Rails application, you just need
326
+ # to configure ActionController::Base.view_paths in an initializer, for example:
327
+ #
328
+ # ActionController::Base.view_paths = FileSystemResolver.new(
329
+ # Rails.root.join("app/views"),
330
+ # ":prefix/:action{.:locale,}{.:formats,}{+:variants,}{.:handlers,}",
331
+ # )
332
+ #
333
+ # ==== Pattern format and variables
334
+ #
335
+ # Pattern has to be a valid glob string, and it allows you to use the
336
+ # following variables:
337
+ #
338
+ # * <tt>:prefix</tt> - usually the controller path
339
+ # * <tt>:action</tt> - name of the action
340
+ # * <tt>:locale</tt> - possible locale versions
341
+ # * <tt>:formats</tt> - possible request formats (for example html, json, xml...)
342
+ # * <tt>:variants</tt> - possible request variants (for example phone, tablet...)
343
+ # * <tt>:handlers</tt> - possible handlers (for example erb, haml, builder...)
344
+ #
345
+ class FileSystemResolver < PathResolver
346
+ def initialize(path, pattern = nil)
347
+ raise ArgumentError, "path already is a Resolver class" if path.is_a?(Resolver)
348
+ super(pattern)
349
+ @path = File.expand_path(path)
350
+ end
351
+
352
+ def to_s
353
+ @path.to_s
354
+ end
355
+ alias :to_path :to_s
356
+
357
+ def eql?(resolver)
358
+ self.class.equal?(resolver.class) && to_path == resolver.to_path
359
+ end
360
+ alias :== :eql?
361
+ end
362
+
363
+ # An Optimized resolver for Rails' most common case.
364
+ class OptimizedFileSystemResolver < FileSystemResolver #:nodoc:
365
+ def build_query(path, details)
366
+ query = escape_entry(File.join(@path, path))
367
+
368
+ exts = EXTENSIONS.map do |ext, prefix|
369
+ if ext == :variants && details[ext] == :any
370
+ "{#{prefix}*,}"
371
+ else
372
+ "{#{details[ext].compact.uniq.map { |e| "#{prefix}#{e}," }.join}}"
373
+ end
374
+ end.join
375
+
376
+ query + exts
377
+ end
378
+ end
379
+
380
+ # The same as FileSystemResolver but does not allow templates to store
381
+ # a virtual path since it is invalid for such resolvers.
382
+ class FallbackFileSystemResolver < FileSystemResolver #:nodoc:
383
+ def self.instances
384
+ [new(""), new("/")]
385
+ end
386
+
387
+ def decorate(*)
388
+ super.each { |t| t.virtual_path = nil }
389
+ end
390
+ end
391
+ end
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ActionView #:nodoc:
4
+ # = Action View Text Template
5
+ class Template #:nodoc:
6
+ class Text #:nodoc:
7
+ attr_accessor :type
8
+
9
+ def initialize(string)
10
+ @string = string.to_s
11
+ @type = Types[:text]
12
+ end
13
+
14
+ def identifier
15
+ "text template"
16
+ end
17
+
18
+ alias_method :inspect, :identifier
19
+
20
+ def to_str
21
+ @string
22
+ end
23
+
24
+ def render(*args)
25
+ to_str
26
+ end
27
+
28
+ def formats
29
+ [@type.ref]
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,57 @@
1
+ # frozen_string_literal: true
2
+
3
+ require "active_support/core_ext/module/attribute_accessors"
4
+
5
+ module ActionView
6
+ class Template #:nodoc:
7
+ class Types
8
+ class Type
9
+ SET = Struct.new(:symbols).new([ :html, :text, :js, :css, :xml, :json ])
10
+
11
+ def self.[](type)
12
+ if type.is_a?(self)
13
+ type
14
+ else
15
+ new(type)
16
+ end
17
+ end
18
+
19
+ attr_reader :symbol
20
+
21
+ def initialize(symbol)
22
+ @symbol = symbol.to_sym
23
+ end
24
+
25
+ def to_s
26
+ @symbol.to_s
27
+ end
28
+ alias to_str to_s
29
+
30
+ def ref
31
+ @symbol
32
+ end
33
+ alias to_sym ref
34
+
35
+ def ==(type)
36
+ @symbol == type.to_sym unless type.blank?
37
+ end
38
+ end
39
+
40
+ cattr_accessor :type_klass
41
+
42
+ def self.delegate_to(klass)
43
+ self.type_klass = klass
44
+ end
45
+
46
+ delegate_to Type
47
+
48
+ def self.[](type)
49
+ type_klass[type]
50
+ end
51
+
52
+ def self.symbols
53
+ type_klass::SET.symbols
54
+ end
55
+ end
56
+ end
57
+ end