jinx 2.1.1 → 2.1.2

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 (43) hide show
  1. data/History.md +4 -0
  2. data/lib/jinx.rb +0 -1
  3. data/lib/jinx/cli/application.rb +3 -3
  4. data/lib/jinx/cli/command.rb +1 -1
  5. data/lib/jinx/helpers/array.rb +3 -3
  6. data/lib/jinx/helpers/associative.rb +41 -0
  7. data/lib/jinx/helpers/collections.rb +0 -1
  8. data/lib/jinx/helpers/enumerable.rb +5 -2
  9. data/lib/jinx/helpers/hash.rb +1 -1
  10. data/lib/jinx/helpers/hashable.rb +1 -7
  11. data/lib/jinx/helpers/inflector.rb +1 -1
  12. data/lib/jinx/helpers/log.rb +63 -11
  13. data/lib/jinx/helpers/math.rb +20 -11
  14. data/lib/jinx/helpers/options.rb +4 -4
  15. data/lib/jinx/helpers/pretty_print.rb +0 -1
  16. data/lib/jinx/helpers/transitive_closure.rb +1 -1
  17. data/lib/jinx/helpers/uniquifier.rb +50 -17
  18. data/lib/jinx/helpers/visitor.rb +3 -3
  19. data/lib/jinx/import/java.rb +1 -1
  20. data/lib/jinx/importer.rb +3 -2
  21. data/lib/jinx/metadata/attribute_enumerator.rb +1 -1
  22. data/lib/jinx/metadata/dependency.rb +3 -3
  23. data/lib/jinx/metadata/introspector.rb +46 -42
  24. data/lib/jinx/metadata/inverse.rb +17 -1
  25. data/lib/jinx/metadata/java_property.rb +10 -10
  26. data/lib/jinx/metadata/propertied.rb +19 -16
  27. data/lib/jinx/metadata/property.rb +11 -11
  28. data/lib/jinx/resource.rb +86 -14
  29. data/lib/jinx/resource/match_visitor.rb +7 -5
  30. data/lib/jinx/resource/merge_visitor.rb +3 -10
  31. data/lib/jinx/resource/mergeable.rb +16 -16
  32. data/lib/jinx/resource/reference_enumerator.rb +0 -1
  33. data/lib/jinx/resource/reference_path_visitor.rb +1 -1
  34. data/lib/jinx/resource/reference_visitor.rb +5 -6
  35. data/lib/jinx/resource/unique.rb +1 -1
  36. data/lib/jinx/version.rb +1 -1
  37. data/test/lib/jinx/helpers/associative_test.rb +26 -0
  38. data/test/lib/jinx/helpers/collections_test.rb +14 -2
  39. data/test/lib/jinx/helpers/uniquifier_test.rb +11 -0
  40. metadata +9 -8
  41. data/Gemfile.lock +0 -27
  42. data/lib/jinx/helpers/error.rb +0 -15
  43. data/lib/jinx/helpers/key_transformer_hash.rb +0 -43
@@ -196,7 +196,7 @@ module Jinx
196
196
  # @yieldparam children the nodes slated by this Visitor to visit next
197
197
  # @raise [ArgumentError] if a block is not given to this method
198
198
  def filter
199
- Jinx.fail(ArgumentError, "A filter block is not given to the visitor filter method") unless block_given?
199
+ raise ArgumentError.new("A filter block is not given to the visitor filter method") unless block_given?
200
200
  Visitor.new(@options) { |node| yield(node, node_children(node)) }
201
201
  end
202
202
 
@@ -319,7 +319,7 @@ module Jinx
319
319
  def visit(*nodes)
320
320
  if nodes.size == 1 then
321
321
  nodes = nodes.first
322
- Jinx.fail(ArgumentError, "Sync visitor requires a pair of entry nodes") unless nodes.size == 2
322
+ raise ArgumentError.new("Sync visitor requires a pair of entry nodes") unless nodes.size == 2
323
323
  end
324
324
  super(nodes)
325
325
  end
