aquarium 0.2.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. data/CHANGES +35 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README +66 -20
  4. data/Rakefile +1 -1
  5. data/UPGRADE +5 -0
  6. data/examples/aspect_design_example.rb +5 -4
  7. data/examples/aspect_design_example_spec.rb +6 -5
  8. data/examples/design_by_contract_example.rb +3 -3
  9. data/examples/design_by_contract_example_spec.rb +4 -4
  10. data/examples/method_missing_example.rb +1 -1
  11. data/examples/method_missing_example_spec.rb +2 -2
  12. data/examples/method_tracing_example.rb +3 -3
  13. data/examples/method_tracing_example_spec.rb +6 -6
  14. data/lib/aquarium/aspects/advice.rb +2 -3
  15. data/lib/aquarium/aspects/aspect.rb +100 -246
  16. data/lib/aquarium/aspects/{default_object_handler.rb → default_objects_handler.rb} +7 -6
  17. data/lib/aquarium/aspects/dsl/aspect_dsl.rb +2 -2
  18. data/lib/aquarium/aspects/pointcut.rb +190 -107
  19. data/lib/aquarium/finders/method_finder.rb +120 -34
  20. data/lib/aquarium/finders/type_finder.rb +2 -5
  21. data/lib/aquarium/utils.rb +1 -0
  22. data/lib/aquarium/utils/array_utils.rb +11 -3
  23. data/lib/aquarium/utils/options_utils.rb +74 -0
  24. data/lib/aquarium/utils/type_utils.rb +25 -11
  25. data/lib/aquarium/version.rb +1 -1
  26. data/spec/aquarium/aspects/advice_chain_node_spec.rb +1 -1
  27. data/spec/aquarium/aspects/advice_spec.rb +1 -1
  28. data/spec/aquarium/aspects/aspect_invocation_spec.rb +179 -145
  29. data/spec/aquarium/aspects/aspect_spec.rb +1 -1
  30. data/spec/aquarium/aspects/aspect_with_nested_types_spec.rb +1 -1
  31. data/spec/aquarium/aspects/aspect_with_subtypes_spec.rb +1 -1
  32. data/spec/aquarium/aspects/concurrent_aspects_spec.rb +1 -1
  33. data/spec/aquarium/aspects/concurrent_aspects_with_objects_and_types_spec.rb +1 -1
  34. data/spec/aquarium/aspects/default_objects_handler_spec.rb +147 -0
  35. data/spec/aquarium/aspects/dsl/aspect_dsl_spec.rb +72 -121
  36. data/spec/aquarium/aspects/join_point_spec.rb +1 -1
  37. data/spec/aquarium/aspects/pointcut_and_composition_spec.rb +1 -1
  38. data/spec/aquarium/aspects/pointcut_or_composition_spec.rb +48 -47
  39. data/spec/aquarium/aspects/pointcut_spec.rb +727 -410
  40. data/spec/aquarium/extensions/hash_spec.rb +1 -1
  41. data/spec/aquarium/extensions/regex_spec.rb +1 -1
  42. data/spec/aquarium/extensions/set_spec.rb +1 -1
  43. data/spec/aquarium/extensions/string_spec.rb +1 -1
  44. data/spec/aquarium/extensions/symbol_spec.rb +1 -1
  45. data/spec/aquarium/extras/design_by_contract_spec.rb +1 -1
  46. data/spec/aquarium/finders/finder_result_spec.rb +1 -1
  47. data/spec/aquarium/finders/method_finder_spec.rb +49 -16
  48. data/spec/aquarium/finders/type_finder_spec.rb +1 -1
  49. data/spec/aquarium/finders/type_finder_with_descendents_and_ancestors_spec.rb +16 -1
  50. data/spec/aquarium/utils/array_utils_spec.rb +31 -6
  51. data/spec/aquarium/utils/hash_utils_spec.rb +1 -1
  52. data/spec/aquarium/utils/html_escaper_spec.rb +1 -1
  53. data/spec/aquarium/utils/logic_error_spec.rb +1 -1
  54. data/spec/aquarium/utils/method_utils_spec.rb +1 -1
  55. data/spec/aquarium/utils/name_utils_spec.rb +1 -1
  56. data/spec/aquarium/utils/nil_object_spec.rb +1 -1
  57. data/spec/aquarium/utils/set_utils_spec.rb +1 -1
  58. data/spec/aquarium/utils/type_utils_spec.rb +1 -1
  59. metadata +9 -7
