Skip to content

Commit

Permalink
Fix couple issues (#1820)
Browse files Browse the repository at this point in the history
* Fixes for various issues

* Fix nullable scenarios

* Ensure trailing slash

* Add another test
  • Loading branch information
manodasanW authored Oct 13, 2024
1 parent 8482124 commit eb67781
Show file tree
Hide file tree
Showing 12 changed files with 133 additions and 9 deletions.
2 changes: 1 addition & 1 deletion nuget/Microsoft.Windows.CsWinRT.Authoring.targets
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<_CsWinRTRuntimeCopyLocalItemsFromNuGetPackage Include="@(RuntimeCopyLocalItems->HasMetadata('NuGetPackageVersion'))" />
<_CsWinRTDetectedPackages Include="%(_CsWinRTRuntimeCopyLocalItemsFromNuGetPackage.NuGetPackageId)\%(_CsWinRTRuntimeCopyLocalItemsFromNuGetPackage.NuGetPackageVersion)" Condition="@(_CsWinRTRuntimeCopyLocalItemsFromNuGetPackage->Count()) > 0" />
<_CsWinRTDetectedDistinctPackages Include="@(_CsWinRTDetectedPackages->Distinct())" />
<CsWinRTAuthoringDetectedWinMDs Include="$(NuGetPackageRoot)%(_CsWinRTDetectedDistinctPackages.Identity)\**\*.winmd" Condition="@(_CsWinRTDetectedDistinctPackages->Count()) > 0" />
<CsWinRTAuthoringDetectedWinMDs Include="$([MSBuild]::EnsureTrailingSlash($(NuGetPackageRoot)))%(_CsWinRTDetectedDistinctPackages.Identity)\**\*.winmd" Condition="@(_CsWinRTDetectedDistinctPackages->Count()) > 0" />
</ItemGroup>

<ItemGroup>
Expand Down
3 changes: 2 additions & 1 deletion nuget/Microsoft.Windows.CsWinRT.Embedded.targets
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ Copyright (C) Microsoft Corporation. All rights reserved.
<Reference Remove="WinRT.Runtime" />
<RuntimeCopyLocalItems Remove="@(RuntimeCopyLocalItems)" Condition="'%(DestinationSubPath)' == 'WinRT.Runtime.dll'"/>
<ResolvedCompileFileDefinitions Remove="@(ResolvedCompileFileDefinitions)" Condition="'%(HintPath)' == '$(CsWinRTPath)lib\net6.0\WinRT.Runtime.dll'"/>
</ItemGroup>
<ResolvedCompileFileDefinitions Remove="@(ResolvedCompileFileDefinitions)" Condition="'%(HintPath)' == '$(CsWinRTPath)lib\net8.0\WinRT.Runtime.dll'"/>
</ItemGroup>

</Target>

Expand Down
12 changes: 8 additions & 4 deletions src/Authoring/WinRT.SourceGenerator/AotOptimizer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -365,7 +365,7 @@ private static string ToFullyQualifiedString(ISymbol symbol)
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Included,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
genericsOptions: SymbolDisplayGenericsOptions.IncludeTypeParameters,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes);
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.UseSpecialTypes | SymbolDisplayMiscellaneousOptions.ExpandNullable);