@@ -331,7 +331,7 @@ module Jinx
331
331
  def to_enum(*nodes)
332
332
  if nodes.size == 1 then
333
333
  nodes = nodes.first
334
- Jinx.fail(ArgumentError, "Sync visitor requires a pair of entry nodes") unless nodes.size == 2
334
+ raise ArgumentError.new("Sync visitor requires a pair of entry nodes") unless nodes.size == 2
335
335
  end
336
336
  super(nodes)
337
337
  end
@@ -91,7 +91,7 @@ module Java
91
91
  # merge return a new collection.
92
92
  def merge(other)
93
93
  return self if other.nil?
94
- Jinx.fail(ArgumentError, "Merge argument must be enumerable: #{other}") unless Enumerable === other
94
+ raise ArgumentError.new("Merge argument must be enumerable: #{other}") unless Enumerable === other
95
95
  other.each { |item| self << item }
96
96
  self
97
97
  end
@@ -69,6 +69,7 @@ module Jinx
69
69
 
70
70
  # @param [String] the module name to resolve in the context of this module
71
71
  # @return [Module] the corresponding module
72
+ # @raise [NameError] if the name cannot be resolved
72
73
  def module_for_name(name)
73
74
  begin
74
75
  # Incrementally resolve the module.
@@ -97,7 +98,7 @@ module Jinx
97
98
  begin
98
99
  eval "java_package Java::#{pkg}"
99
100
  rescue Exception => e
100
- Jinx.fail(ArgumentError, "#{self} Java package #{pkg} not found - #{$!}")
101
+ raise ArgumentError.new("#{self} Java package #{pkg} not found - #{$!}")
101
102
  end
102
103
  end
103
104
  # The introspected classes.
@@ -221,7 +222,7 @@ module Jinx
221
222
  mod = klass.parent_module
222
223
  klass.each_property do |prop|
223
224
  ref = prop.type
224
- if ref.nil? then Jinx.fail(MetadataError, "#{self} #{prop} domain type is unknown.") end
225
+ if ref.nil? then raise MetadataError.new("#{self} #{prop} domain type is unknown.") end
225
226
  unless @introspected.include?(ref) or ref.parent_module != mod then
226
227
  logger.debug { "Introspecting #{qp} #{prop} reference #{ref.qp}..." }
227
228
  add_metadata(ref)
@@ -10,7 +10,7 @@ module Jinx
10
10
  # @yieldparam [Property] the metadata for the standard attribute
11
11
  # @raise [ArgumentError] if a parameter is missing
12
12
  def initialize(hash, &filter)
13
- Jinx.fail(ArgumentError, "Attribute filter missing hash argument") if hash.nil?
13
+ raise ArgumentError.new("Attribute filter missing hash argument") if hash.nil?
14
14
  @hash = hash
15
15
  @filter = block_given? ? filter : Proc.new { true }
16
16
  end
@@ -115,11 +115,11 @@ module Jinx
115
115
  # @raise [ValidationError] if the inverse is nil
116
116
  def add_owner(klass, inverse, attribute=nil)
117
117
  if inverse.nil? then
118
- Jinx.fail(ValidationError, "Owner #{klass.qp} missing dependent attribute for dependent #{qp}")
118
+ raise ValidationError.new("Owner #{klass.qp} missing dependent attribute for dependent #{qp}")
119
119
  end
120
120
  logger.debug { "Adding #{qp} owner #{klass.qp}#{' attribute ' + attribute.to_s if attribute} with inverse #{inverse}..." }
121
121
  if @owner_prop_hash then
122
- Jinx.fail(MetadataError, "Can't add #{qp} owner #{klass.qp} after dependencies have been accessed")
122
+ raise MetadataError.new("Can't add #{qp} owner #{klass.qp} after dependencies have been accessed")
123
123
  end
124
124
 
125
125
  # detect the owner attribute, if necessary
@@ -175,7 +175,7 @@ module Jinx
175
175
  if hash.include?(otype) then
176
176
  oa = hash[otype]
