From e846a1cc18146071585b4667f5b23a9eaf4f3cc1 Mon Sep 17 00:00:00 2001 From: Zoe Roux Date: Sun, 21 Apr 2024 14:12:06 +0200 Subject: [PATCH] Remove dead code --- .../Utility/EnumerableExtensions.cs | 70 -------- back/src/Kyoo.Abstractions/Utility/Merger.cs | 133 --------------- back/src/Kyoo.Abstractions/Utility/Utility.cs | 160 ------------------ 3 files changed, 363 deletions(-) delete mode 100644 back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs delete mode 100644 back/src/Kyoo.Abstractions/Utility/Merger.cs diff --git a/back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs b/back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs deleted file mode 100644 index 4c3b72b0..00000000 --- a/back/src/Kyoo.Abstractions/Utility/EnumerableExtensions.cs +++ /dev/null @@ -1,70 +0,0 @@ -// Kyoo - A portable and vast media library solution. -// Copyright (c) Kyoo. -// -// See AUTHORS.md and LICENSE file in the project root for full license information. -// -// Kyoo is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// Kyoo is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Kyoo. If not, see . - -using System; -using System.Collections.Generic; - -namespace Kyoo.Utils; - -/// -/// A set of extensions class for enumerable. -/// -public static class EnumerableExtensions -{ - /// - /// If the enumerable is empty, execute an action. - /// - /// The enumerable to check - /// The action to execute is the list is empty - /// The type of items inside the list - /// The iterator proxied, there is no dual iterations. - public static IEnumerable IfEmpty(this IEnumerable self, Action action) - { - static IEnumerable Generator(IEnumerable self, Action action) - { - using IEnumerator enumerator = self.GetEnumerator(); - - if (!enumerator.MoveNext()) - { - action(); - yield break; - } - - do - { - yield return enumerator.Current; - } while (enumerator.MoveNext()); - } - - return Generator(self, action); - } - - /// - /// A foreach used as a function with a little specificity: the list can be null. - /// - /// The list to enumerate. If this is null, the function result in a no-op - /// The action to execute for each arguments - /// The type of items in the list - public static void ForEach(this IEnumerable? self, Action action) - { - if (self == null) - return; - foreach (T i in self) - action(i); - } -} diff --git a/back/src/Kyoo.Abstractions/Utility/Merger.cs b/back/src/Kyoo.Abstractions/Utility/Merger.cs deleted file mode 100644 index a97530ef..00000000 --- a/back/src/Kyoo.Abstractions/Utility/Merger.cs +++ /dev/null @@ -1,133 +0,0 @@ -// Kyoo - A portable and vast media library solution. -// Copyright (c) Kyoo. -// -// See AUTHORS.md and LICENSE file in the project root for full license information. -// -// Kyoo is free software: you can redistribute it and/or modify -// it under the terms of the GNU General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// any later version. -// -// Kyoo is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with Kyoo. If not, see . - -using System; -using System.Collections.Generic; -using System.Linq; -using System.Reflection; -using Kyoo.Abstractions.Models.Attributes; - -namespace Kyoo.Utils; - -/// -/// A class containing helper methods to merge objects. -/// -public static class Merger -{ - /// - /// Merge two dictionary, if the same key is found on both dictionary, the values of the second one is kept. - /// - /// The first dictionary to merge - /// The second dictionary to merge - /// - /// true if a new items has been added to the dictionary, false otherwise. - /// - /// The type of the keys in dictionaries - /// The type of values in the dictionaries - /// - /// A dictionary with the missing elements of - /// set to those of . - /// - public static IDictionary? CompleteDictionaries( - IDictionary? first, - IDictionary? second, - out bool hasChanged - ) - { - if (first == null) - { - hasChanged = true; - return second; - } - - hasChanged = false; - if (second == null) - return first; - hasChanged = second.Any(x => - !first.ContainsKey(x.Key) || x.Value?.Equals(first[x.Key]) == false - ); - foreach ((T key, T2 value) in first) - second.TryAdd(key, value); - return second; - } - - /// - /// Set every non-default values of seconds to the corresponding property of second. - /// Dictionaries are handled like anonymous objects with a property per key/pair value - /// At the end, the OnMerge method of first will be called if first is a - /// - /// - /// {id: 0, slug: "test"}, {id: 4, slug: "foo"} -> {id: 4, slug: "foo"} - /// - /// - /// The object to complete - /// - /// - /// Missing fields of first will be completed by fields of this item. If second is null, the function no-op. - /// - /// - /// Filter fields that will be merged - /// - /// Fields of T will be completed - /// - public static T Complete(T first, T? second, Func? where = null) - { - if (second == null) - return first; - - Type type = typeof(T); - IEnumerable properties = type.GetProperties() - .Where(x => - x is { CanRead: true, CanWrite: true } - && Attribute.GetCustomAttribute(x, typeof(NotMergeableAttribute)) == null - ); - - if (where != null) - properties = properties.Where(where); - - foreach (PropertyInfo property in properties) - { - object? value = property.GetValue(second); - - if (value?.Equals(property.GetValue(first)) == true) - continue; - - if (Utility.IsOfGenericType(property.PropertyType, typeof(IDictionary<,>))) - { - Type[] dictionaryTypes = Utility - .GetGenericDefinition(property.PropertyType, typeof(IDictionary<,>))! - .GenericTypeArguments; - object?[] parameters = { property.GetValue(first), value, false }; - object newDictionary = Utility.RunGenericMethod( - typeof(Merger), - nameof(CompleteDictionaries), - dictionaryTypes, - parameters - )!; - if ((bool)parameters[2]!) - property.SetValue(first, newDictionary); - } - else - property.SetValue(first, value); - } - - if (first is IOnMerge merge) - merge.OnMerge(second); - return first; - } -} diff --git a/back/src/Kyoo.Abstractions/Utility/Utility.cs b/back/src/Kyoo.Abstractions/Utility/Utility.cs index 422d673d..9e085457 100644 --- a/back/src/Kyoo.Abstractions/Utility/Utility.cs +++ b/back/src/Kyoo.Abstractions/Utility/Utility.cs @@ -177,25 +177,6 @@ public static class Utility yield return type; } - /// - /// Check if inherit from a generic type . - /// - /// The type to check - /// The generic type to check against (Only generic types are supported like typeof(IEnumerable<>). - /// True if obj inherit from genericType. False otherwise - public static bool IsOfGenericType(Type type, Type genericType) - { - if (!genericType.IsGenericType) - throw new ArgumentException($"{nameof(genericType)} is not a generic type."); - - IEnumerable types = genericType.IsInterface - ? type.GetInterfaces() - : type.GetInheritanceTree(); - return types - .Prepend(type) - .Any(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); - } - /// /// Get the generic definition of . /// For example, calling this function with List<string> and typeof(IEnumerable<>) will return IEnumerable<string> @@ -217,147 +198,6 @@ public static class Utility .FirstOrDefault(x => x.IsGenericType && x.GetGenericTypeDefinition() == genericType); } - /// - /// Retrieve a method from an with the given name and respect the - /// amount of parameters and generic parameters. This works for polymorphic methods. - /// - /// - /// The type owning the method. For non static methods, this is the this. - /// - /// - /// The binding flags of the method. This allow you to specify public/private and so on. - /// - /// - /// The name of the method. - /// - /// - /// The list of generic parameters. - /// - /// - /// The list of parameters. - /// - /// No method match the given constraints. - /// The method handle of the matching method. - public static MethodInfo GetMethod( - Type type, - BindingFlags flag, - string name, - Type[] generics, - object?[] args - ) - { - MethodInfo[] methods = type.GetMethods(flag | BindingFlags.Public) - .Where(x => x.Name == name) - .Where(x => x.GetGenericArguments().Length == generics.Length) - .Where(x => x.GetParameters().Length == args.Length) - .IfEmpty(() => - { - throw new ArgumentException( - $"A method named {name} with " - + $"{args.Length} arguments and {generics.Length} generic " - + $"types could not be found on {type.Name}." - ); - }) - // TODO this won't work but I don't know why. - // .Where(x => - // { - // int i = 0; - // return x.GetGenericArguments().All(y => y.IsAssignableFrom(generics[i++])); - // }) - // .IfEmpty(() => throw new NullReferenceException($"No method {name} match the generics specified.")) - - // TODO this won't work for Type because T is specified in arguments but not in the parameters type. - // .Where(x => - // { - // int i = 0; - // return x.GetParameters().All(y => y.ParameterType.IsInstanceOfType(args[i++])); - // }) - // .IfEmpty(() => throw new NullReferenceException($"No method {name} match the parameters's types.")) - .Take(2) - .ToArray(); - - if (methods.Length == 1) - return methods[0]; - throw new ArgumentException( - $"Multiple methods named {name} match the generics and parameters constraints." - ); - } - - /// - /// Run a generic static method for a runtime . - /// - /// - /// To run Merger.MergeLists{T} for a List where you don't know the type at compile type, - /// you could do: - /// - /// Utility.RunGenericMethod<object>( - /// typeof(Utility), - /// nameof(MergeLists), - /// enumerableType, - /// oldValue, newValue, equalityComparer) - /// - /// - /// The type that owns the method. For non static methods, the type of this. - /// The name of the method. You should use the nameof keyword. - /// The generic type to run the method with. - /// The list of arguments of the method - /// - /// The return type of the method. You can put for an unknown one. - /// - /// No method match the given constraints. - /// The return of the method you wanted to run. - /// - public static T? RunGenericMethod( - Type owner, - string methodName, - Type type, - params object[] args - ) - { - return RunGenericMethod(owner, methodName, new[] { type }, args); - } - - /// - /// Run a generic static method for a multiple runtime . - /// If your generic method only needs one type, see - /// - /// - /// - /// To run Merger.MergeLists{T} for a List where you don't know the type at compile type, - /// you could do: - /// - /// Utility.RunGenericMethod<object>( - /// typeof(Utility), - /// nameof(MergeLists), - /// enumerableType, - /// oldValue, newValue, equalityComparer) - /// - /// - /// The type that owns the method. For non static methods, the type of this. - /// The name of the method. You should use the nameof keyword. - /// The list of generic types to run the method with. - /// The list of arguments of the method - /// - /// The return type of the method. You can put for an unknown one. - /// - /// No method match the given constraints. - /// The return of the method you wanted to run. - /// - public static T? RunGenericMethod( - Type owner, - string methodName, - Type[] types, - params object?[] args - ) - { - if (types.Length < 1) - throw new ArgumentException( - $"The {nameof(types)} array is empty. At least one type is needed." - ); - MethodInfo method = GetMethod(owner, BindingFlags.Static, methodName, types, args); - return (T?)method.MakeGenericMethod(types).Invoke(null, args); - } - /// /// Convert a dictionary to a query string. ///