Skip to content

Commit

Permalink
Fix interface name returned for GetRuntimeClassName and fix build (#1290
Browse files Browse the repository at this point in the history
)

* Fix interface name returned in GetRuntimeClassName

* Fix build

* Try build fix

* Update version
  • Loading branch information
manodasanW authored Jan 31, 2023
1 parent e3f6727 commit 579b61a
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 59 deletions.
9 changes: 9 additions & 0 deletions build/AzurePipelineTemplates/CsWinRT-Build-Steps.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ steps:
installationPath: C:\Users\VssAdministrator\AppData\Local\Microsoft\dotnet\
performMultiLevelLookup: true

- task: UseDotNet@2
displayName: Use .NET Core SDK 3.1
inputs:
version: 3.1.x
installationPath: C:\Users\VssAdministrator\AppData\Local\Microsoft\dotnet\x86
performMultiLevelLookup: true
env:
PROCESSOR_ARCHITECTURE: x86

# Install .NET 6 SDK
- task: PowerShell@2
displayName: Install .NET 6 SDK
Expand Down
2 changes: 1 addition & 1 deletion build/AzurePipelineTemplates/CsWinRT-Variables.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
variables:
MajorVersion: 2
MinorVersion: 0
PatchVersion: 1
PatchVersion: 2
WinRT.Runtime.AssemblyVersion: '2.0.0.0'
Net5.SDK.Feed: 'https://dotnetcli.blob.core.windows.net/dotnet'
Net5.SDK.Version: '5.0.408'
Expand Down
116 changes: 58 additions & 58 deletions src/WinRT.Runtime/TypeNameSupport.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Reflection;
using System.Text;
Expand All @@ -29,59 +29,59 @@ internal enum TypeNameGenerationFlags

internal static class TypeNameSupport
{
private static readonly List<Assembly> projectionAssemblies = new List<Assembly>();
private static readonly List<Assembly> projectionAssemblies = new List<Assembly>();
private static readonly List<IDictionary<string, string>> projectionTypeNameToBaseTypeNameMappings = new List<IDictionary<string, string>>();
private static readonly ConcurrentDictionary<string, Type> typeNameCache = new ConcurrentDictionary<string, Type>(StringComparer.Ordinal) { ["TrackerCollection<T>"] = null };
private static readonly ConcurrentDictionary<string, Type> baseRcwTypeCache = new ConcurrentDictionary<string, Type>(StringComparer.Ordinal) { ["TrackerCollection<T>"] = null };

public static void RegisterProjectionAssembly(Assembly assembly)
{
projectionAssemblies.Add(assembly);
}

public static void RegisterProjectionTypeBaseTypeMapping(IDictionary<string, string> typeNameToBaseTypeNameMapping)
{
projectionTypeNameToBaseTypeNameMappings.Add(typeNameToBaseTypeNameMapping);
}

}

public static void RegisterProjectionTypeBaseTypeMapping(IDictionary<string, string> typeNameToBaseTypeNameMapping)
{
projectionTypeNameToBaseTypeNameMappings.Add(typeNameToBaseTypeNameMapping);
}

#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
public static Type FindRcwTypeByNameCached(string runtimeClassName)
{
// Try to get the given type name. If it is not found, the type might have been trimmed.
// Due to that, check if one of the base types exists and if so use that instead for the RCW type.
var rcwType = FindTypeByNameCached(runtimeClassName);
if (rcwType is null)
{
rcwType = baseRcwTypeCache.GetOrAdd(runtimeClassName,
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
(runtimeClassName) =>
{
var resolvedBaseType = projectionTypeNameToBaseTypeNameMappings.Find((dict) => dict.ContainsKey(runtimeClassName))?[runtimeClassName];
return resolvedBaseType is not null ? FindRcwTypeByNameCached(resolvedBaseType) : null;
});
}

{
// Try to get the given type name. If it is not found, the type might have been trimmed.
// Due to that, check if one of the base types exists and if so use that instead for the RCW type.
var rcwType = FindTypeByNameCached(runtimeClassName);
if (rcwType is null)
{
rcwType = baseRcwTypeCache.GetOrAdd(runtimeClassName,
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
(runtimeClassName) =>
{
var resolvedBaseType = projectionTypeNameToBaseTypeNameMappings.Find((dict) => dict.ContainsKey(runtimeClassName))?[runtimeClassName];
return resolvedBaseType is not null ? FindRcwTypeByNameCached(resolvedBaseType) : null;
});
}

return rcwType;
}

}