177
177
  unless oa.nil? then
178
- Jinx.fail(MetadataError, "Cannot set #{qp} owner attribute to #{attribute} since it is already set to #{oa}")
178
+ raise MetadataError.new("Cannot set #{qp} owner attribute to #{attribute} since it is already set to #{oa}")
179
179
  end
180
180
  hash[otype] = prop
181
181
  else
@@ -2,6 +2,7 @@ require 'jinx/helpers/module'
2
2
  require 'jinx/import/java'
3
3
  require 'jinx/metadata/propertied'
4
4
  require 'jinx/metadata/java_property'
5
+ require 'jinx/helpers/math'
5
6
 
6
7
  module Jinx
7
8
  # Meta-data mix-in to infer attribute meta-data from Java properties.
@@ -77,68 +78,71 @@ module Jinx
77
78
  return
78
79
  end
79
80
  # the standard underscore lower-case attributes
80
- ja = add_java_property(pd).attribute
81
+ prop = add_java_property(pd)
81
82
  # delegate the standard attribute accessors to the attribute accessors
82
- alias_property_accessors(ja, pd.name)
83
+ alias_property_accessors(prop)
83
84
  # add special wrappers
84
- wrap_java_property(ja, pd)
85
+ wrap_java_property(prop)
85
86
  # create Ruby alias for boolean, e.g. alias :empty? for :empty
86
87
  if pd.property_type.name[/\w+$/].downcase == 'boolean' then
87
- # strip leading is_, if any, before appending question mark
88
- aliaz = ja.to_s[/^(is_)?(\w+)/, 2] << '?'
89
- delegate_to_attribute(aliaz, ja)
88
+ # Strip the leading is_, if any, before appending a question mark.
89
+ aliaz = prop.to_s[/^(is_)?(\w+)/, 2] << '?'
90
+ delegate_to_property(aliaz, prop)
90
91
  end
91
92
  end
92
93
 
93
- # Adds a filter to the attribute access method for the property descriptor pd if it is a String or Date.
94
- def wrap_java_property(attribute, pd)
94
+ # Adds a filter to the given property access methods if it is a String or Date.
95
+ def wrap_java_property(property)
96
+ pd = property.property_descriptor
95
97
  if pd.property_type == Java::JavaLang::String.java_class then
96
- wrap_java_string_attribute(attribute, pd)
98
+ wrap_java_string_property(property)
97
99
  elsif pd.property_type == Java::JavaUtil::Date.java_class then
98
- wrap_java_date_attribute(attribute, pd)
100
+ wrap_java_date_property(property)
99
101
  end
100
102
  end
101
103
 
102
- # Adds a to_s filter to this Class's String attribute access methods.
103
- def wrap_java_string_attribute(attribute, pd)
104
+ # Adds a number -> string filter to the given String property Ruby access methods.
105
+ def wrap_java_string_property(property)
106
+ ra, wa = property.accessors
107
+ jra, jwa = property.java_accessors
104
108
  # filter the attribute writer
105
- awtr = "#{attribute}=".to_sym
106
- pwtr = pd.write_method.name.to_sym
107
- define_method(awtr) do |value|
108
- stdval = value.to_s unless value.nil_or_empty?
109
- send(pwtr, stdval)
109
+ define_method(wa) do |value|
110
+ stdval = Math.numeric?(value) ? value.to_s : value
111
+ send(jwa, stdval)
110
112
  end
111
- logger.debug { "Filtered #{qp} #{awtr} method with non-String -> String converter." }
113
+ logger.debug { "Filtered #{qp} #{wa} method with non-String -> String converter." }
112
114
  end
113
115
 
114
- # Adds a date parser filter to this Class's Date attribute access methods.
115
- def wrap_java_date_attribute(attribute, pd)
116
+ # Adds a Java-Ruby Date filter to the given Date property Ruby access methods.
117
+ # The reader returns a Ruby date. The writer sets a Java date.
118
+ def wrap_java_date_property(property)
119
+ ra, wa = property.accessors
120
+ jra, jwa = property.java_accessors
121
+
116
122
  # filter the attribute reader
