rdl 2.0.0.rc2 → 2.0.0.rc3
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +7 -1
- data/README.md +94 -20
- data/lib/rdl.rb +4 -1
- data/lib/rdl/config.rb +90 -3
- data/lib/rdl/info.rb +16 -0
- data/lib/rdl/typecheck.rb +207 -79
- data/lib/rdl/types/bot.rb +1 -1
- data/lib/rdl/types/dependent_arg.rb +17 -8
- data/lib/rdl/types/{finitehash.rb → finite_hash.rb} +3 -29
- data/lib/rdl/types/generic.rb +1 -37
- data/lib/rdl/types/intersection.rb +1 -0
- data/lib/rdl/types/lexer.rex +2 -1
- data/lib/rdl/types/lexer.rex.rb +4 -1
- data/lib/rdl/types/method.rb +2 -12
- data/lib/rdl/types/nominal.rb +1 -22
- data/lib/rdl/types/non_null.rb +50 -0
- data/lib/rdl/types/parser.racc +3 -1
- data/lib/rdl/types/parser.tab.rb +222 -190
- data/lib/rdl/types/singleton.rb +1 -6
- data/lib/rdl/types/structural.rb +1 -10
- data/lib/rdl/types/top.rb +1 -2
- data/lib/rdl/types/tuple.rb +3 -19
- data/lib/rdl/types/type.rb +223 -0
- data/lib/rdl/types/union.rb +12 -2
- data/lib/rdl/types/var.rb +4 -1
- data/lib/rdl/types/wild_query.rb +1 -0
- data/lib/rdl/wrap.rb +199 -169
- data/lib/rdl_disable.rb +41 -0
- data/lib/rdl_types.rb +1 -4
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/_aliases.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/abbrev.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/array.rb +56 -56
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/base64.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/basic_object.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/benchmark.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bigdecimal.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bigmath.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/bignum.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/class.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/complex.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/coverage.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/csv.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/date.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/dir.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/encoding.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/enumerable.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/enumerator.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/exception.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/file.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/fileutils.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/fixnum.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/float.rb +26 -26
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/gem.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/hash.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/integer.rb +8 -8
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/io.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/kernel.rb +12 -11
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/marshal.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/matchdata.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/math.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/module.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/nil.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/numeric.rb +0 -0
- data/lib/types/core-ruby-2.x/object.rb +75 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/pathname.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/process.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/random.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/range.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/rational.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/regexp.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/set.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/string.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/strscan.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/symbol.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/time.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/uri.rb +0 -0
- data/{types/ruby-2.x → lib/types/core-ruby-2.x}/yaml.rb +0 -0
- data/lib/types/core.rb +4 -0
- data/rdl.gemspec +2 -2
- data/test/test_le.rb +77 -35
- data/test/test_parser.rb +75 -59
- data/test/test_rdl.rb +18 -0
- data/test/test_typecheck.rb +73 -4
- metadata +54 -57
- data/lib/rails_types.rb +0 -1
- data/types/rails-4.2.1/fixnum.rb +0 -3
- data/types/rails-4.2.1/string.rb +0 -3
- data/types/rails-tmp/action_dispatch.rb +0 -406
- data/types/rails-tmp/active_record.rb +0 -406
- data/types/rails-tmp/devise_contracts.rb +0 -216
- 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
|
-
|