diff options
author | nulltoken <emeric.fermas@gmail.com> | 2011-04-17 22:36:43 +0400 |
---|---|---|
committer | nulltoken <emeric.fermas@gmail.com> | 2011-04-17 22:39:26 +0400 |
commit | 81fd7757904ae4c685ec25fdd90b2d4a74f1b4bc (patch) | |
tree | 1cb18ddb25ffa6509231b3100df17aca3f87ff26 /LibGit2Sharp/Reference.cs | |
parent | 1bf453d51d08cfb48269678f5fee4f980fa5115e (diff) |
Refactor Reference, Branch and Tag instantiation
Diffstat (limited to 'LibGit2Sharp/Reference.cs')
-rw-r--r-- | LibGit2Sharp/Reference.cs | 99 |
1 files changed, 48 insertions, 51 deletions
diff --git a/LibGit2Sharp/Reference.cs b/LibGit2Sharp/Reference.cs index dcbcb596..5319efd8 100644 --- a/LibGit2Sharp/Reference.cs +++ b/LibGit2Sharp/Reference.cs @@ -9,89 +9,86 @@ namespace LibGit2Sharp /// </summary> public abstract class Reference : IEquatable<Reference> { + private static readonly LambdaEqualityHelper<Reference> equalityHelper = + new LambdaEqualityHelper<Reference>(new Func<Reference, object>[] { x => x.CanonicalName, x => x.ProvideAdditionalEqualityComponent() }); + /// <summary> /// Gets the full name of this reference. /// </summary> public string CanonicalName { get; protected set; } - #region IEquatable<Reference> Members - - public bool Equals(Reference other) - { - if (ReferenceEquals(null, other)) - { - return false; - } - - if (ReferenceEquals(this, other)) - { - return true; - } - - if (GetType() != other.GetType()) - { - return false; - } - - if (!Equals(CanonicalName, other.CanonicalName)) - { - return false; - } - - return Equals(ProvideAdditionalEqualityComponent(), other.ProvideAdditionalEqualityComponent()); - } - - #endregion - - internal static Reference CreateFromPtr(IntPtr ptr, Repository repo) + internal static T BuildFromPtr<T>(IntPtr ptr, Repository repo) where T : class { var name = NativeMethods.git_reference_name(ptr); var type = NativeMethods.git_reference_type(ptr); - + + Reference reference; + switch (type) { case GitReferenceType.Symbolic: IntPtr resolveRef; NativeMethods.git_reference_resolve(out resolveRef, ptr); - var reference = CreateFromPtr(resolveRef, repo); - return new SymbolicReference {CanonicalName = name, Target = reference}; + var targetRef = BuildFromPtr<Reference>(resolveRef, repo); + reference = new SymbolicReference { CanonicalName = name, Target = targetRef }; + break; case GitReferenceType.Oid: var oidPtr = NativeMethods.git_reference_oid(ptr); - var oid = (GitOid) Marshal.PtrToStructure(oidPtr, typeof (GitOid)); + var oid = (GitOid)Marshal.PtrToStructure(oidPtr, typeof(GitOid)); var target = repo.Lookup(new ObjectId(oid)); - return new DirectReference {CanonicalName = name, Target = target}; - + reference = new DirectReference { CanonicalName = name, Target = target }; + break; + default: throw new InvalidOperationException(); } - } - public override bool Equals(object obj) - { - return Equals(obj as Reference); - } + if (typeof(Reference).IsAssignableFrom(typeof(T))) + { + return reference as T; + } - public override int GetHashCode() - { - int hashCode = GetType().GetHashCode(); + GitObject targetGitObject = repo.Lookup(reference.ResolveToDirectReference().Target.Id); + + if (Equals(typeof(T), typeof(Tag))) + { + return new Tag(reference.CanonicalName, targetGitObject, targetGitObject as TagAnnotation) as T; + } - unchecked + if (Equals(typeof(T), typeof(Branch))) { - hashCode = (hashCode*397) ^ CanonicalName.GetHashCode(); - hashCode = (hashCode*397) ^ ProvideAdditionalEqualityComponent().GetHashCode(); + return new Branch(reference.CanonicalName, targetGitObject as Commit, repo) as T; } - return hashCode; + throw new InvalidOperationException( + string.Format("Unable to build a new instance of '{0}' from a reference of type '{1}'.", + typeof (T), + Enum.GetName(typeof (GitReferenceType), type))); } - protected abstract object ProvideAdditionalEqualityComponent(); - /// <summary> /// Resolves to direct reference. /// </summary> /// <returns></returns> - public abstract DirectReference ResolveToDirectReference(); + public abstract DirectReference ResolveToDirectReference(); + + protected abstract object ProvideAdditionalEqualityComponent(); + + public override bool Equals(object obj) + { + return Equals(obj as Reference); + } + + public bool Equals(Reference other) + { + return equalityHelper.Equals(this, other); + } + + public override int GetHashCode() + { + return equalityHelper.GetHashCode(this); + } public static bool operator ==(Reference left, Reference right) { |