117
- prdr = pd.read_method.name.to_sym
118
- define_method(attribute) do
119
- value = send(prdr)
123
+ define_method(ra) do
124
+ value = send(jra)
120
125
  Java::JavaUtil::Date === value ? value.to_ruby_date : value
121
126
  end
122
127
 
123
128
  # filter the attribute writer
124
- awtr = "#{attribute}=".to_sym
125
- pwtr = pd.write_method.name.to_sym
126
- define_method(awtr) do |value|
129
+ define_method(wa) do |value|
127
130
  value = Java::JavaUtil::Date.from_ruby_date(value) if ::Date === value
128
- send(pwtr, value)
131
+ send(jwa, value)
129
132
  end
130
133
 
131
- logger.debug { "Filtered #{qp} #{attribute} and #{awtr} methods with Java Date <-> Ruby Date converter." }
134
+ logger.debug { "Filtered #{qp} #{ra} and #{wa} methods with Java Date <-> Ruby Date converter." }
132
135
  end
133
136
 
134
- # Aliases the methods _aliaz_ and _aliaz=_ to _attribute_ and _attribute=_, resp.,
135
- # where _attribute_ is the Java attribute name for the attribute.
136
- def alias_property_accessors(aliaz, attribute)
137
+ # Aliases the given Ruby property reader and writer to its underlying Java property reader and writer, resp.
138
+ #
139
+ # @param [Property] property the property to alias
140
+ def alias_property_accessors(property)
141
+ # the Java reader and writer accessor method symbols
142
+ jra, jwa = property.java_accessors
137
143
  # strip the Java reader and writer is/get/set prefix and make a symbol
138
- prdr, pwtr = property(attribute).property_accessors
139
- alias_method(aliaz, prdr)
140
- writer = "#{aliaz}=".to_sym
141
- alias_method(writer, pwtr)
144
+ alias_method(property.reader, jra)
145
+ alias_method(property.writer, jwa)
142
146
  end
143
147
 
144
148
  # Makes a standard attribute for the given property descriptor.
@@ -154,7 +158,7 @@ module Jinx
154
158
  pa = prop.attribute
155
159
  # the Java property name as an attribute symbol
156
160
  ja = pd.name.to_sym
157
- delegate_to_attribute(ja, pa) unless pa == ja
161
+ delegate_to_property(ja, prop) unless prop.reader == ja
158
162
  prop
159
163
  end
160
164
 
@@ -168,12 +172,12 @@ module Jinx
168
172
  # _attribute=_ accessor methods, resp.
169
173
  # Calling rather than aliasing the attribute accessor allows the aliaz accessor to
170
174
  # reflect a change to the attribute accessor.
171
- def delegate_to_attribute(aliaz, attribute)
172
- if aliaz == attribute then Jinx.fail(MetadataError, "Cannot delegate #{self} #{aliaz} to itself.") end
173
- rdr, wtr = property(attribute).accessors
174
- define_method(aliaz) { send(rdr) }
175
- define_method("#{aliaz}=".to_sym) { |value| send(wtr, value) }
176
- register_property_alias(aliaz, attribute)
175
+ def delegate_to_property(aliaz, property)
176
+ ra, wa = property.accessors
177
+ if aliaz == ra then raise MetadataError.new("Cannot delegate #{self} #{aliaz} to itself.") end
178
+ define_method(aliaz) { send(ra) }
179
+ define_method("#{aliaz}=".to_sym) { |value| send(wa, value) }
180
+ register_property_alias(aliaz, property.attribute)
177
181
  end
178
182
  end
179
183
  end
@@ -56,7 +56,7 @@ module Jinx
56
56
  end
57
57
  # This class must be the same as or a subclass of the inverse attribute type.
58
58
  unless self <= inv_prop.type then