@@ -72,8 +72,7 @@ module Aquarium
72
72
 
73
73
  def last
74
74
  last_node = nil
75
- each { |node| last_node = node unless node.nil? } #; p "<br/>last_node: #{last_node.inspect .gsub(/\</,"&lt;").gsub(/\>/,"&gt;")}"}
76
- # p "<br/><br/>returning last_node: #{last_node.inspect .gsub(/\</,"&lt;").gsub(/\>/,"&gt;")}"
75
+ each { |node| last_node = node unless node.nil? }
77
76
  last_node
78
77
  end
79
78
 
@@ -166,7 +165,7 @@ module Aquarium
166
165
  end
167
166
 
168
167
  def after_raising_exceptions_list
169
- list = make_array(@after_raising)
168
+ list = @after_raising.kind_of?(Set) ? @after_raising.to_a : @after_raising
170
169
  (list.nil? || list.empty? || (list.size == 1 && list[0] == "")) ? [Object] : list
171
170
  end
172
171
  end
@@ -6,7 +6,7 @@ require 'aquarium/aspects/exclusion_handler'
6
6
  require 'aquarium/aspects/join_point'
7
7
  require 'aquarium/aspects/pointcut'
8
8
  require 'aquarium/aspects/pointcut_composition'
9
- require 'aquarium/aspects/default_object_handler'
9
+ require 'aquarium/aspects/default_objects_handler'
10
10
 
11
11
  module Aquarium
12
12
  module Aspects
@@ -23,55 +23,37 @@ module Aquarium
23
23
  class Aspect
24
24
  include Advice
25
25
  include ExclusionHandler
26
- include DefaultObjectHandler
26
+ include DefaultObjectsHandler
27
+ include Aquarium::Aspects
27
28
  include Aquarium::Utils::ArrayUtils
28
29
  include Aquarium::Utils::HashUtils
29
30
  include Aquarium::Utils::HtmlEscaper
31
+ include Aquarium::Utils::OptionsUtils
30
32
 
31
- attr_accessor :verbose, :log
32
33
  attr_reader :specification, :pointcuts, :advice
33
34
 
34
- OTHER_ALLOWED_OPTIONS_SINGULAR = %w[type_and_descendents type_and_ancestors exclude_type_and_descendents exclude_type_and_ancestors].map {|o| o.intern}
35
- OTHER_ALLOWED_OPTIONS_PLURAL = %w[types_and_descendents types_and_ancestors exclude_types_and_descendents exclude_types_and_ancestors].map {|o| o.intern}
35
+ CANONICAL_OPTIONS = Pointcut::CANONICAL_OPTIONS.merge({
36
+ "advice" => %w[action do_action use_advice advise_with invoke call],
37
+ "pointcuts" => %w[pointcut within_pointcuts within_pointcut on_pointcuts on_pointcut],
38
+ "exclude_pointcuts" => %w[exclude_pointcut exclude_on_pointcut exclude_on_pointcuts exclude_within_pointcut exclude_within_pointcuts]
39
+ })
40
+
41
+ ALL_ALLOWED_OPTIONS = CANONICAL_OPTIONS.keys.inject([]) {|ary,i| ary << i << CANONICAL_OPTIONS[i]}.flatten +
42
+ Pointcut::ATTRIBUTE_OPTIONS
36
43
 