var qualifiedString = symbol.ToDisplayString(symbolDisplayString);
return qualifiedString.StartsWith("global::") ? qualifiedString[8..] : qualifiedString;
Expand Down Expand Up @@ -410,7 +410,8 @@ private static string ToVtableLookupString(ISymbol symbol, List<string> genericA
var arity = symbol is INamedTypeSymbol namedType && namedType.Arity > 0 ? "`" + namedType.Arity : "";
var symbolDisplayString = new SymbolDisplayFormat(
globalNamespaceStyle: SymbolDisplayGlobalNamespaceStyle.Omitted,
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces);
typeQualificationStyle: SymbolDisplayTypeQualificationStyle.NameAndContainingTypesAndNamespaces,
miscellaneousOptions: SymbolDisplayMiscellaneousOptions.ExpandNullable);
return symbol.ToDisplayString(symbolDisplayString) + arity;
}
else
Expand Down Expand Up @@ -640,9 +641,12 @@ void AddGenericInterfaceInstantiation(INamedTypeSymbol iface)
List<GenericParameter> genericParameters = new();
foreach (var genericParameter in iface.TypeArguments)
{
var isNullable = genericParameter.IsValueType && genericParameter.NullableAnnotation.HasFlag(NullableAnnotation.Annotated);

// Handle initialization of nested generics as they may not be
// initialized already.
if (genericParameter is INamedTypeSymbol genericParameterIface &&
if (!isNullable &&
genericParameter is INamedTypeSymbol genericParameterIface &&
genericParameterIface.IsGenericType)
{
AddGenericInterfaceInstantiation(genericParameterIface);
Expand All @@ -651,7 +655,7 @@ void AddGenericInterfaceInstantiation(INamedTypeSymbol iface)
genericParameters.Add(new GenericParameter(
ToFullyQualifiedString(genericParameter),
GeneratorHelper.GetAbiType(genericParameter, mapper),
genericParameter.TypeKind));
isNullable ? TypeKind.Interface : genericParameter.TypeKind));
}

