Skip to content

Commit fcf37c3

Browse files
authored
Handle generic params of manually projected types (#120)
* Handle generic params of manually projected types * Update ts files
1 parent 21b9ae6 commit fcf37c3

6 files changed

Lines changed: 62 additions & 2 deletions

File tree

jswinrt/jswinrt/MetadataTypes.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,23 @@ static void handle_generic_instantiation(projection_data& data, generic_instanti
528528
if ((typeDef.TypeName() == "IReference`1"sv) || (typeDef.TypeName() == "IReferenceArray`1"sv) ||
529529
(typeDef.TypeName() == "IAsyncActionWithProgress`1"sv) || (typeDef.TypeName() == "IAsyncOperation`1"sv) ||
530530
(typeDef.TypeName() == "IAsyncOperationWithProgress`2"sv))
531+
{
532+
// All of these types are manually projected as they are handled specially in JS. Therefore we won't get the
533+
// chance to enumerate function arguments/return types below. All of the generic params for these types are
534+
// visible to JS, so just go ahead and enumerate them.
535+
auto stack = inst.stack();
536+
for (auto&& arg : inst.signature().GenericArgs())
537+
{
538+
resolve_type(arg, stack,
539+
overloaded{
540+
[&](const GenericTypeInstSig& sig, const generic_param_stack& newStack, bool) {
541+
handle_generic_instantiation(data, generic_instantiation(sig, newStack));
542+
},
543+
[&](auto&&, bool) {},
544+
});
545+
}
531546
return;
547+
}
532548
}
533549

534550
// First check to see if we've handled this type before

tests/RnWinRTTests/AsyncTests.js

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ export function makeAsyncTestScenarios(pThis) {
1515
new TestScenario('Test::CountDoubleAsync', runAsyncOperationWithProgressTest.bind(pThis)),
1616
new TestScenario('Test::ThrowAsyncException', runAsyncActionWithException.bind(pThis)),
1717
new TestScenario('Async await', runAsyncAwaitTest.bind(pThis)),
18+
new TestScenario('Test::GetObjectsAsync', runGetObjectsTest.bind(pThis)),
1819
];
1920
}
2021

@@ -255,3 +256,17 @@ function runAsyncAwaitTest(scenario) {
255256
}
256257
});
257258
}
259+
260+
function runGetObjectsTest(scenario) {
261+
this.runAsync(scenario, async (resolve, reject) => {
262+
try
263+
{
264+
var result = await TestComponent.Test.getObjectsAsync();
265+
assert.equal(42, result[0].magicValue);
266+
267+
resolve();
268+
} catch (err) {
269+
reject(err);
270+
}
271+
});
272+
}

tests/RnWinRTTests/windows/TestComponent/Test.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1571,11 +1571,18 @@ namespace winrt::TestComponent::implementation
15711571
throw std::invalid_argument("test");
15721572
}
15731573

1574-
Windows::Foundation::IAsyncOperation<int32_t> Test::ImmediateReturnAsync(int32_t value)
1574+
IAsyncOperation<int32_t> Test::ImmediateReturnAsync(int32_t value)
15751575
{
15761576
co_return value;
15771577
}
15781578

1579+
IAsyncOperation<IVectorView<ITestInterface>> Test::GetObjectsAsync()
1580+
{
1581+
std::vector<ITestInterface> result;
1582+
result.push_back(winrt::make_self<TestObject>(1).as<ITestInterface>());
1583+
co_return winrt::single_threaded_vector(std::move(result)).as<IVectorView<ITestInterface>>();
1584+
}
1585+
15791586
bool Test::BoolProperty()
15801587
{
15811588
return m_boolProperty;

tests/RnWinRTTests/windows/TestComponent/Test.h

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
namespace winrt::TestComponent::implementation
77
{
8-
struct TestObject : TestObjectT<TestObject>
8+
struct TestObject : TestObjectT<TestObject, ITestInterface>
99
{
1010
TestObject(int32_t val) : m_value(val)
1111
{
@@ -16,6 +16,11 @@ namespace winrt::TestComponent::implementation
1616
return m_value;
1717
}
1818

19+
int32_t MagicValue()
20+
{
21+
return 42;
22+
}
23+
1924
private:
2025
int32_t m_value;
2126
};
@@ -376,6 +381,9 @@ namespace winrt::TestComponent::implementation
376381
static Windows::Foundation::IAsyncOperationWithProgress<int32_t, int32_t> CountDoubleAsync(int32_t value);
377382
static Windows::Foundation::IAsyncAction ThrowAsyncException();
378383
static Windows::Foundation::IAsyncOperation<int32_t> ImmediateReturnAsync(int32_t value);
384+
static Windows::Foundation::IAsyncOperation<
385+
Windows::Foundation::Collections::IVectorView<TestComponent::ITestInterface>>
386+
GetObjectsAsync();
379387

380388
bool BoolProperty();
381389
void BoolProperty(bool value);

tests/RnWinRTTests/windows/TestComponent/TestComponent.idl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ namespace TestComponent
6969
Int32 Value{ get; };
7070
}
7171

72+
[contract(TestContract, 1)]
73+
interface ITestInterface
74+
{
75+
Int32 MagicValue { get; }; // 42
76+
}
77+
7278
// Delegates
7379
delegate Boolean BoolDelegate(Boolean value);
7480
delegate Char CharDelegate(Char value);
@@ -581,6 +587,9 @@ namespace TestComponent
581587
void RaiseCompositeStructEvent(CompositeType value);
582588
void RaiseRefEvent(Windows.Foundation.IReference<Int32> value);
583589
void RaiseObjectEvent(TestObject value);
590+
591+
// Used to validate the fix to https://github.com/microsoft/jswinrt/issues/119
592+
static Windows.Foundation.IAsyncOperation<Windows.Foundation.Collections.IVectorView<ITestInterface> > GetObjectsAsync();
584593
}
585594

586595
[contract(TestContract, 1)]

tests/TestArtifacts/TestComponent.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,10 @@ declare namespace TestComponent {
5858
public overloadedHierarchyBaseMethod(param1: string, param2: string): string;
5959
}
6060

61+
interface ITestInterface {
62+
readonly magicValue: number;
63+
}
64+
6165
type InterwovenDelegate = (inBool: boolean, inNumeric: number, inArray: number[]) => { outBool: boolean; outNumeric: number; outArray: number[]; fillArray: number[]; returnValue: number };
6266

6367
type NumericArrayDelegate = (values: number[]) => { subset: number[]; outValue: number[]; returnValue: number[] };
@@ -435,6 +439,7 @@ declare namespace TestComponent {
435439
public static countDoubleAsync(value: number): Windows.Foundation.WinRTPromise<number, number>;
436440
public static throwAsyncException(): Windows.Foundation.WinRTPromise<void, void>;
437441
public static immediateReturnAsync(value: number): Windows.Foundation.WinRTPromise<number, void>;
442+
public static getObjectsAsync(): Windows.Foundation.WinRTPromise<Windows.Foundation.Collections.IVectorView<TestComponent.ITestInterface>, void>;
438443
public addEventListener(type: "booleventhandler", listener: Windows.Foundation.TypedEventHandler<TestComponent.Test, boolean>): void;
439444
public removeEventListener(type: "booleventhandler", listener: Windows.Foundation.TypedEventHandler<TestComponent.Test, boolean>): void;
440445
public addEventListener(type: "chareventhandler", listener: Windows.Foundation.TypedEventHandler<TestComponent.Test, string>): void;

0 commit comments

Comments
 (0)