37
- ALLOWED_OPTIONS_SINGULAR = %w[advice type object method attribute method_option attribute_option pointcut default_object
38
- exclude_type exclude_object exclude_pointcut exclude_join_point exclude_method exclude_attribute noop].map {|o| o.intern}
39
-
40
- ALLOWED_OPTIONS_PLURAL = OTHER_ALLOWED_OPTIONS_PLURAL + ALLOWED_OPTIONS_SINGULAR.map {|o| "#{o.to_s}s".intern}
41
-
42
- ALLOWED_OPTIONS = ALLOWED_OPTIONS_PLURAL + ALLOWED_OPTIONS_SINGULAR + OTHER_ALLOWED_OPTIONS_SINGULAR
44
+ ALL_ALLOWED_OPTION_SYMBOLS = ALL_ALLOWED_OPTIONS.map {|o| o.intern} + Advice::kinds
43
45
 
44
- ADVICE_OPTIONS_SYNONYMS_MAP = {
45
- :call => :advice,
46
- :invoke => :advice,
47
- :advise_with => :advice
48
- }
49
-
50
- ALLOWED_OPTIONS_SYNONYMS_MAP = {
51
- :type => :types,
52
- :type_and_descendents => :types_and_descendents,
53
- :type_and_ancestors => :types_and_ancestors,
54
- :within_type => :types,
55
- :within_types => :types,
56
- :object => :objects,
57
- :within_object => :objects,
58
- :within_objects => :objects,
59
- :method => :methods,
60
- :within_method => :methods,
61
- :within_methods => :methods,
62
- :attribute => :attributes,
63
- :pointcut => :pointcuts,
64
- :within_pointcut => :pointcuts,
65
- :within_pointcuts => :pointcuts,
66
- :exclude_type => :exclude_types,
67
- :exclude_type_and_descendents => :exclude_types_and_descendents,
68
- :exclude_type_and_ancestors => :exclude_types_and_ancestors,
69
- :exclude_object => :exclude_objects,
70
- :exclude_pointcut => :exclude_pointcuts,
71
- :exclude_join_point => :exclude_join_points,
72
- :exclude_method => :exclude_methods,
73
- :exclude_attribute => :exclude_attributes,
74
- }
46
+ CANONICAL_OPTIONS.keys.each do |name|
47
+ module_eval(<<-EOF, __FILE__, __LINE__)
48
+ def #{name}_given
49
+ @specification[:#{name}]
50
+ end
51
+
52
+ def #{name}_given?
53
+ not (#{name}_given.nil? or #{name}_given.empty?)
54
+ end
55
+ EOF
56
+ end
75
57
 
76
58
  # Aspect.new (:around | :before | :after | :after_returning | :after_raising ) \
77
59
  # (:pointcuts => [...]), | \
@@ -87,21 +69,32 @@ module Aquarium
87
69
  # <tt>:around</tt>::
88
70
  # Invoke the specified advice "around" the join points. It is up to the advice
89
71
  # itself to call <tt>join_point.proceed</tt> (where <tt>join_point</tt> is the
90
- # first argument passed to the advice) if it wants the advised method to actually
72
+ # first option passed to the advice) if it wants the advised method to actually
91
73
  # execute.
92
74
  #
93
75
  # <tt>:before</tt>::
94
- # Invoke the specified advice as before the join point.
76
+ # Invoke the specified advice before the join point.
95
77
  #
96
78
  # <tt>:after</tt>::
97
- # Invoke the specified advice as after the join point either returns successfully
79
+ # Invoke the specified advice after the join point either returns successfully
98
80
  # or raises an exception.
99
81
  #
100
82
  # <tt>:after_returning</tt>::
101
- # Invoke the specified advice as after the join point returns successfully.
83
+ # Invoke the specified advice after the join point returns successfully.
102
84
  #
103
- # <tt>:after_raising</tt>::
104
- # Invoke the specified advice as after the join point raises an exception.
85
+ # <tt>:after_raising [=> exception || [exception_list]]</tt>::
86
+ # Invoke the specified advice after the join point raises one of the specified exceptions.
87
+ # If no exceptions are specified, the advice is invoked after any exception is raised.
88
+ #
89
+ # <tt>:advice => proc</tt>::
90
+ # <tt>:action => proc</tt>::
91
+ # <tt>:do_action => proc</tt>::
92
+ # <tt>:use_advice => proc</tt>::
93
+ # <tt>:advise_with => proc</tt>::
94
+ # <tt>:invoke => proc</tt>::
95
+ # <tt>:call => proc</tt>::
96
+ # The specified advice to be invoked. Only one advice may be specified. If a block is
97
+ # specified, it is used instead.
105
98
  #
106
99
  # <tt>:pointcuts => pointcut || [pointcut_list]</tt>::
107
100
  # <tt>:pointcut => pointcut || [pointcut_list]</tt>::
@@ -110,90 +103,18 @@ module Aquarium
110
103
  # One or an array of Pointcut or JoinPoint objects. Mutually-exclusive with the :types, :objects,
111
104
  # :methods, :attributes, :method_options, and :attribute_options parameters.
112
105
  #
113
- # <tt>:types => type || [type_list]</tt>::
114
- # <tt>:type => type || [type_list]</tt>::
115
- # <tt>:within_type => type || [type_list]</tt>::
116
- # <tt>:within_types => type || [type_list]</tt>::
117
- # One or an array of types, type names and/or type regular expessions to advise.
118
- # All the :types, :objects, :methods, :attributes, :method_options, and :attribute_options
119
- # are used to construct Pointcuts internally.
120
- #
121
- # <tt>:types_and_descendents => type || [type_list]</tt>::
122
- # <tt>:type_and_descendents => type || [type_list]</tt>::
123
- # <tt>:types_and_ancestors => type || [type_list]</tt>::
124
- # <tt>:type_and_ancestors => type || [type_list]</tt>::
125
- # One or an array of types and either their descendents or ancestors.
126
- # If you want both the descendents _and_ ancestors, use both options.
127
- #
128
- # <tt>:objects => object || [object_list]</tt>::
129
- # <tt>:object => object || [object_list]</tt>::
130
- # <tt>:within_object => object || [object_list]</tt>::
131
- # <tt>:within_objects => object || [object_list]</tt>::
132
- # One or an array of objects to advise.
133
- #
134
- # <tt>:default_objects => object || [object_list]</tt>::
135
- # <tt>:default_object => object || [object_list]</tt>::
136
- # An "internal" flag used by the methods that AspectDSL adds to Object. When no object
137
- # or type is specified, the value of :default_objects will be used, if defined. The
138
- # AspectDSL methods set the value to self, so that the user doesn't have to in the
139
- # appropriate contexts, for convenience. This flag is subject to change, so don't
140
- # use it explicitly!
141
- #
142
- # <tt>:methods => method || [method_list]</tt>::
143
- # <tt>:method => method || [method_list]</tt>::
144
- # <tt>:within_method => method || [method_list]</tt>::
145
- # <tt>:within_methods => method || [method_list]</tt>::
146
- # One or an array of methods, method names and/or method regular expessions to match.
147
- # Unless :attributes are specified, defaults to :all, which searches for all public
148
- # instance methods with an implied :method_options => :exclude_ancestor_methods, unless
149
- # :method_options provided explicitly.
150
- #
151
- # <tt>:method_options => [options]</tt>::
152
- # One or more options supported by Aquarium::Finders::MethodFinder. Defaults to :exclude_ancestor_methods
106
+ # <tt>:noop</tt>::
107
+ # Does not actually advise any join points. Useful for testing.
153
108
  #
154
- # <tt>:attributes => attribute || [attribute_list]</tt>::
155
- # <tt>:attribute => attribute || [attribute_list]</tt>::
156
- # <tt>:within_attribute => attribute || [attribute_list]</tt>::
157
- # <tt>:within_attributes => attribute || [attribute_list]</tt>::
158
- # One or an array of attribute names and/or regular expessions to match.
159
- # This is syntactic sugar for the corresponding attribute readers and/or writers
160
- # methods, as specified using the <tt>:attrbute_options. Any matches will be
161
- # joined with the matched :methods.</tt>.
162
- #
163
- # <tt>:attribute_options => [options]</tt>::
164
- # One or more of <tt>:readers</tt>, <tt>:reader</tt> (synonymous),
165
- # <tt>:writers</tt>, and/or <tt>:writer</tt> (synonymous). By default, both
166
- # readers and writers are matched.
167
- #
168
- # <tt>:exclude_pointcuts => pc || [pc_list]</tt>::
169
- # <tt>:exclude_pointcut => pc || [pc_list]</tt>::
170
- # <tt>:exclude_join_points => jp || [jp_list]</tt>::
171
- # <tt>:exclude_join_point => jp || [jp_list]</tt>::
172
- # <tt>:exclude_types => type || [type_list]</tt>::
173
- # <tt>:exclude_types => type || [type_list]</tt>::
174
- # <tt>:exclude_type => type || [type_list]</tt>::
175
- # <tt>:exclude_objects => object || [object_list]</tt>::
176
- # <tt>:exclude_object => object || [object_list]</tt>::
177
- # <tt>:exclude_methods => method || [method_list]</tt>::
178
- # <tt>:exclude_method => method || [method_list]</tt>::
179
- # <tt>:exclude_attributes => attribute || [attribute_list]</tt>::
180
- # <tt>:exclude_attribute => attribute || [attribute_list]</tt>::
181
- # Exclude the specified "things" from the matched join points.
182
- #
183
- # <tt>:exclude_types_and_descendents => type || [type_list]</tt>::
184
- # <tt>:exclude_type_and_descendents => type || [type_list]</tt>::
185
- # <tt>:exclude_types_and_ancestors => type || [type_list]</tt>::
186
- # <tt>:exclude_type_and_ancestors => type || [type_list]</tt>::
187
- # Exclude the specified types and their descendents, ancestors.
188
- # If you want to exclude both the descendents _and_ ancestors, use both options.
189
- #
190
- # The actual advice to execute is the block or you can pass a Proc using :advice => proc.
191
- # Note that the advice takes a join_point argument, which will include a non-nil
192
- # JoinPoint#Context object, the object being executed, and the argument list to the method.
109
+ # It also accepts all the same options that Pointcut accepts, including the synonyms for :types,
110
+ # :methods, etc.
193
111
  def initialize *options, &block
194
- process_input options, &block
112
+ @first_option_that_was_method = []
113
+ opts = rationalize options
114
+ init_specification opts, canonical_options, &block
195
115
  init_pointcuts
196
- return if specification[:noop]
116
+ validate_specification
117
+ return if noop
197
118
  advise_join_points
198
119
  end
199
120
 
@@ -205,8 +126,15 @@ module Aquarium
205
126
  get_jps :join_points_not_matched
206
127
  end
207
128
 
129
+ def canonical_options
130
+ CANONICAL_OPTIONS
131
+ end
132
+ def all_allowed_option_symbols
133
+ ALL_ALLOWED_OPTION_SYMBOLS + @first_option_that_was_method
134
+ end
135
+
208
136
  def unadvise
209
- return if @specification[:noop]
137
+ return if noop
210
138
  @pointcuts.each do |pointcut|
211
139
  interesting_join_points(pointcut).each do |join_point|
212
140
  remove_advice_for_aspect_at join_point
@@ -233,24 +161,24 @@ module Aquarium
233
161
 
234
162
  protected
235
163
 
236
- def process_input options, &block
237
- @original_options = options.flatten
238
- make_specification options, &block
239
- @verbose = @specification[:verbose] || false
240
- @log = @specification[:log] || ""
241
- end
242
-
243
- def make_specification options, &block
244
- opts = rationalize_parameters options.flatten.dup
245
- # For non-hash inputs, use an empty string for the value
246
- @specification = Aquarium::Utils::MethodUtils.method_args_to_hash(*opts) {|option| ""}
247
- use_default_object_if_defined unless some_type_or_pc_option_given?
248
- use_first_nonadvice_symbol_as_method(opts) unless methods_given?
164
+ def rationalize options
165
+ return {} if options.nil? or options.empty?
166
+ return options if options.size > 1
167
+ # remove [] wrapping if we're wrapping a single hash element
168
+ return (options.first.kind_of?(Hash) or options.first.kind_of?(Array)) ? options.first : options
169
+ end
170
+
171
+ def init_type_specific_specification original_options, options_hash, &block
172
+ Advice.kinds.each do |kind|
173
+ @specification[kind] = Set.new(make_array(options_hash[kind])) if options_hash[kind]
174
+ end
175
+ @specification.merge! Pointcut.make_attribute_reading_writing_options(options_hash)
176
+ use_default_objects_if_defined unless some_type_or_pc_option_given?
177
+ use_first_nonadvice_symbol_as_method(original_options) unless methods_given?
249
178
  calculate_excluded_types
250
179
  @advice = determine_advice block
251
- validate_specification
252
180
  end
253
-
181
+
254
182
  def calculate_excluded_types
255
183
  type_finder_options = {}
256
184
  %w[types types_and_ancestors types_and_descendents].each do |opt|
@@ -261,45 +189,32 @@ module Aquarium
261
189
  end
262
190
 
263
191
  def determine_advice block
264
- # There can be only one advice; take the last one...
265
- block || (@specification[:advice].kind_of?(Array) ? @specification[:advice].last : @specification[:advice])
192
+ # There can be only one advice; take any one in the set; options validation will raise if there is more than one.
193
+ block || (@specification[:advice].to_a.first)
266
194
  end
267
195
 
268
196
  def init_pointcuts
269
197
  pointcuts = []
270
198
  if pointcuts_given?
271
199
  pointcuts_given.each do |pointcut|
272
- if pointcut.kind_of?(Aquarium::Aspects::Pointcut)
200
+ if pointcut.kind_of? Pointcut
273
201
  pointcuts << pointcut
274
- elsif pointcut.kind_of?(Aquarium::Aspects::JoinPoint)
275
- pointcuts << Aquarium::Aspects::Pointcut.new(:join_point => pointcut)
202
+ elsif pointcut.kind_of? JoinPoint
203
+ pointcuts << Pointcut.new(:join_point => pointcut)
276
204
  else # a hash of Pointcut.new options?
277
- pointcuts << Aquarium::Aspects::Pointcut.new(pointcut)
205
+ pointcuts << Pointcut.new(pointcut)
278
206
  end
279
207
  end
280
208
  else
281
209
  pc_options = {}
282
- ALLOWED_OPTIONS_PLURAL.each do |option|
283
- next if pointcut_new_doesnt_accept? option
284
- self.instance_eval(<<-EOF, __FILE__, __LINE__)
285
- pc_options[:#{option}] = #{option}_given if #{option}_given?
286
- EOF
210
+ Pointcut::ALL_ALLOWED_OPTION_SYMBOLS.each do |pc_option|
211
+ pc_options[pc_option] = @specification[pc_option] unless @specification[pc_option].nil?
287
212
  end
288
- pointcuts << Aquarium::Aspects::Pointcut.new(pc_options)
213
+ pointcuts << Pointcut.new(pc_options)
289
214
  end
290
215
  @pointcuts = Set.new(remove_excluded_join_points_and_empty_pointcuts(pointcuts))
291
216
  end
292
217
 
293
- def pointcut_new_doesnt_accept? option
294
- case option
295
- when :advices: true
296
- when :pointcuts: true
297
- when :default_objects: true
298
- when :noops: true
299
- else false
300
- end
301
- end
302
-
303
218
  def remove_excluded_join_points_and_empty_pointcuts pointcuts
304
219
  pointcuts.reject do |pc|
305
220
  pc.join_points_matched.delete_if do |jp|
@@ -315,7 +230,7 @@ module Aquarium
315
230
  interesting_join_points(pointcut).each do |join_point|
316
231
  attr_name = Aspect.make_advice_chain_attr_sym(join_point)
317
232
  add_advice_framework(join_point) if need_advice_framework?(join_point)
318
- Aquarium::Aspects::Advice.sort_by_priority_order(specified_advice_kinds).reverse.each do |advice_kind|
233
+ Advice.sort_by_priority_order(specified_advice_kinds).reverse.each do |advice_kind|
319
234
  add_advice_to_chain join_point, advice_kind, advice
320
235
  end
321
236
  end
@@ -341,7 +256,7 @@ module Aquarium
341
256
  :next_node => start_of_advice_chain,
342
257
  :static_join_point => join_point})
343
258
  # New node is new start of chain.
344
- Aspect.set_advice_chain(join_point, Aquarium::Aspects::AdviceChainNodeFactory.make_node(options))
259
+ Aspect.set_advice_chain(join_point, AdviceChainNodeFactory.make_node(options))
345
260
  end
346
261
 
347
262
  def get_jps which_jps
@@ -370,7 +285,7 @@ module Aquarium
370
285
  type_to_advise = Aspect.type_to_advise_for join_point
371
286
  # Note: Must set advice chain, a class variable on the type we're advising, FIRST.
372
287
  # Otherwise the class_eval that follows will assume the @@ advice chain belongs to Aspect!
373
- Aspect.set_advice_chain join_point, Aquarium::Aspects::AdviceChainNodeFactory.make_node(
288
+ Aspect.set_advice_chain join_point, AdviceChainNodeFactory.make_node(
374
289
  :aspect => nil, # Belongs to all aspects that might advise this join point!
375
290
  :advice_kind => :none,
376
291
  :alias_method_name => alias_method_name,
@@ -529,7 +444,7 @@ module Aquarium
529
444
  end
530
445
 
531
446
  def some_type_or_pc_option_given?
532
- pointcuts_given? or some_type_option_given? or objects_given? #or default_objects_given?
447
+ pointcuts_given? or some_type_option_given? or objects_given?
533
448
  end
534
449
 
535
450
  def some_type_option_given?
@@ -545,42 +460,11 @@ module Aquarium
545
460
  end
546
461
 
547
462
  def specified_advice_kinds
548
- @specification.keys.select do |key|
549
- Aquarium::Aspects::Advice.kinds.include? key
550
- end
463
+ Advice.kinds & @specification.keys
551
464
  end
552
465
 
553
- def rationalize_parameters opts
554
- return opts unless opts.last.kind_of?(Hash)
555
- hash = opts.pop.dup
556
- opts.push hash
557
- ALLOWED_OPTIONS_SYNONYMS_MAP.each do |syn, actual|
558
- if hash.has_key? syn
559
- hash[actual] = make_array(hash[actual], hash[syn])
560
- hash.delete syn
561
- end
562
- end
563
- # Only one advice argument allowed.
564
- unless hash.has_key?(:advice)
565
- ADVICE_OPTIONS_SYNONYMS_MAP.each do |syn, actual|
566
- if hash.has_key? syn
567
- hash[actual] = hash[syn]
568
- hash.delete syn
569
- end
570
- end
571
- end
572
- ALLOWED_OPTIONS_PLURAL.each do |opt|
573
- case opt
574
- when :advices: next
575
- when :noops: next
576
- end
577
- hash[opt] = Set.new(make_array(hash[opt]))
578
- end
579
- opts
580
- end
581
-
582
466
  def validate_specification
583
- bad_options("One of #{Aquarium::Aspects::Advice.kinds.inspect} is required.") unless advice_kinds_given?
467
+ bad_options("One of #{Advice.kinds.inspect} is required.") unless advice_kinds_given?
584
468
  bad_options(":around can't be used with :before.") if around_given_with? :before
585
469
  bad_options(":around can't be used with :after.") if around_given_with? :after
586
470
  bad_options(":around can't be used with :after_returning.") if around_given_with? :after_returning
@@ -594,34 +478,20 @@ module Aquarium
594
478
  if pointcuts_given? and (some_type_option_given? or objects_given?)
595
479
  bad_options("Can't specify both :pointcut(s) and one or more of :type(s), and/or :object(s).")
596
480
  end
597
- @specification.each_key do |parameter|
598
- check_parameter parameter
599
- end
600
- if @advice.nil? && @specification[:noop].nil?
601
- bad_options "No advice block nor :advice argument was given."
602
- end
603
- if @advice.arity == -2
604
- bad_options "It appears that your advice parameter list is the obsolete format |jp, *args|. The correct format is |jp, object, *args|"
481
+ unless noop
482
+ if (not @specification[:advice].nil?) && @specification[:advice].size > 1
483
+ bad_options "You can only specify one advice object for the :advice option."
484
+ end
485
+ if @advice.nil?
486
+ bad_options "No advice block nor :advice option was given."
487
+ elsif @advice.arity == -2
488
+ bad_options "It appears that your advice parameter list is the obsolete format |jp, *args|. The correct format is |jp, object, *args|"
489
+ end
605
490
  end
606
491
  end
607
492
 
608
- def check_parameter parameter
609
- bad_options("Unrecognized parameter: :#{parameter}") unless is_valid_parameter(parameter)
610
- end
611
-
612
- def is_valid_parameter key
613
- ALLOWED_OPTIONS.include?(key) || ALLOWED_OPTIONS_SYNONYMS_MAP.keys.include?(key) ||
614
- ADVICE_OPTIONS_SYNONYMS_MAP.keys.include?(key) || KINDS_IN_PRIORITY_ORDER.include?(key) ||
615
- key == :exclude_types_calculated ||
616
- parameter_is_a_method_name?(key) # i.e., use_first_nonadvice_symbol_as_method
617
- end
618
-
619
- def parameter_is_a_method_name? name
620
- @specification[:methods].include? name
621
- end
622
-
623
493
  def advice_kinds_given
624
- Aquarium::Aspects::Advice.kinds.inject([]) {|ary, kind| ary << @specification[kind] if @specification[kind]; ary}
494
+ Advice.kinds.inject([]) {|ary, kind| ary << @specification[kind] if @specification[kind]; ary}
625
495
  end
626
496
 
627
497
  def advice_kinds_given?
@@ -636,29 +506,13 @@ module Aquarium
636
506
  EOF
637
507
  end
638
508
 
639
- ALLOWED_OPTIONS_PLURAL.each do |name|
640
- case name
641
- when :advices : next
642
- when :default_objects : next
643
- when :noops : next
644
- end
645
- class_eval(<<-EOF, __FILE__, __LINE__)
646
- def #{name}_given
647
- make_array(@specification[:#{name}])
648
- end
649
-
650
- def #{name}_given?
651
- not (#{name}_given.nil? or #{name}_given.empty?)
652
- end
653
- EOF
654
- end
655
-
656
509
  def use_first_nonadvice_symbol_as_method options
657
510
  2.times do |i|
658
511
  if options.size >= i+1
659
512
  sym = options[i]
660
- if sym.kind_of?(Symbol) && !Aquarium::Aspects::Advice::kinds.include?(sym)
513
+ if sym.kind_of?(Symbol) && !Advice::kinds.include?(sym)
661
514
  @specification[:methods] = Set.new([sym])
515
+ @first_option_that_was_method << sym
662
516
  return
663
517
  end
664
518
  end