/// <summary>
/// Parses and loads the given type name, if not found in the cache.
/// </summary>
/// <param name="runtimeClassName">The runtime class name to attempt to parse.</param>
/// <returns>The type, if found. Null otherwise</returns>
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
public static Type FindTypeByNameCached(string runtimeClassName)
{
return typeNameCache.GetOrAdd(runtimeClassName,
return typeNameCache.GetOrAdd(runtimeClassName,
#if NET
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
(runtimeClassName) =>
{
Type implementationType = null;
Expand All @@ -108,8 +108,8 @@ public static (Type type, int remaining) FindTypeByName(ReadOnlySpan<char> runti
if (runtimeClassName.StartsWith("<>f__AnonymousType".AsSpan(), StringComparison.Ordinal))
{
return (typeof(System.Dynamic.ExpandoObject), 0);
}
// PropertySet and ValueSet can return IReference<String> but Nullable<String> is illegal
}
// PropertySet and ValueSet can return IReference<String> but Nullable<String> is illegal
else if (runtimeClassName.CompareTo("Windows.Foundation.IReference`1<String>".AsSpan(), StringComparison.Ordinal) == 0)
{
return (typeof(ABI.System.Nullable_string), 0);
Expand All @@ -118,17 +118,17 @@ public static (Type type, int remaining) FindTypeByName(ReadOnlySpan<char> runti
{
return (typeof(ABI.System.Nullable_Type), 0);
}
else
{
var (genericTypeName, genericTypes, remaining) = ParseGenericTypeName(runtimeClassName);
if (genericTypeName == null)
{
return (null, -1);
}
return (FindTypeByNameCore(genericTypeName, genericTypes), remaining);
else
{
var (genericTypeName, genericTypes, remaining) = ParseGenericTypeName(runtimeClassName);
if (genericTypeName == null)
{
return (null, -1);
}
return (FindTypeByNameCore(genericTypeName, genericTypes), remaining);
}
}

}

/// <summary>
/// Resolve a type from the given simple type name and the provided generic parameters.
/// </summary>
Expand All @@ -140,9 +140,9 @@ public static (Type type, int remaining) FindTypeByName(ReadOnlySpan<char> runti
/// the full type closure of the application.
/// </remarks>
#if NET
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
[UnconditionalSuppressMessage("ReflectionAnalysis", "IL2026:RequiresUnreferencedCode",
Justification = "Any types which are trimmed are not used by user code and there is fallback logic to handle that.")]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
[return: DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors)]
#endif
private static Type FindTypeByNameCore(string runtimeClassName, Type[] genericTypes)
{
Expand Down Expand Up @@ -181,21 +181,21 @@ private static Type FindTypeByNameCore(string runtimeClassName, Type[] genericTy
break;
}
}
}
}

if (resolvedType is not null)
{
if (genericTypes != null)
{
if(resolvedType == typeof(global::System.Nullable<>) && genericTypes[0].IsDelegate())
{
return typeof(ABI.System.Nullable_Delegate<>).MakeGenericType(genericTypes);
if(resolvedType == typeof(global::System.Nullable<>) && genericTypes[0].IsDelegate())
{
return typeof(ABI.System.Nullable_Delegate<>).MakeGenericType(genericTypes);
}
resolvedType = resolvedType.MakeGenericType(genericTypes);
}
return resolvedType;
}

}

Debug.WriteLine($"FindTypeByNameCore: Unable to find a type named '{runtimeClassName}'");
return null;
}
Expand All @@ -214,7 +214,7 @@ public static Type ResolvePrimitiveType(string primitiveTypeName)
"Int64" => typeof(long),
"Boolean" => typeof(bool),
"String" => typeof(string),
"Char" => typeof(char),
"Char" => typeof(char),
"Char16" => typeof(char),
"Single" => typeof(float),
"Double" => typeof(double),
Expand Down Expand Up @@ -256,9 +256,9 @@ private static (string genericTypeName, Type[] genericTypes, int remaining) Pars
{
// Resolve the generic type argument at this point in the parameter list.
var (genericType, endOfGenericArgument) = FindTypeByName(remainingTypeName);
if (genericType == null)
{
return (null, null, -1);
if (genericType == null)
{
return (null, null, -1);
}

remainingIndex += endOfGenericArgument;
Expand Down Expand Up @@ -394,7 +394,7 @@ private static bool TryAppendWinRTInterfaceNameForType(Type type, StringBuilder
{
if (Projections.IsTypeWindowsRuntimeType(iface))
{
if (interfaceTypeToUse is null || iface.IsAssignableFrom(interfaceTypeToUse))
if (interfaceTypeToUse is null || interfaceTypeToUse.IsAssignableFrom(iface))
{
interfaceTypeToUse = iface;
}
Expand Down

0 comments on commit 579b61a

Please sign in to comment.