59
- Jinx.fail(TypeError, "Cannot set #{qp}.#{pa} inverse to #{prop.type.qp}.#{pa} with incompatible type #{inv_prop.type.qp}")
59
+ raise TypeError.new("Cannot set #{qp}.#{pa} inverse to #{prop.type.qp}.#{pa} with incompatible type #{inv_prop.type.qp}")
60
60
  end
61
61
  # Set the inverse in the attribute metadata.
62
62
  prop.inverse = inverse
@@ -70,6 +70,22 @@ module Jinx
70
70
  end
71
71
  logger.debug { "Set #{qp}.#{pa} inverse to #{inverse}." }
72
72
  end
73
+
74
+ # Clears the property inverse, if there is one.
75
+ def clear_inverse(property)
76
+ # the inverse property
77
+ ip = property.inverse_property || return
78
+ # If the property is a collection and the inverse is not, then delegate to
79
+ # the inverse.
80
+ if property.collection? then
81
+ return ip.declarer.clear_inverse(ip) unless ip.collection?
82
+ else
83
+ # Restore the property reader and writer to the Java reader and writer, resp.
84
+ alias_property_accessors(property)
85
+ end
86
+ # Unset the inverse.
87
+ property.inverse = nil
88
+ end
73
89
 
74
90
  # Detects an unambiguous attribute which refers to the given referencing class.
75
91
  # If there is exactly one attribute with the given return type, then that attribute is chosen.
@@ -9,7 +9,7 @@ module Jinx
9
9
  attr_reader :property_descriptor
10
10
 
11
11
  # This property's Java property [reader, writer] accessors, e.g. +[:getActivityStatus, :setActivityStatus]+.
12
- attr_reader :property_accessors
12
+ attr_reader :java_accessors
13
13
 
14
14
  # Creates a Ruby Property symbol corresponding to the given Ruby Java class wrapper klazz
15
15
  # and Java property_descriptor.
@@ -34,34 +34,34 @@ module Jinx
34
34
  @property_descriptor = pd
35
35
  # deficient Java introspector does not recognize 'is' prefix for a Boolean property
36
36
  rm = declarer.property_read_method(pd)
37
- Jinx.fail(ArgumentError, "Property does not have a read method: #{declarer.qp}.#{pd.name}") unless rm
37
+ raise ArgumentError.new("Property does not have a read method: #{declarer.qp}.#{pd.name}") unless rm
38
38
  reader = rm.name.to_sym
39
39
  unless declarer.method_defined?(reader) then
40
40
  reader = "is#{reader.to_s.capitalize_first}".to_sym
41
41
  unless declarer.method_defined?(reader) then
42
- Jinx.fail(ArgumentError, "Reader method not found for #{declarer} property #{pd.name}")
42
+ raise ArgumentError.new("Reader method not found for #{declarer} property #{pd.name}")
43
43
  end
44
44
  end
45
45
  unless pd.write_method then
46
- Jinx.fail(ArgumentError, "Property does not have a write method: #{declarer.qp}.#{pd.name}")
46
+ raise ArgumentError.new("Property does not have a write method: #{declarer.qp}.#{pd.name}")
47
47
  end
48
48
  writer = pd.write_method.name.to_sym
49
49
  unless declarer.method_defined?(writer) then
50
- Jinx.fail(ArgumentError, "Writer method not found for #{declarer} property #{pd.name}")
50
+ raise ArgumentError.new("Writer method not found for #{declarer} property #{pd.name}")
51
51
  end
52
- @property_accessors = [reader, writer]
52
+ @java_accessors = [reader, writer]
53
53
  qualify(:collection) if collection_java_class?
54
54
  @type = infer_type
55
55
  end
56
56
 
57
57
  # @return [Symbol] the JRuby wrapper method for the Java property reader
58
- def property_reader
59
- property_accessors.first
58
+ def java_reader
59
+ java_accessors.first
60
60
  end
61
61
 
62
62
  # @return [Symbol] the JRuby wrapper method for the Java property writer
63
- def property_writer
64
- property_accessors.last
63
+ def java_writer
64
+ java_accessors.last
65
65
  end
66
66
 
