rdl 2.0.0.rc2 → 2.0.0.rc3

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 (92) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGES.md +7 -1
  3. data/README.md +94 -20
  4. data/lib/rdl.rb +4 -1
  5. data/lib/rdl/config.rb +90 -3
  6. data/lib/rdl/info.rb +16 -0
  7. data/lib/rdl/typecheck.rb +207 -79
  8. data/lib/rdl/types/bot.rb +1 -1
  9. data/lib/rdl/types/dependent_arg.rb +17 -8
  10. data/lib/rdl/types/{finitehash.rb → finite_hash.rb} +3 -29
  11. data/lib/rdl/types/generic.rb +1 -37
  12. data/lib/rdl/types/intersection.rb +1 -0
  13. data/lib/rdl/types/lexer.rex +2 -1
  14. data/lib/rdl/types/lexer.rex.rb +4 -1
  15. data/lib/rdl/types/method.rb +2 -12
  16. data/lib/rdl/types/nominal.rb +1 -22
  17. data/lib/rdl/types/non_null.rb +50 -0
  18. data/lib/rdl/types/parser.racc +3 -1
  19. data/lib/rdl/types/parser.tab.rb +222 -190
  20. data/lib/rdl/types/singleton.rb +1 -6
  21. data/lib/rdl/types/structural.rb +1 -10
  22. data/lib/rdl/types/top.rb +1 -2
  23. data/lib/rdl/types/tuple.rb +3 -19
  24. data/lib/rdl/types/type.rb +223 -0
  25. data/lib/rdl/types/union.rb +12 -2
  26. data/lib/rdl/types/var.rb +4 -1
  27. data/lib/rdl/types/wild_query.rb +1 -0
  28. data/lib/rdl/wrap.rb +199 -169
  29. data/lib/rdl_disable.rb +41 -0
  30. data/lib/rdl_types.rb +1 -4
  31. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/_aliases.rb +0 -0
  32. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/abbrev.rb +0 -0
  33. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/array.rb +56 -56
  34. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/base64.rb +0 -0
  35. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/basic_object.rb +0 -0
  36. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/benchmark.rb +0 -0
  37. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bigdecimal.rb +0 -0
  38. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bigmath.rb +0 -0
  39. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bignum.rb +0 -0
  40. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/class.rb +0 -0
  41. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/complex.rb +0 -0
  42. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/coverage.rb +0 -0
  43. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/csv.rb +0 -0
  44. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/date.rb +0 -0
  45. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/dir.rb +0 -0
  46. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/encoding.rb +0 -0
  47. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/enumerable.rb +0 -0
  48. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/enumerator.rb +0 -0
  49. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/exception.rb +0 -0
  50. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/file.rb +0 -0
  51. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/fileutils.rb +0 -0
  52. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/fixnum.rb +0 -0
  53. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/float.rb +26 -26
  54. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/gem.rb +0 -0
  55. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/hash.rb +0 -0
  56. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/integer.rb +8 -8
  57. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/io.rb +0 -0
  58. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/kernel.rb +12 -11
  59. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/marshal.rb +0 -0
  60. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/matchdata.rb +0 -0
  61. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/math.rb +0 -0
  62. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/module.rb +0 -0
  63. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/nil.rb +0 -0
  64. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/numeric.rb +0 -0
  65. data/lib/types/core-ruby-2.x/object.rb +75 -0
  66. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/pathname.rb +0 -0
  67. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/process.rb +0 -0
  68. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/random.rb +0 -0
  69. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/range.rb +0 -0
  70. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/rational.rb +0 -0
  71. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/regexp.rb +0 -0
  72. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/set.rb +0 -0
  73. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/string.rb +0 -0
  74. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/strscan.rb +0 -0
  75. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/symbol.rb +0 -0
  76. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/time.rb +0 -0
  77. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/uri.rb +0 -0
  78. data/{types/ruby-2.x → lib/types/core-ruby-2.x}/yaml.rb +0 -0
  79. data/lib/types/core.rb +4 -0
  80. data/rdl.gemspec +2 -2
  81. data/test/test_le.rb +77 -35
  82. data/test/test_parser.rb +75 -59
  83. data/test/test_rdl.rb +18 -0
  84. data/test/test_typecheck.rb +73 -4
  85. metadata +54 -57
  86. data/lib/rails_types.rb +0 -1
  87. data/types/rails-4.2.1/fixnum.rb +0 -3
  88. data/types/rails-4.2.1/string.rb +0 -3
  89. data/types/rails-tmp/action_dispatch.rb +0 -406
  90. data/types/rails-tmp/active_record.rb +0 -406
  91. data/types/rails-tmp/devise_contracts.rb +0 -216
  92. data/types/ruby-2.x/object.rb +0 -73
