You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucenenet.apache.org by sy...@apache.org on 2016/09/01 21:29:18 UTC

[3/6] lucenenet git commit: Only loading non-Microsoft Assemblies to search for public types

Only loading non-Microsoft Assemblies to search for public types


Project: http://git-wip-us.apache.org/repos/asf/lucenenet/repo
Commit: http://git-wip-us.apache.org/repos/asf/lucenenet/commit/e8c4963a
Tree: http://git-wip-us.apache.org/repos/asf/lucenenet/tree/e8c4963a
Diff: http://git-wip-us.apache.org/repos/asf/lucenenet/diff/e8c4963a

Branch: refs/heads/master
Commit: e8c4963a01372b6544b5da89743832a550323e55
Parents: a43d4e2
Author: Connie Yau <co...@microsoft.com>
Authored: Sun Aug 28 19:47:46 2016 -0700
Committer: Connie Yau <co...@microsoft.com>
Committed: Thu Sep 1 10:25:39 2016 -0700

----------------------------------------------------------------------
 src/Lucene.Net.Core/Util/SPIClassIterator.cs | 85 ++++++++++++++++++++++-
 1 file changed, 83 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/lucenenet/blob/e8c4963a/src/Lucene.Net.Core/Util/SPIClassIterator.cs
----------------------------------------------------------------------
diff --git a/src/Lucene.Net.Core/Util/SPIClassIterator.cs b/src/Lucene.Net.Core/Util/SPIClassIterator.cs
index 949647f..50f2eb0 100644
--- a/src/Lucene.Net.Core/Util/SPIClassIterator.cs
+++ b/src/Lucene.Net.Core/Util/SPIClassIterator.cs
@@ -1,6 +1,9 @@
 using System;
 using System.Collections.Generic;
+using System.Diagnostics;
+using System.Linq;
 using System.Reflection;
+using System.Text;
 
 namespace Lucene.Net.Util
 {
@@ -44,12 +47,35 @@ namespace Lucene.Net.Util
             // hoping would be loaded hasn't been loaded yet into the app domain,
             // it is unavailable. So we go to the next level on each and check each referenced
             // assembly.
+            var assembliesLoaded = AppDomain.CurrentDomain.GetAssemblies().Where(x => !DotNetFrameworkFilter.IsFrameworkAssembly(x));
+            var referencedAssemblies = assembliesLoaded
+                .SelectMany(assembly =>
+                {
+                    return assembly
+                        .GetReferencedAssemblies()
+                        .Where(reference => !DotNetFrameworkFilter.IsFrameworkAssembly(reference))
+                        .Select(assemblyName => {
+                            try
+                            {
+                                return Assembly.Load(assemblyName);
+                            }
+                            catch
+                            {
+                                // swallow
+                                return null;
+                            }
+                        });
+                })
+                .Where(x => x != null)
+                .Distinct();
+
+            var assembliesToExamine = assembliesLoaded.Concat(referencedAssemblies).Distinct();
 
-            foreach (var loadedAssembly in AppDomain.CurrentDomain.GetAssemblies())
+            foreach (var assembly in assembliesToExamine)
             {
                 try
                 {
-                    foreach (var type in loadedAssembly.GetTypes())
+                    foreach (var type in assembly.GetTypes().Where(x => x.IsPublic))
                     {
                         try
                         {
@@ -114,6 +140,61 @@ namespace Lucene.Net.Util
         {
             return GetEnumerator();
         }
+
+        /// <summary>
+        /// Assembly filter logic from:
+        /// https://raw.githubusercontent.com/Microsoft/dotnet-apiport/master/src/Microsoft.Fx.Portability/Analyzer/DotNetFrameworkFilter.cs
+        /// </summary>
+        private static class DotNetFrameworkFilter
+        {
+            /// <summary>
+            /// These keys are a collection of public key tokens derived from all the reference assemblies in
+            /// "%ProgramFiles%\Reference Assemblies\Microsoft" on a Windows 10 machine with VS 2015 installed
+            /// </summary>
+            private static readonly ICollection<string> s_microsoftKeys = new HashSet<string>(new[] 
+            {
+                "b77a5c561934e089", // ECMA
+                "b03f5f7f11d50a3a", // DEVDIV
+                "7cec85d7bea7798e", // SLPLAT
+                "31bf3856ad364e35", // Windows
+                "24eec0d8c86cda1e", // Phone
+                "0738eb9f132ed756", // Mono
+                "ddd0da4d3e678217", // Component model
+                "84e04ff9cfb79065", // Mono Android
+                "842cf8be1de50553"  // Xamarin.iOS
+            }, StringComparer.OrdinalIgnoreCase);
+
+            private static readonly IEnumerable<string> s_frameworkAssemblyNamePrefixes = new[]
+            {
+                "System.",
+                "Microsoft.",
+                "Mono."
+            };
+
+            /// <summary>
+            /// Gets a best guess as to whether this assembly is a .NET Framework assembly or not.
+            /// </summary>
+            public static bool IsFrameworkAssembly(Assembly assembly)
+            {
+                return assembly != null && IsFrameworkAssembly(assembly.GetName());
+            }
+
+            /// <summary>
+            /// Gets a best guess as to whether this assembly is a .NET Framework assembly or not.
+            /// </summary>
+            public static bool IsFrameworkAssembly(AssemblyName assembly)
+            {
+                if (assembly == null)
+                {
+                    return false;
+                }
+
+                var publicKeyToken = string.Concat(assembly.GetPublicKeyToken().Select(i => i.ToString("x2")));
+
+                return s_microsoftKeys.Contains(publicKeyToken)
+                    || s_frameworkAssemblyNamePrefixes.Any(p => assembly.Name.StartsWith(p, StringComparison.OrdinalIgnoreCase));
+            }
+        }
     }
 
     /* Being Re-written