67
67
  # Returns a lower-case, underscore symbol for the given property_name.
@@ -15,13 +15,10 @@ module Jinx
15
15
 
16
16
  # Returns whether this class has an attribute with the given symbol.
17
17
  #
18
- # @param [Symbol] symbol the potential attribute
18
+ # @param [String, Symbol] name the potential attribute
19
19
  # @return [Boolean] whether there is a corresponding attribute
20
- def property_defined?(symbol)
21
- unless Symbol === symbol then
22
- Jinx.fail(ArgumentError, "Property argument #{symbol.qp} of type #{symbol.class.qp} is not a symbol")
23
- end
24
- !!@alias_std_prop_map[symbol.to_sym]
20
+ def property_defined?(name)
21
+ !!@alias_std_prop_map[name.to_sym]
25
22
  end
26
23
 
27
24
  # Adds the given attribute to this Class.
@@ -80,7 +77,8 @@ module Jinx
80
77
  @prop_hash.each_value(&block)
81
78
  end
82
79
 
83
- # @return the Property for the given attribute symbol or alias
80
+ # @param [Symbol] attribute the property attribute symbol or alias
81
+ # @return [Property] the corresponding property
84
82
  # @raise [NameError] if the attribute is not recognized
85
83
  def property(attribute)
86
84
  # Simple and predominant case is that the attribute is a standard attribute.
@@ -88,7 +86,7 @@ module Jinx
88
86
  prop = @prop_hash[attribute] || @prop_hash[standard_attribute(attribute)]
89
87
  # If not found, then raise a NameError.
90
88
  if prop.nil? then
91
- Jinx.fail(NameError, "#{name.demodulize} attribute not found: #{attribute}")
89
+ raise NameError.new("#{name.demodulize} attribute not found: #{attribute}")
92
90
  end
93
91
  prop
94
92
  end
@@ -116,9 +114,9 @@ module Jinx
116
114
  # @raise [NameError] if the attribute is not found
117
115
  def standard_attribute(name_or_alias)
118
116
  if name_or_alias.nil? then
119
- Jinx.fail(ArgumentError, "#{qp} standard attribute call is missing the attribute name/alias parameter")
117
+ raise ArgumentError.new("#{qp} standard attribute call is missing the attribute name/alias parameter")
120
118
  end
121
- @alias_std_prop_map[name_or_alias.to_sym] or Jinx.fail(NameError, "#{self} attribute not found: #{name_or_alias}")
119
+ @alias_std_prop_map[name_or_alias.to_sym] or raise NameError.new("#{self} attribute not found: #{name_or_alias}")
122
120
  end
123
121
 
124
122
  ## Metadata ATTRIBUTE FILTERS ##
@@ -217,10 +215,15 @@ module Jinx
217
215
  # @return [AttributeEnumerator] a new attribute enumerator
218
216
  def attribute_filter(attributes=nil, &filter)
219
217
  # make the attribute filter
220
- raise MetadataError.new("#{self} has not been introspected") if @prop_hash.nil?
218
+ raise MetadataError.new("#{self} has not been introspected") unless introspected?
221
219
  ph = attributes ? attributes.to_compact_hash { |pa| @prop_hash[pa] } : @prop_hash
222
220
  AttributeEnumerator.new(ph, &filter)
223
221
  end
222
+
223
+ # @return [Boolean] whether this class's metadata has been introspected
224
+ def introspected?
225
+ !!@prop_hash
226
+ end
224
227
 
225
228
  protected
226
229
 
@@ -296,7 +299,7 @@ module Jinx
296
299
  # @param [Symbol] attribute the attribute to alias
297
300
  def alias_attribute(aliaz, attribute)
298
301
  if property_defined?(attribute) then
299
- delegate_to_attribute(aliaz, attribute)
302
+ delegate_to_property(aliaz, property(attribute))
300
303
  register_property_alias(aliaz, attribute)
301
304
  else
302
305
  super
@@ -368,7 +371,7 @@ module Jinx
368
371
  prop.restrict(self, :type => klass)
