diff options
Diffstat (limited to 'lib/rake/invocation_chain.rb')
-rw-r--r-- | lib/rake/invocation_chain.rb | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/lib/rake/invocation_chain.rb b/lib/rake/invocation_chain.rb new file mode 100644 index 0000000000..8a01ab4c29 --- /dev/null +++ b/lib/rake/invocation_chain.rb @@ -0,0 +1,51 @@ +module Rake + + #################################################################### + # InvocationChain tracks the chain of task invocations to detect + # circular dependencies. + class InvocationChain + def initialize(value, tail) + @value = value + @tail = tail + end + + def member?(obj) + @value == obj || @tail.member?(obj) + end + + def append(value) + if member?(value) + fail RuntimeError, "Circular dependency detected: #{to_s} => #{value}" + end + self.class.new(value, self) + end + + def to_s + "#{prefix}#{@value}" + end + + def self.append(value, chain) + chain.append(value) + end + + private + + def prefix + "#{@tail.to_s} => " + end + + class EmptyInvocationChain + def member?(obj) + false + end + def append(value) + InvocationChain.new(value, self) + end + def to_s + "TOP" + end + end + + EMPTY = EmptyInvocationChain.new + end +end |