A game framework written with osu! in mind.
at master 3.8 kB view raw
1// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. 2// See the LICENCE file in the repository root for full licence text. 3 4using System; 5using System.Linq; 6using System.Reflection; 7using osu.Framework.Extensions.TypeExtensions; 8 9namespace osu.Framework.Development 10{ 11 internal static class ReflectionUtils 12 { 13 // taken from https://github.com/nunit/nunit/blob/73dbcce0896a6897a2add4281cc48734eca546a2/src/NUnitFramework/framework/Internal/Reflect.cs 14 // as it was removed/refactored in nunit 3.13.1 15 16 // *********************************************************************** 17 // Copyright (c) 2007-2018 Charlie Poole, Rob Prouse 18 // 19 // Permission is hereby granted, free of charge, to any person obtaining 20 // a copy of this software and associated documentation files (the 21 // "Software"), to deal in the Software without restriction, including 22 // without limitation the rights to use, copy, modify, merge, publish, 23 // distribute, sublicense, and/or sell copies of the Software, and to 24 // permit persons to whom the Software is furnished to do so, subject to 25 // the following conditions: 26 // 27 // The above copyright notice and this permission notice shall be 28 // included in all copies or substantial portions of the Software. 29 // 30 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 31 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 32 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 33 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 34 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 35 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 36 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 37 // *********************************************************************** 38 39 private const BindingFlags all_members = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static; 40 41 /// <summary> 42 /// Returns all methods declared by the specified fixture type that have the specified attribute, optionally 43 /// including base classes. Methods from a base class are always returned before methods from a class that 44 /// inherits from it. 45 /// </summary> 46 /// <param name="fixtureType">The type to examine.</param> 47 /// <param name="attributeType">Only methods to which this attribute is applied will be returned.</param> 48 /// <param name="inherit">Specifies whether to search the fixture type inheritance chain.</param> 49 internal static MethodInfo[] GetMethodsWithAttribute(Type fixtureType, Type attributeType, bool inherit) 50 { 51 if (!inherit) 52 { 53 return fixtureType 54 .GetMethods(all_members | BindingFlags.DeclaredOnly) 55 .Where(method => method.IsDefined(attributeType, inherit: false)) 56 .ToArray(); 57 } 58 59 var methodsByDeclaringType = fixtureType 60 .GetMethods(all_members | BindingFlags.FlattenHierarchy) // FlattenHierarchy is complex to replicate by looping over base types with DeclaredOnly. 61 .Where(method => method.IsDefined(attributeType, inherit: true)) 62 .ToLookup(method => method.DeclaringType); 63 64 return fixtureType 65 .EnumerateBaseTypes() 66 .Reverse() 67 .SelectMany(declaringType => methodsByDeclaringType[declaringType]) 68 .ToArray(); 69 } 70 } 71}