@@ -1,406 +0,0 @@
1
- module ActiveRecord
2
- module Associations
3
- module ClassMethods
4
- extend RDL
5
-
6
- def __rdl_get_arg_method_typesig(mname, arg_options)
7
- if arg_options.keys.include?(:class_name)
8
- c = arg_options[:class_name]
9
- else
10
- c = mname.to_s.singularize.camelize
11
- end
12
-
13
- t = "() -> Array<#{c}>"
14
-
15
- puts "#{self} ##% #{mname} : #{t}"
16
-
17
- t
18
- end
19
-
20
- def __rdl_option_keys_valid?(spec_valid_options, options_used)
21
- # Original class association options can be found with
22
- # ActiveRecord::Associations::Builder::Association.valid_options
23
- # + some more found in ancestors.
24
-
25
- common_options = [:class_name, :foreign_key, :select, :conditions, :include, :extend, :readonly, :validate, :autosave]
26
- valid_options = common_options + spec_valid_options
27
- options_used.keys.all? {|k| valid_options.include?(k)}
28
- end
29
-
30
- def __rdl_arg_objects_defined?(arg_name, arg_options)
31
- if arg_options.keys.include?(:class_name)
32
- n = arg_options[:class_name]
33
- else
34
- n = arg_name.to_s.singularize.camelize
35
- end
36
-
37
- r = true
38
-
39
- if not (arg_options.keys.include?(:polymorphic) and arg_options[:polymorphic] == true)
40
- begin
41
- r = eval(n).ancestors.include?(ActiveRecord::Base)
42
- rescue
43
- r = false
44
- end
45
- end
46
-
47
- r
48
-
49
- # TODO: Fix this, late binding?
50
- true
51
- end
52
-
53
- def __rdl_collection_methods_added?(collection, arg_options)
54
- cstr = collection.to_s
55
- cstr_s = cstr.singularize
56
- new_self_methods = [cstr, "#{cstr}=", "#{cstr_s}_ids", "#{cstr_s}_ids="]
57
- new_self_methods.map! {|m| m.to_sym}
58
-
59
- # TODO: self.new is ok to call here, but may mutate global state in certain classes
60
- # The class of self.new is Array here.
61
-
62
- collection_obj = eval("#{self}.new.#{collection.to_s}")
63
-
64
- new_collection_methods = [:push, :concat, :build, :create, :create!, :size, :length, :count, :sum, :empty?, :clear, :delete, :delete_all, :destroy_all, :find, :exists?, :uniq, :<<]
65
- # TODO: reset is also defined on obj, according to the comment in associations.rb
66
- # but collection_obj.respond(:reset) returns false
67
- # However, http://guides.rubyonrails.org/association_basics.html does not list :reset
68
- # as well as several methods from the above as auto-generated methods.
69
-
70
- methods_added_on_self = new_self_methods.all? {|m|
71
- self.instance_methods.include?(m)
72
- }
73
-
74
- methods_added_on_collection = new_collection_methods.all? {|m|
75
- collection_obj.respond_to?(m)
76
- }
77
-
78
- methods_added_on_self and methods_added_on_collection
79
-
80
- end
81
-
82
- def __rdl_singular_methods_added?(type, assoc, arg_options)
83
- new_methods = {}
84
-
85
- if arg_options.keys.include?(:class_name)
86
- cls = arg_options[:class_name]
87
- else
88
- cls = assoc.to_s.camelize
89
- end
90
-
91
- if type == :belongs_to
92
- if arg_options.keys.include?(:polymorphic) and arg_options[:polymorphic] == true
93
- new_methods[:"#{assoc}"] = "(?%bool) -> #{cls}"
94
- new_methods[:"#{assoc}="] = "(#{cls}) -> #{cls}"
95
- else
96
- new_methods[:"#{assoc}"] = "(?%bool) -> #{cls}"
97
- new_methods[:"#{assoc}="] = "(#{cls}) -> #{cls}"
98
- new_methods[:"build_#{assoc}"] = "(Hash) -> #{cls}"
99
- new_methods[:"create_#{assoc}"] = "(Hash) -> #{cls}"
100
- new_methods[:"create_#{assoc}!"] = "(Hash) -> #{cls}"
101
- end
102
- elsif type == :has_one
103
- new_methods[:"#{assoc}"] = "(?%bool) -> #{cls}"
104
- new_methods[:"#{assoc}="] = "(#{cls}) -> #{cls}"
105
- new_methods[:"build_#{assoc}"] = "(Hash) -> #{cls}"
106
- new_methods[:"create_#{assoc}"] = "(Hash) -> #{cls}"
107
- new_methods[:"create_#{assoc}!"] = "(Hash) -> #{cls}"
108
- else
109
- raise Exception, "type must be a singular association"
110
- end
111
-
112
- new_methods.each {|k, v|
113
- puts "#{self} ##% #{k} : #{v}"
114
-
115
- #add_typesig(self, k, v)
116
- }
117
-
118
- new_methods.keys.all? {|m| self.instance_methods.include?(m)}
119
- end
120
-
121
- spec :belongs_to do
122
- pre_task do |*args|
123
- $belongs_to_arg_name = args[0]
124
-
125
- if args.size == 2
126
- $belongs_to_arg_options = args[1].dup
127
- else
128
- $belongs_to_arg_options = {}
129
- end
130
-
131
- $belongs_to_self = self
132
- end
133
-
134
- pre_cond do |*args|
135
- $belongs_to_arg_name = args[0]
136
- arg_name = $belongs_to_arg_name
137
-
138
- if args.size == 2
139
- $belongs_to_arg_options = args[1].dup
140
- else
141
- $belongs_to_arg_options = {}
142
- end
143
-
144
- slf = eval("self")
145
- arg_options = $belongs_to_arg_options
146
-
147
- spec_valid_options = [:foreign_type, :polymorphic, :touch, :remote, :dependent, :counter_cache, :primary_key, :inverse_of]
148
- option_keys_valid = __rdl_option_keys_valid?(spec_valid_options, arg_options)
149
- arg_classes_defined = __rdl_arg_objects_defined?(arg_name, arg_options)
150
-
151
- if arg_options.keys.include?(:foreign_key)
152
- fk = arg_options[:foreign_key]
153
- else
154
- fk = "#{arg_name.to_s.underscore}_id"
155
- end
156
-
157
- col_names = slf.columns.map {|x| x.name}
158
- foreign_key_col_exist = col_names.include?(fk)
159
-
160
- counter_cache_col_exist = true
161
-
162
- if (arg_options.keys.include?(:counter_cache) and arg_options[:counter_cache]) and not (arg_options.keys.include?(:polymorphic) and arg_options[:polymorphic])
163
- if arg_options.keys.include?(:class_name)
164
- assoc = arg_options[:class_name]
165
- else
166
- assoc = arg_name.to_s.singularize.camelize
167
- end
168
-
169
- assoc_cls = eval(assoc)
170
- assoc_cols = assoc_cls.columns.map {|x| x.name}
171
-
172
- # can specify a symbol to override default
173
- if arg_options[:counter_cache] != true
174
- cid = arg_options[:counter_cache]
175
- else
176
- cid = "#{slf.to_s.pluralize.camelize(:lower)}_count"
177
- end
178
-
179
- counter_cache_col_exist = assoc_cols.include?(cid.to_s)
180
- end
181
-
182
- option_keys_valid and
183
- arg_classes_defined and
184
- foreign_key_col_exist and
185
- counter_cache_col_exist
186
- end
187
-
188
- post_cond do |ret, *args|
189
- arg_name = $belongs_to_arg_name
190
- arg_options = $belongs_to_arg_options
191
- slf = $belongs_to_self
192
-
193
- correct_methods_added = __rdl_singular_methods_added?(:belongs_to, arg_name, arg_options)
194
-
195
- if arg_options.keys.include?(:foreign_key)
196
- fk = arg_options[:foreign_key]
197
- else
198
- fk = "#{arg_name.to_s.underscore}_id"
199
- end
200
-
201
- foreign_key_added = (slf.reflections.keys.include?(arg_name) and
202
- (slf.reflections[arg_name].foreign_key == fk))
203
-
204
- arg_method_added = self.instance_methods.include?(args[0])
205
- arg_method_typesig = __rdl_get_arg_method_typesig(args[0], arg_options)
206
-
207
- puts "#{self} ##% #{args[0]} : #{arg_method_typesig}"
208
- #add_typesig(self, args[0], arg_method_typesig)
209
-
210
- arg_method_added and correct_methods_added and foreign_key_added
211
- end
212
- end
213
-
214
- spec :has_one do
215
- pre_task do |*args|
216
- $has_to_arg_name = args[0]
217
-
218
- if args.size == 2
219
- $has_to_arg_options = args[1].dup
220
- else
221
- $has_to_arg_options = {}
222
- end
223
-
224
- $has_to_self = self
225
- end
226
-
227
- pre_cond do |*args|
228
- $has_one_arg_name = args[0]
229
- arg_name = $has_one_arg_name
230
-
231
- if args.size == 2
232
- $has_one_arg_options = args[1].dup
233
- else
234
- $has_one_arg_options = {}
235
- end
236
-
237
- slf = eval("self")
238
- arg_options = $has_one_arg_options
239
-
240
- spec_valid_options = [:order, :as, :through, :remote, :dependent, :counter_cache, :primary_key, :inverse_of]
241
- option_keys_valid = __rdl_option_keys_valid?(spec_valid_options, arg_options)
242
- arg_classes_defined = __rdl_arg_objects_defined?(arg_name, arg_options)
243
-
244
- option_keys_valid and
245
- arg_classes_defined
246
- end
247
-
248
- post_cond do |ret, *args|
249
- arg_name = $has_one_arg_name
250
- arg_options = $has_one_arg_options
251
- slf = $has_one_self
252
-
253
- correct_methods_added = __rdl_singular_methods_added?(:has_one, arg_name, arg_options)
254
-
255
- arg_method_added = self.instance_methods.include?(args[0])
256
- arg_method_typesig = __rdl_get_arg_method_typesig(args[0], arg_options)
257
-
258
- puts "#{self} ##% #{args[0]} : #{arg_method_typesig}"
259
-
260
- arg_method_added and correct_methods_added
261
- end
262
- end
263
-
264
- spec :has_many do
265
- pre_task do |*args|
266
- $has_many_arg_name = args[0]
267
-
268
- if args.size == 2
269
- $has_many_arg_options = args[1].dup
270
- else
271
- $has_many_arg_options = {}
272
- end
273
-
274
- $has_many_self = self
275
- end
276
-
277
- pre_cond do |*args|
278
- arg_name = args[0]
279
-
280
- if args.size == 2
281
- arg_options = args[1].dup
282
- else
283
- arg_options = {}
284
- end
285
-
286
- slf = eval("self")
287
-
288
- spec_valid_options = [:primary_key, :dependent, :as, :through, :source, :source_type, :inverse_of, :table_name, :order, :group, :having, :limit, :offset, :uniq, :finder_sql, :counter_sql, :before_add, :after_add, :before_remove, :after_remove]
289
- option_keys_valid = __rdl_option_keys_valid?(spec_valid_options, arg_options)
290
- arg_classes_defined = __rdl_arg_objects_defined?(arg_name, arg_options)
291
-
292
- option_keys_valid and
293
- arg_classes_defined
294
- end
295
-
296
- post_cond do |ret, *args|
297
- arg_name = $has_many_arg_name
298
- arg_options = $has_many_arg_options
299
- slf = $has_many_self
300
-
301
- correct_methods_added = __rdl_collection_methods_added?(arg_name, arg_options)
302
-
303
- if arg_options.keys.include?(:foreign_key)
304
- fk = arg_options[:foreign_key]
305
- elsif arg_options.keys.include?(:as)
306
- fk = arg_options[:as].to_s + "_id"
307
- elsif arg_options.keys.include?(:class_name)
308
- fk = arg_options[:class_name].to_s.underscore.camelize(:lower) + "_id"
309
- else
310
- fk = "#{slf.to_s.camelize(:lower)}_id"
311
- end
312
-
313
- foreign_key_added = (slf.reflections.keys.include?(arg_name) and
314
- (slf.reflections[arg_name].foreign_key == fk))
315
-
316
- if arg_options.keys.include?(:foreign_key)
317
- bad_fk = arg_options[:foreign_key]
318
- else
319
- bad_fk = "#{arg_name.to_s.underscore}_id"
320
- end
321
-
322
- col_names = slf.columns.map {|x| x.name}
323
- bad_foreign_key_col_not_exist = (not col_names.include?(fk))
324
-
325
- arg_method_added = self.instance_methods.include?(args[0])
326
- arg_method_typesig = __rdl_get_arg_method_typesig(args[0], arg_options)
327
-
328
- #add_typesig(self, args[0], arg_method_typesig)
329
-
330
- puts "#{self} ##% #{args[0]} : #{arg_method_typesig}"
331
-
332
- arg_method_added and
333
- correct_methods_added and foreign_key_added and
334
- bad_foreign_key_col_not_exist
335
- end
336
- end
337
-
338
- spec :has_and_belongs_to_many do
339
- pre_task do |*args|
340
- $has_and_belongs_to_many_arg_name = args[0]
341
-
342
- if args.size == 2
343
- $has_and_belongs_to_many_arg_options = args[1].dup
344
- else
345
- $has_and_belongs_to_many_arg_options = {}
346
- end
347
-
348
- $has_and_belongs_to_many_self = self
349
- end
350
-
351
- pre_cond do |*args|
352
- $has_and_belongs_to_many_arg_name = args[0]
353
- arg_name = $has_and_belongs_to_many_arg_name
354
-
355
- if args.size == 2
356
- $has_and_belongs_to_many_arg_options = args[1].dup
357
- else
358
- $has_and_belongs_to_many_arg_options = {}
359
- end
360
-
361
- slf = eval("self")
362
- arg_options = $has_and_belongs_to_many_arg_options
363
-
364
- spec_valid_options = [:join_table, :association_foreign_key, :delete_sql, :insert_sql, :table_name, :order, :group, :having, :limit, :offset, :uniq, :finder_sql, :counter_sql, :before_add, :after_add, :before_remove, :after_remove]
365
- option_keys_valid = __rdl_option_keys_valid?(spec_valid_options, arg_options)
366
-
367
- arg_classes_defined = __rdl_arg_objects_defined?(arg_name, arg_options)
368
-
369
- option_keys_valid and
370
- arg_classes_defined
371
- end
372
-
373
- post_cond do |ret, *args|
374
- arg_name = $has_and_belongs_to_many_arg_name
375
- arg_options = $has_and_belongs_to_many_arg_options
376
- slf = $has_and_belongs_to_many_self
377
-
378
- correct_methods_added = __rdl_collection_methods_added?(arg_name, arg_options)
379
-
380
- if arg_options.keys.include?(:foreign_key)
381
- fk = arg_options[:foreign_key]
382
- elsif arg_options.keys.include?(:as)
383
- fk = arg_options[:as].to_s + "_id"
384
- elsif arg_options.keys.include?(:class_name)
385
- fk = arg_options[:class_name].to_s.underscore.camelize(:lower) + "_id"
386
- else
387
- fk = "#{slf.to_s.camelize(:lower)}_id"
388
- end
389
-
390
- arg_method_added = self.instance_methods.include?(args[0])
391
- arg_method_typesig = __rdl_get_arg_method_typesig(args[0], arg_options)
392
-
393
- # this adds methods like poster_lists, owned_lists, etc
394
- #add_typesig(self, args[0], arg_method_typesig)
395
-
396
- puts "#{self} ##% #{args[0]} : #{arg_method_typesig}"
397
-
398
- foreign_key_added = (slf.reflections.keys.include?(arg_name) and
399
- (slf.reflections[arg_name].foreign_key == fk))
400
-
401
- arg_method_added and correct_methods_added and foreign_key_added
402
- end
403
- end
404
- end
405
- end
406
- end
@@ -1,216 +0,0 @@
1
- require'rdl'
2
-
3
- module MapperHelper
4
- class << self
5
- attr_accessor :namespace_stack
6
- end
7
-
8
- def self.devise_for_info_valid?(model, type, action, routes, path_prefix)
9
- ctrl_cls = model.to_s.pluralize.camelize + "Controller"
10
- ctrl_cls = eval(ctrl_cls)
11
-
12
- info = get_devise_for_info(model, type, action, path_prefix)
13
- path_helper_method = info[:path_helper][0]
14
- url_helper_method = info[:url_helper][0]
15
- path_helper_method_type = info[:path_helper][0]
16
- url_helper_method_type = info[:url_helper][0]
17
- path = info[:path]
18
- verb = info[:verb]
19
- ctrl = info[:controller]
20
-
21
- # TODO: this part should be in post_task, but need a better way to
22
- # take care of shared code?
23
-
24
- # typesig(ctrl_cls, path_helper_method, path_helper_method_type)
25
- # typesig(ctrl_cls, url_helper_method, url_helper_method_type)
26
-
27
- route_added = routes.any? {|r|
28
- defaults = r.defaults
29
- route_path = r.path.spec.to_s.split('(')[0]
30
-
31
- route_path == path and verb.include?(r.verb) and
32
- defaults[:action] == action.to_s and defaults[:controller] == ctrl
33
- }
34
-
35
- ctrl_cls.instance_methods.include?(path_helper_method) and
36
- ctrl_cls.instance_methods.include?(url_helper_method) and
37
- route_added
38
- end
39
-
40
- def self.get_devise_for_info(model, type, action, path_prefix="")
41
- # TODO: the arg types may be (*Hash), where each Hash is a user_session?
42
- # where is this defined?
43
-
44
- model_s = model.to_s.singularize
45
- model_s_c = model_s.camelize
46
-
47
- ns = MapperHelper.namespace_stack
48
- namespace_str = ns.empty? ? "" : ns.join("_") + "_"
49
- namespace_path_str = ns.empty? ? "" : ns.join("/") + "/"
50
- ctrl_prefix = namespace_path_str == "" ? "devise/" : namespace_path_str
51
-
52
- case type
53
- when :session
54
- case action
55
- when :new
56
- h = :"new_#{namespace_str}#{model_s}_session"
57
- v = [/^GET$/]
58
- p = "#{path_prefix}/#{model}/sign_in"
59
- pht = "(?Hash) -> String"
60
- when :create
61
- h = :"#{namespace_str}#{model_s}_session"
62
- v = [/^POST$/]
63
- p = "#{path_prefix}/#{model}/sign_in"
64
- pht = "(?Hash) -> String"
65
- when :destroy
66
- h = :"destroy_#{namespace_str}#{model_s}_session"
67
- v = [/^DELETE$/]
68
- p = "#{path_prefix}/#{model}/sign_out"
69
- # TODO: Is there a better way to specify arg is a user session?
70
- pht = "(?Hash) -> String"
71
- else
72
- raise Exception, "invalid action for #{type.inspect}"
73
- end
74
-
75
- controller = "#{ctrl_prefix}sessions"
76
- when :password
77
- case action
78
- when :new
79
- h = :"new_#{namespace_str}#{model_s}_password"
80
- v = [/^GET$/]
81
- p = "#{path_prefix}/#{model}/password/new"
82
- pht = "(?Hash) -> String"
83
- when :edit
84
- h = :"edit_#{namespace_str}#{model_s}_password"
85
- v = [/^GET$/]
86
- p = "#{path_prefix}/#{model}/password/edit"
87
- pht = "(?Hash) -> String"
88
- when :update
89
- h = :"#{namespace_str}#{model_s}_password"
90
- v = [/^PUT$/]
91
- p = "#{path_prefix}/#{model}/password"
92
- pht = "(?Hash) -> String"
93
- when :create
94
- h = :"#{namespace_str}#{model_s}_password"
95
- v = [/^POST$/]
96
- p = "#{path_prefix}/#{model}/password"
97
- pht = "(?Hash) -> String"
98
- else
99
- raise Exception, "invalid action for #{type.inspect}"
100
- end
101
-
102
- controller = "#{ctrl_prefix}passwords"
103
- when :confirmation
104
- case action
105
- when :new
106
- h = :"new_#{namespace_str}#{model_s}_confirmation"
107
- v = [/^GET$/]
108
- p = "#{path_prefix}/#{model}/confirmation/new"
109
- pht = "(?Hash) -> String"
110
- when :show
111
- h = :"#{namespace_str}#{model_s}_confirmation"
112
- v = [/^GET$/]
113
- p = "#{path_prefix}/#{model}/confirmation"
114
- pht = "(?Hash) -> String"
115
- when :create
116
- h = :"#{namespace_str}#{model_s}_confirmation"
117
- v = [/^POST$/]
118
- p = "#{path_prefix}/#{model}/confirmation"
119
- pht = "(?Hash) -> String"
120
- else
121
- raise Exception, "invalid action for #{type.inspect}"
122
- end
123
-
124
- controller = "#{ctrl_prefix}confirmations"
125
- else
126
- raise Exception, "invalid action"
127
- end
128
-
129
- ph = :"#{h}_path"
130
- uh = :"#{h}_url"
131
- uht = pht
132
-
133
- {:verb => v, :path => p, :path_helper => [ph, pht], :url_helper => [uh, uht], :controller => controller}
134
- end
135
- end
136
-
137
- module ActionDispatch::Routing
138
- class Mapper
139
- extend RDL
140
-
141
- spec :namespace do
142
- pre_task do |arg|
143
- MapperHelper.namespace_stack = [] if not MapperHelper.namespace_stack
144
- MapperHelper.namespace_stack.push(arg)
145
- end
146
-
147
- post_task do |ret, *arg|
148
- MapperHelper.namespace_stack.pop
149
- end
150
- end
151
-
152
- # TODO: other valid options for devise_for
153
- spec :devise_for do
154
- post_cond do |ret, *args|
155
- model = args[0].to_s
156
- model_s = model.singularize
157
- model_cls = eval(model_s.camelize)
158
-
159
- if args[-1].class == Hash and args[-1].keys.include?(:path_prefix)
160
- path_prefix = "/#{args[-1][:path_prefix]}"
161
- else
162
- path_prefix = ""
163
- end
164
-
165
- routes = Rails.application.routes.routes.to_a
166
-
167
- # default is session
168
- actions = [:new, :create, :destroy]
169
-
170
- session_info_valid = actions.all? {|action|
171
- MapperHelper.devise_for_info_valid?(model, :session, action, routes, path_prefix)
172
- }
173
-
174
- if model_cls.devise_modules.include?(:recoverable)
175
- actions = [:new, :edit, :update, :create]
176
-
177
- password_info_valid = actions.all? {|action|
178
- MapperHelper.devise_for_info_valid?(model, :password, action, routes, path_prefix)
179
- }
180
- else
181
- password_info_valid = true
182
- end
183
-
184
- if model_cls.devise_modules.include?(:confirmable)
185
- actions = [:new, :show, :create]
186
-
187
- confirmation_info_valid = actions.all? {|action|
188
- MapperHelper.devise_for_info_valid?(model, :confirmation, action, routes, path_prefix)
189
- }
190
- else
191
- confirmation_info_valid = true
192
- end
193
-
194
- ns = MapperHelper.namespace_stack
195
- namespace_str = ns.empty? ? "" : ns.join("_") + "_"
196
-
197
- helper_methods = {}
198
- helper_methods[:"current_#{namespace_str}#{model_s}"] = "() -> #{model_cls}"
199
- helper_methods[:"#{namespace_str}#{model_s}_signed_in?"] = "() -> %bool"
200
- helper_methods[:"authenticate_#{namespace_str}#{model_s}!"] = "() -> #{model_cls}"
201
-
202
- helper_info_valid = helper_methods.keys.all? {|m|
203
- ApplicationController.instance_methods.include?(m)
204
- }
205
-
206
- # this should be in post_task? but how to take care of shared code
207
- helper_methods.each {|method, type|
208
- #add_typesig(ApplicationController, method, type)
209
- }
210
-
211
- session_info_valid and password_info_valid and confirmation_info_valid and helper_info_valid
212
- end
213
- end
214
- end
215
- end
216
-