@@ -2826,20 +2826,44 @@ public static Type classForName(string p)
28262826 return classForName ( p , CurrentNSVar . deref ( ) as Namespace , true ) ;
28272827 }
28282828
2829+ public static int NumDuplicates { get ; set ; } = 0 ;
2830+ public static int NumDirects { get ; set ; } = 0 ;
2831+ public static int NumLoadedAssemblyFinds { get ; set ; } = 0 ;
2832+ public static int NumRuntimeAssemblyLoads { get ; set ; } = 0 ;
2833+ public static int NumRuntimeAssemblyFinds { get ; set ; } = 0 ;
2834+ public static int NumLoadedAssemblyFinds2 { get ; set ; } = 0 ;
2835+ public static int NumParsing { get ; set ; } = 0 ;
2836+ public static int NumFails { get ; set ; } = 0 ;
2837+
2838+ public static void ClassForNameReport ( )
2839+ {
2840+ Console . WriteLine ( $ "NumDuplicates: { NumDuplicates } ") ;
2841+ Console . WriteLine ( $ "NumDirects: { NumDirects } ") ;
2842+ Console . WriteLine ( $ "NumLoadedAssemblyFinds: { NumLoadedAssemblyFinds } ") ;
2843+ Console . WriteLine ( $ "NumRuntimeAssemblyLoads: { NumRuntimeAssemblyLoads } ") ;
2844+ Console . WriteLine ( $ "NumRuntimeAssemblyFinds: { NumRuntimeAssemblyFinds } ") ;
2845+ Console . WriteLine ( $ "NumLoadedAssemblyFinds2: { NumLoadedAssemblyFinds2 } ") ;
2846+ Console . WriteLine ( $ "NumParsing: { NumParsing } ") ;
2847+ Console . WriteLine ( $ "NumFails: { NumFails } ") ;
2848+
2849+ }
2850+
28292851 internal static Type classForName ( string p , Namespace ns , bool canCallClrTypeSpec )
28302852 {
28312853 // First, check for types generated during the current compilation session.
28322854
28332855 Type t = Compiler . FindDuplicateType ( p ) ;
28342856 if ( t != null )
28352857 {
2858+ NumDuplicates ++ ;
28362859 return t ;
28372860 }
28382861
28392862 // Try using Type.GetType which can find types with assembly-qualified names.
28402863 t = Type . GetType ( p , false ) ;
28412864 if ( t != null && ( t . IsPublic || t . IsNestedPublic ) )
28422865 {
2866+ NumDirects ++ ;
28432867 return t ;
28442868 }
28452869
@@ -2853,13 +2877,12 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
28532877 Type t1 = assy . GetType ( p , false ) ;
28542878 if ( t1 != null && ( t1 . IsPublic || t1 . IsNestedPublic ) )
28552879 {
2880+ NumLoadedAssemblyFinds ++ ;
28562881 return t1 ;
28572882 }
28582883 }
28592884
28602885 // Try to load from runtime libraries if we have DependencyContext.
2861- var runtimeAssemblyNames = _runtimeAssemblyNames . Value ;
2862- if ( runtimeAssemblyNames . Count > 0 )
28632886 {
28642887 // Split the type name to identify the namespace and simple name.
28652888 string namespaceName = null ;
@@ -2871,69 +2894,65 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
28712894 typeName = p . Substring ( lastDot + 1 ) ;
28722895 }
28732896
2874- // Try to find and load the assembly that might contain this type.
2875- foreach ( var assemblyName in runtimeAssemblyNames )
2897+ if ( ! string . IsNullOrEmpty ( namespaceName ) )
28762898 {
2877- // Skip if this assembly is already loaded.
2878- if ( loadedAssemblies . Any ( a => a . GetName ( ) . Name == assemblyName . Name ) )
2879- {
2880- continue ;
2881- }
28822899
2883- // Try common patterns for framework assemblies.
2884- if ( namespaceName != null )
2900+ var runtimeAssemblyNames = _runtimeAssemblyNames . Value ;
2901+ if ( runtimeAssemblyNames . Count > 0 )
28852902 {
2886- // Check if the assembly name matches the namespace pattern.
2887- if ( assemblyName . Name . StartsWith ( "System" ) && namespaceName . StartsWith ( "System" ) )
2903+
2904+ // Try to find and load the assembly that might contain this type.
2905+ foreach ( var assemblyName in runtimeAssemblyNames )
28882906 {
2889- try
2907+ // Skip if this assembly is already loaded.
2908+ if ( loadedAssemblies . Any ( a => a . GetName ( ) . Name == assemblyName . Name ) )
28902909 {
2891- var assy = Assembly . Load ( assemblyName ) ;
2892- var type = assy . GetType ( p , false ) ;
2893- if ( type != null && ( type . IsPublic || type . IsNestedPublic ) )
2894- {
2895- return type ;
2896- }
2910+ continue ;
28972911 }
2898- catch { }
2899- }
2900- // Also try if the namespace directly matches the assembly name.
2901- else if ( assemblyName . Name . Equals ( namespaceName , StringComparison . OrdinalIgnoreCase ) )
2902- {
2903- try
2912+
2913+ // try if the namespace directly matches the assembly name.
2914+ if ( assemblyName . Name . Equals ( namespaceName , StringComparison . OrdinalIgnoreCase ) )
29042915 {
2905- var assy = Assembly . Load ( assemblyName ) ;
2906- var type = assy . GetType ( p , false ) ;
2907- if ( type != null && ( type . IsPublic || type . IsNestedPublic ) )
2916+ try
29082917 {
2909- return type ;
2918+ NumRuntimeAssemblyLoads ++ ;
2919+ var assy = Assembly . Load ( assemblyName ) ;
2920+ var type = assy . GetType ( p , false ) ;
2921+ if ( type != null && ( type . IsPublic || type . IsNestedPublic ) )
2922+ {
2923+ NumRuntimeAssemblyFinds ++ ;
2924+ return type ;
2925+ }
29102926 }
2927+ catch { }
29112928 }
2912- catch { }
2929+
29132930 }
29142931 }
29152932 }
29162933 }
29172934
2918- // Re-check loaded assemblies (some might have been loaded during the search).
2919- loadedAssemblies = domain . GetAssemblies ( ) ;
2920- foreach ( Assembly assy in loadedAssemblies )
2921- {
2922- Type t1 = assy . GetType ( p , false ) ;
2923- if ( t1 != null && ( t1 . IsPublic || t1 . IsNestedPublic ) )
2924- {
2925- return t1 ;
2926- }
2927- }
2935+ //// Re-check loaded assemblies (some might have been loaded during the search).
2936+ //loadedAssemblies = domain.GetAssemblies();
2937+ //foreach (Assembly assy in loadedAssemblies)
2938+ //{
2939+ // Type t1 = assy.GetType(p, false);
2940+ // if (t1 != null && (t1.IsPublic || t1.IsNestedPublic))
2941+ // {
2942+ // NumLoadedAssemblyFinds2++;
2943+ // return t1;
2944+ // }
2945+ //}
29282946
29292947 // Search by simple type name (slow path).
2930- List < Type > candidateTypes = [ ] ;
2931- foreach ( Assembly assy1 in loadedAssemblies )
2948+ // At some point this became a no-op unless running on Mono, so I restricted it to that.
2949+ if ( IsRunningOnMono )
29322950 {
2933- Type t1 = null ;
2934-
2935- if ( IsRunningOnMono )
2951+ List < Type > candidateTypes = [ ] ;
2952+ foreach ( Assembly assy1 in loadedAssemblies )
29362953 {
2954+ Type t1 = null ;
2955+
29372956 if ( ! assy1 . IsDynamic )
29382957 {
29392958 try
@@ -2951,19 +2970,20 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
29512970 {
29522971 }
29532972 }
2973+
2974+
2975+ if ( t1 != null && ! candidateTypes . Contains ( t1 ) )
2976+ {
2977+ candidateTypes . Add ( t1 ) ;
2978+ }
29542979 }
29552980
2956- if ( t1 != null && ! candidateTypes . Contains ( t1 ) )
2981+ if ( candidateTypes . Count == 1 )
29572982 {
2958- candidateTypes . Add ( t1 ) ;
2983+ return candidateTypes [ 0 ] ;
29592984 }
29602985 }
29612986
2962- if ( candidateTypes . Count == 1 )
2963- {
2964- return candidateTypes [ 0 ] ;
2965- }
2966-
29672987 //// Handle generic types and array types.
29682988 //if (p.IndexOfAny(_triggerTypeChars) != -1)
29692989 //{
@@ -2972,7 +2992,12 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
29722992
29732993 if ( canCallClrTypeSpec )
29742994 {
2975- return ClrTypeSpec . GetTypeFromName ( p , ns ) ;
2995+ var t1 = ClrTypeSpec . GetTypeFromName ( p , ns ) ;
2996+ if ( t1 is not null )
2997+ {
2998+ NumParsing ++ ;
2999+ return t1 ;
3000+ }
29763001
29773002 }
29783003 //// Handle generic types and array types.
@@ -2981,6 +3006,7 @@ internal static Type classForName(string p, Namespace ns, bool canCallClrTypeSpe
29813006 // return ClrTypeSpec.GetTypeFromName(p);
29823007 //}
29833008
3009+ NumFails ++ ;
29843010 return null ;
29853011 }
29863012
0 commit comments