369
372
  logger.debug { "Restricted #{prop.declarer.qp}.#{attribute}(#{prop.type.qp}) to #{qp} with return type #{klass.qp}." }
370
373
  else
371
- Jinx.fail(ArgumentError, "Cannot reset #{qp}.#{attribute} type #{prop.type.qp} to incompatible #{klass.qp}")
374
+ raise ArgumentError.new("Cannot reset #{qp}.#{attribute} type #{prop.type.qp} to incompatible #{klass.qp}")
372
375
  end
373
376
  end
374
377
 
@@ -416,7 +419,7 @@ module Jinx
416
419
  prop = @local_prop_hash.delete(std_prop)
417
420
  if prop then
418
421
  # clear the inverse, if any
419
- prop.inverse = nil
422
+ clear_inverse(prop)
420
423
  # remove from the mandatory attributes, if necessary
421
424
  @local_mndty_flt.delete(std_prop)
422
425
  # remove from the attribute => metadata hash
@@ -443,7 +446,7 @@ module Jinx
443
446
  # @param (see #alias_attribute)
444
447
  def register_property_alias(aliaz, attribute)
445
448
  std = standard_attribute(attribute)
446
- Jinx.fail(ArgumentError, "#{self} attribute not found: #{attribute}") if std.nil?
449
+ raise ArgumentError.new("#{self} attribute not found: #{attribute}") if std.nil?
447
450
  @local_std_prop_hash[aliaz.to_sym] = std
448
451
  end
449
452
 
@@ -457,7 +460,7 @@ module Jinx
457
460
  return enum unless Class === self and superclass.parent_module == parent_module
458
461
  anc_enum = yield superclass
459
462
  if anc_enum.nil? then
460
- Jinx.fail(MetadataError, "#{qp} superclass #{superclass.qp} does not have required metadata")
463
+ raise MetadataError.new("#{qp} superclass #{superclass.qp} does not have required metadata")
461
464
  end
462
465
  enum.union(anc_enum)
463
466
  end
@@ -121,13 +121,13 @@ module Jinx
121
121
  begin
122
122
  @inv_prop = type.property(attribute)
123
123
  rescue NameError => e
124
- Jinx.fail(MetadataError, "#{@declarer.qp}.#{self} inverse attribute #{type.qp}.#{attribute} not found", e)
124
+ raise MetadataError.new("#{@declarer.qp}.#{self} inverse attribute #{type.qp}.#{attribute} not found")
125
125
  end
126
126
  # the inverse of the inverse
127
127
  inv_inv_prop = @inv_prop.inverse_property
128
128
  # If the inverse of the inverse is already set to a different attribute, then raise an exception.
129
129
  if inv_inv_prop and not (inv_inv_prop == self or inv_inv_prop.restriction?(self))
130
- Jinx.fail(MetadataError, "Cannot set #{type.qp}.#{attribute} inverse attribute to #{@declarer.qp}.#{self}@#{object_id} since it conflicts with existing inverse #{inv_inv_prop.declarer.qp}.#{inv_inv_prop}@#{inv_inv_prop.object_id}")
130
+ raise MetadataError.new("Cannot set #{type.qp}.#{attribute} inverse attribute to #{@declarer.qp}.#{self}@#{object_id} since it conflicts with existing inverse #{inv_inv_prop.declarer.qp}.#{inv_inv_prop}@#{inv_inv_prop.object_id}")
131
131
  end
132
132
  # Set the inverse of the inverse to this attribute.
133
133
  @inv_prop.inverse = @attribute
@@ -270,10 +270,10 @@ module Jinx
270
270
  rtype = opts[:type] || @type
271
271
  rinv = opts[:inverse] || inverse
272
272
  unless declarer < @declarer then
273
- Jinx.fail(ArgumentError, "Cannot restrict #{@declarer.qp}.#{self} to an incompatible declarer type #{declarer.qp}")
273
+ raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self} to an incompatible declarer type #{declarer.qp}")
274
274
  end