genericInterfacesToAddToVtable.Add(new GenericInterface(
Expand Down
15 changes: 12 additions & 3 deletions src/Authoring/WinRT.SourceGenerator/Helper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -708,7 +708,7 @@ public static string GetAbiType(ITypeSymbol type, TypeMapper mapper)
return "ABI.System.Exception";
}

if (type.IsValueType)
if (type.IsValueType && !type.NullableAnnotation.HasFlag(NullableAnnotation.Annotated))
{
string customTypeMapKey = string.Join(".", type.ContainingNamespace.ToDisplayString(), type.MetadataName);
if (mapper.HasMappingForType(customTypeMapKey))
Expand Down Expand Up @@ -912,8 +912,8 @@ public static string GetCreateMarshaler(GenericParameter genericParameter, strin

public static string GetCreateMarshaler(string type, string abiType, TypeKind kind, string arg)
{
if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) ||
type == "bool" ||
if (kind == TypeKind.Enum || (kind == TypeKind.Struct && type == abiType) ||
type == "bool" ||
type == "char")
{
return "";
Expand All @@ -923,6 +923,11 @@ public static string GetCreateMarshaler(string type, string abiType, TypeKind ki
// TODO: Consider switching to pinning
return $$"""__{{arg}} = MarshalString.CreateMarshaler({{arg}});""";
}
else if (kind == TypeKind.Struct)
{
string marshalerClass = GetMarshalerClass(type, abiType, kind, false);
return $$"""__{{arg}} = {{marshalerClass}}.CreateMarshaler({{arg}});""";
}
else
{
string marshalerClass = GetMarshalerClass(type, abiType, kind, false);
Expand Down Expand Up @@ -1001,6 +1006,10 @@ public static string GetMarshalerDeclaration(string type, string abiType, TypeKi
{
return "";
}
else if (kind == TypeKind.Struct)
{
return $"{GetAbiMarshalerType(type, abiType, kind, false)}.Marshaler __{arg} = default;";
}
else
{
return $"{GetAbiMarshalerType(type, abiType, kind, false)} __{arg} = default;";
Expand Down
15 changes: 15 additions & 0 deletions src/Tests/FunctionalTests/Async/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using TestComponentCSharp;
using Windows.Foundation;
using Windows.Storage.Streams;
using Windows.Web.Http;
using WinRT;

var instance = new Class();
Expand Down Expand Up @@ -119,6 +120,20 @@
return 113;
}

bool progressCalledWithExpectedResults = false;
var asyncProgressHandler = new AsyncActionProgressHandler<HttpProgress>((info, progress) =>
{
if (progress.BytesReceived == 3 && progress.TotalBytesToReceive == 4)
{
progressCalledWithExpectedResults = true;
}
});
Class.UnboxAndCallProgressHandler(asyncProgressHandler);
if (!progressCalledWithExpectedResults)
{
return 114;
}

return 100;

static async Task<int> InvokeAddAsync(Class instance, int lhs, int rhs)
Expand Down
11 changes: 11 additions & 0 deletions src/Tests/FunctionalTests/CCW/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
using System.Windows.Input;
using System.Runtime.InteropServices;
using System.Collections.Specialized;
using Windows.Foundation;
using Windows.Web.Http;

var managedProperties = new ManagedProperties(42);
var instance = new Class();
Expand Down Expand Up @@ -178,6 +180,15 @@
var notifyCollectionChangedActionList = new List<NotifyCollectionChangedAction>();
instance.BindableIterableProperty = notifyCollectionChangedActionList;

var nullableDoubleList = new List<double?>();
instance.BindableIterableProperty = nullableDoubleList;

var nullableDoubleList2 = new List<System.Nullable<double>>();
instance.BindableIterableProperty = nullableDoubleList2;

var nullableHandleList = new List<GCHandle?>();
instance.BindableIterableProperty = nullableHandleList;

var customCommand = new CustomCommand() as ICommand;
ccw = MarshalInspectable<object>.CreateMarshaler(customCommand);
ccw.TryAs<IUnknownVftbl>(ABI.System.Windows.Input.ICommandMethods.IID, out var commandCCW);
Expand Down
23 changes: 23 additions & 0 deletions src/Tests/FunctionalTests/Collections/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -241,6 +241,29 @@
return 101;
}

var nullableDoubleList = new List<double?>() { 1, 2, null, 3, 4, null};
var result = instance.Calculate(nullableDoubleList);
if (result != 10)
{
return 101;
}

sum = 0;

var nullableIntList = instance.GetNullableIntList();
foreach (var num in nullableIntList)
{
if (num.HasValue)
{
sum += num.Value;
}
}

if (sum != 3)
{
return 101;
}

return 100;

static bool SequencesEqual<T>(IEnumerable<T> x, params IEnumerable<T>[] list) => list.All((y) => x.SequenceEqual(y));
Expand Down
27 changes: 27 additions & 0 deletions src/Tests/TestComponentCSharp/Class.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1805,6 +1805,33 @@ namespace winrt::TestComponentCSharp::implementation
throw hresult_not_implemented();
}

void Class::UnboxAndCallProgressHandler(WF::IInspectable const& httpProgressHandler)
{
Windows::Web::Http::HttpProgress progress;
progress.BytesReceived = 3;
progress.TotalBytesToReceive = 4;

winrt::unbox_value<Windows::Foundation::AsyncActionProgressHandler<Windows::Web::Http::HttpProgress>>(httpProgressHandler)(nullptr, progress);
}

double Class::Calculate(winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IReference<double>> const& values)
{
double result = 0;
for (auto val : values)
{
if (val)
{
result += val.Value();
}
}
return result;
}

winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IReference<int32_t>> Class::GetNullableIntList()
{
return single_threaded_vector<winrt::Windows::Foundation::IReference<int32_t>>({ 1, nullptr, 2 });
}

TestComponentCSharp::IProperties1 Class::NativeProperties1()
{
struct native_properties1 : winrt::implements<native_properties1, TestComponentCSharp::IProperties1>
Expand Down
4 changes: 4 additions & 0 deletions src/Tests/TestComponentCSharp/Class.h
Original file line number Diff line number Diff line change
Expand Up @@ -406,6 +406,10 @@ namespace winrt::TestComponentCSharp::implementation
static com_array<bool> UnboxBooleanArray(IInspectable const& obj);
static com_array<hstring> UnboxStringArray(IInspectable const& obj);

static void UnboxAndCallProgressHandler(IInspectable const& httpProgressHandler);
double Calculate(winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IReference<double>> const& values);
winrt::Windows::Foundation::Collections::IVector<winrt::Windows::Foundation::IReference<int32_t>> GetNullableIntList();

static int GetPropertyType(Windows::Foundation::IInspectable const& obj);
static hstring GetName(Windows::Foundation::IInspectable const& obj);

Expand Down
4 changes: 4 additions & 0 deletions src/Tests/TestComponentCSharp/TestComponentCSharp.idl
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ namespace TestComponentCSharp
// HResult->Exception type mapping
Windows.Foundation.HResult HResultProperty;

Double Calculate(Windows.Foundation.Collections.IVector<Windows.Foundation.IReference<Double> > values);
Windows.Foundation.Collections.IVector<Windows.Foundation.IReference<Int32> > GetNullableIntList();

// Boxing
static Int32 UnboxInt32(Object obj);
static Boolean UnboxBoolean(Object obj);
Expand All @@ -436,6 +439,7 @@ namespace TestComponentCSharp
static Object BoxedDelegate{ get; };
static Object BoxedEnum{ get; };
static Object BoxedEventHandler{ get; };
static void UnboxAndCallProgressHandler(Object httpProgressHandler);

static Int32 GetPropertyType(Object obj);
static String GetName(Object obj);
Expand Down
1 change: 1 addition & 0 deletions src/Tests/TestComponentCSharp/pch.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
#include <winrt/Microsoft.UI.Xaml.Interop.h>
#include <winrt/Microsoft.UI.Xaml.Markup.h>
#include <winrt/Microsoft.UI.Xaml.Navigation.h>
#include <winrt/Windows.Web.Http.h>

// TODO: Replace with latest Cpp/WinRT
namespace winrt
Expand Down
25 changes: 25 additions & 0 deletions src/WinRT.Runtime/Marshalers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2120,6 +2120,31 @@ static Marshaler()
CopyManagedArray = MarshalGenericHelper<T>.CopyManagedArray;
DisposeMarshalerArray = MarshalInterface<T>.DisposeMarshalerArray;
DisposeAbiArray = MarshalInterface<T>.DisposeAbiArray;
#if !NET
RefAbiType = AbiType.MakeByRefType();
#endif

return;
}
else if (typeof(T).IsNullableT())
{
AbiType = typeof(IntPtr);
CreateMarshaler = (T value) => MarshalInterface<T>.CreateMarshaler2(value);
CreateMarshaler2 = CreateMarshaler;
GetAbi = (object objRef) => objRef is ObjectReferenceValue objRefValue ?
MarshalInspectable<object>.GetAbi(objRefValue) : MarshalInterface<T>.GetAbi((IObjectReference)objRef);
FromAbi = (object value) => MarshalInterface<T>.FromAbi((IntPtr)value);
FromManaged = (T value) => MarshalInterface<T>.CreateMarshaler2(value).Detach();
DisposeMarshaler = MarshalInterface<T>.DisposeMarshaler;
DisposeAbi = (object box) => MarshalInterface<T>.DisposeAbi((IntPtr)box);
CreateMarshalerArray = (T[] array) => MarshalInterface<T>.CreateMarshalerArray(array);
GetAbiArray = MarshalInterface<T>.GetAbiArray;
FromAbiArray = MarshalInterface<T>.FromAbiArray;
FromManagedArray = MarshalInterface<T>.FromManagedArray;
CopyManagedArray = MarshalInterface<T>.CopyManagedArray;
DisposeMarshalerArray = MarshalInterface<T>.DisposeMarshalerArray;
DisposeAbiArray = MarshalInterface<T>.DisposeAbiArray;

#if !NET
RefAbiType = AbiType.MakeByRefType();
#endif
Expand Down

0 comments on commit eb67781

Please sign in to comment.