2011-06-23 18:11:55 -04:00
|
|
|
module Rake
|
|
|
|
|
|
|
|
# InvocationChain tracks the chain of task invocations to detect
|
|
|
|
# circular dependencies.
|
2013-10-11 17:35:01 -04:00
|
|
|
class InvocationChain < LinkedList
|
2011-06-23 18:11:55 -04:00
|
|
|
|
2013-10-11 17:35:01 -04:00
|
|
|
# Is the invocation already in the chain?
|
|
|
|
def member?(invocation)
|
|
|
|
head == invocation || tail.member?(invocation)
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
|
|
|
|
2013-10-11 17:35:01 -04:00
|
|
|
# Append an invocation to the chain of invocations. It is an error
|
|
|
|
# if the invocation already listed.
|
|
|
|
def append(invocation)
|
|
|
|
if member?(invocation)
|
|
|
|
fail RuntimeError, "Circular dependency detected: #{to_s} => #{invocation}"
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
2013-10-11 17:35:01 -04:00
|
|
|
conj(invocation)
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
|
|
|
|
2013-10-11 17:35:01 -04:00
|
|
|
# Convert to string, ie: TOP => invocation => invocation
|
2011-06-23 18:11:55 -04:00
|
|
|
def to_s
|
2013-10-11 17:35:01 -04:00
|
|
|
"#{prefix}#{head}"
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
|
|
|
|
2013-10-11 17:35:01 -04:00
|
|
|
# Class level append.
|
|
|
|
def self.append(invocation, chain)
|
|
|
|
chain.append(invocation)
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
|
|
|
def prefix
|
2014-08-27 08:21:41 -04:00
|
|
|
"#{tail} => "
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
|
|
|
|
2013-10-11 17:35:01 -04:00
|
|
|
# Null object for an empty chain.
|
|
|
|
class EmptyInvocationChain < LinkedList::EmptyLinkedList
|
|
|
|
@parent = InvocationChain
|
|
|
|
|
2011-06-23 18:11:55 -04:00
|
|
|
def member?(obj)
|
|
|
|
false
|
|
|
|
end
|
2013-10-11 17:35:01 -04:00
|
|
|
|
|
|
|
def append(invocation)
|
|
|
|
conj(invocation)
|
2011-06-23 18:11:55 -04:00
|
|
|
end
|
2013-10-11 17:35:01 -04:00
|
|
|
|
2011-06-23 18:11:55 -04:00
|
|
|
def to_s
|
|
|
|
"TOP"
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
EMPTY = EmptyInvocationChain.new
|
|
|
|
end
|
|
|
|
end
|