275
275
  unless rtype <= @type then
276
- Jinx.fail(ArgumentError, "Cannot restrict #{@declarer.qp}.#{self}({@type.qp}) to an incompatible return type #{rtype.qp}")
276
+ raise ArgumentError.new("Cannot restrict #{@declarer.qp}.#{self}({@type.qp}) to an incompatible return type #{rtype.qp}")
277
277
  end
278
278
  # Copy this attribute and its instance variables minus the restrictions and make a deep copy of the flags.
279
279
  rst = deep_copy
@@ -318,7 +318,7 @@ module Jinx
318
318
  # @param [Class] klass the declaring class of this restriction attribute
319
319
  def set_restricted_declarer(klass)
320
320
  if @declarer and not klass < @declarer then
321
- Jinx.fail(MetadataError, "Cannot reset #{declarer.qp}.#{self} declarer to #{type.qp}")
321
+ raise MetadataError.new("Cannot reset #{declarer.qp}.#{self} declarer to #{type.qp}")
322
322
  end
323
323
  @declarer = klass
324
324
  @declarer.add_restriction(self)
@@ -350,11 +350,11 @@ module Jinx
350
350
  return unless @inv_prop
351
351
  logger.debug { "Clearing #{@declarer.qp}.#{self} inverse #{type.qp}.#{inverse}..." }
352
352
  # Capture the inverse before unsetting it.
353
- inv_prop = @inv_prop
353
+ ip = @inv_prop
354
354
  # Unset the inverse.
355
355
  @inv_prop = nil
356
356
  # Clear the inverse of the inverse.
357
- inv_prop.inverse = nil
357
+ ip.inverse = nil
358
358
  logger.debug { "Cleared #{@declarer.qp}.#{self} inverse." }
359
359
  end
360
360
 
@@ -363,7 +363,7 @@ module Jinx
363
363
  def set_flag(flag)
364
364
  return if @flags.include?(flag)
365
365
  unless flag_supported?(flag) then
366
- Jinx.fail(ArgumentError, "Property #{declarer.name}.#{self} flag not supported: #{flag.qp}")
366
+ raise ArgumentError.new("Property #{declarer.name}.#{self} flag not supported: #{flag.qp}")
367
367
  end
368
368
  @flags << flag
369
369
  case flag
@@ -379,11 +379,11 @@ module Jinx
379
379
  # @raise [MetadataError] if this attribute is dependent or an inverse could not be inferred
380
380
  def owner_flag_set
381
381
  if dependent? then
382
- Jinx.fail(MetadataError, "#{declarer.qp}.#{self} cannot be set as a #{type.qp} owner since it is already defined as a #{type.qp} dependent")
382
+ raise MetadataError.new("#{declarer.qp}.#{self} cannot be set as a #{type.qp} owner since it is already defined as a #{type.qp} dependent")
383
383
  end
384
384
  inv_attr = type.dependent_attribute(@declarer)
385
385
  if inv_attr.nil? then
386
- Jinx.fail(MetadataError, "#{@declarer.qp} owner attribute #{self} does not have a #{type.qp} dependent inverse")
386
+ raise MetadataError.new("#{@declarer.qp} owner attribute #{self} does not have a #{type.qp} dependent inverse")
387
387
  end
388
388
  logger.debug { "#{declarer.qp}.#{self} inverse is the #{type.qp} dependent attribute #{inv_attr}." }
389
389
  self.inverse = inv_attr
@@ -394,7 +394,7 @@ module Jinx
394
394
  # @raise [MetadataError] if this is an owner attribute
395
395
  def dependent_flag_set
396
396
  if owner? then
397
- Jinx.fail(MetadataError, "#{declarer.qp}.#{self} cannot be set as a #{type.qp} dependent since it is already defined as a #{type.qp} owner")
397
+ raise MetadataError.new("#{declarer.qp}.#{self} cannot be set as a #{type.qp} dependent since it is already defined as a #{type.qp} owner")
398
398
  end
399
399
  end
400
400
  end