Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

use a connected type rather than one single type #201

Merged
merged 2 commits into from
Jan 24, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions swiftwinrt/Resources/Support/MakeFromAbi.swift
Original file line number Diff line number Diff line change
Expand Up @@ -4,14 +4,15 @@ import Foundation
// when we cast to `any MakeFromAbi`, plus that requires a lot more exported
// simples than we want
public protocol MakeFromAbi {
static func from(typeName: String, abi: SUPPORT_MODULE.IInspectable) -> Any?
associatedtype SwiftType
static func from(abi: SUPPORT_MODULE.IInspectable) -> SwiftType
}

func make(typeName: SwiftTypeName, from abi: SUPPORT_MODULE.IInspectable) -> Any? {
guard let makerType = NSClassFromString("\(typeName.module).__MakeFromAbi") as? any MakeFromAbi.Type else {
guard let makerType = NSClassFromString("\(typeName.module).\(typeName.typeName)Maker") as? any MakeFromAbi.Type else {
return nil
}
return makerType.from(typeName: typeName.typeName, abi: abi)
return makerType.from(abi: abi)
}

func makeFrom(abi: SUPPORT_MODULE.IInspectable) -> Any? {
Expand Down
34 changes: 20 additions & 14 deletions swiftwinrt/code_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -1203,31 +1203,37 @@ bind_bridge_fullname(type));
return true;
}

static void write_make_from_abi_case(writer& w, metadata_type const& type)
{
if (skip_write_from_abi(w, type)) return;
w.write("case \"%\": return make%From(abi: abi)\n", type.swift_type_name(), type.swift_type_name());
}

static void write_make_from_abi(writer& w, metadata_type const& type)
{
if (skip_write_from_abi(w, type)) return;

w.write("fileprivate func make%From(abi: %.IInspectable) -> Any {\n", type.swift_type_name(), w.support);

std::string fromAbi;
std::string swiftType;
if (is_interface(type))
{
auto indent = w.push_indent();
w.write("let swiftAbi: %.% = try! abi.QueryInterface()\n", abi_namespace(type),
fromAbi = w.write_temp("let swiftAbi: %.% = try! abi.QueryInterface()\n", abi_namespace(type),
type.swift_type_name());
w.write("return %.from(abi: RawPointer(swiftAbi))!\n", bind_bridge_fullname(type));
fromAbi += w.write_temp(" return %.from(abi: RawPointer(swiftAbi))!", bind_bridge_fullname(type));
swiftType = w.write_temp("%", bind<write_swift_interface_existential_identifier>(type));
}
else if (is_class(&type))
{
auto indent = w.push_indent();
w.write("return %(fromAbi: abi)\n", type.swift_type_name());
fromAbi = w.write_temp("return %(fromAbi: abi)", type.swift_type_name());
swiftType = w.write_temp("%", bind<write_swift_type_identifier>(type));
}
w.write("}\n\n");
else
{
throw std::exception("Invalid type for MakeFromAbi");
}

w.write(R"(^@_spi(WinRTInternal)
public class %Maker: MakeFromAbi {
public typealias SwiftType = %
public static func from(abi: %.IInspectable) -> SwiftType {
%
}
}
)", type.swift_type_name(), swiftType, w.support, fromAbi);
}

static void write_interface_bridge(writer& w, metadata_type const& type)
Expand Down
36 changes: 4 additions & 32 deletions swiftwinrt/file_writers.h
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,10 @@ namespace swiftwinrt

w.write("%", w.filter.bind_each<write_struct_bridgeable>(members.structs));

// MakeFromAbi has to be in impl file (or main file) otherwise they get stripped away
w.write("%", w.filter.bind_each<write_make_from_abi>(members.interfaces));
w.write("%", w.filter.bind_each<write_make_from_abi>(members.classes));

w.swap();
write_preamble(w, /* swift_code: */ true);

Expand Down Expand Up @@ -274,36 +278,4 @@ namespace swiftwinrt
write_preamble(w, /* swift_code: */ true);
w.save_file("Generics");
}

static void write_module_make_from_abi(std::string_view const& module, type_cache const& members, include_only_used_filter const& filter)
{
writer w;
w.filter = filter;
w.support = settings.support;
w.c_mod = settings.get_c_module_name();
w.type_namespace = module;
w.swift_module = module;
w.cache = members.cache;
w.write("%", w.filter.bind_each<write_make_from_abi>(members.interfaces));
w.write("%", w.filter.bind_each<write_make_from_abi>(members.classes));

w.write("@_spi(__MakeFromAbi_DoNotImport)\n");
w.write("public class __MakeFromAbi: MakeFromAbi {\n");
w.write(" public static func from(typeName: String, abi: %.IInspectable) -> Any? {\n", w.support);
w.write(" switch typeName {\n");
{
auto indent_guard = w.push_indent(indent{ 3 });
w.write("%", w.filter.bind_each<write_make_from_abi_case>(members.interfaces));
w.write("%", w.filter.bind_each<write_make_from_abi_case>(members.classes));
}

w.write(" default: return nil\n");
w.write(" }\n");
w.write(" }\n");
w.write("}\n");

w.swap();
write_preamble(w, /* swift_code: */ true);
w.save_file("MakeFromAbi");
}
}
1 change: 0 additions & 1 deletion swiftwinrt/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -363,7 +363,6 @@ Where <spec> is one or more of:
// amount of code that is generated.
auto types = mdCache.compile_namespaces(namespaces, mf);
write_module_generics(module, types, mf);
write_module_make_from_abi(module, types, mf);
});

if (module == settings.support)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -547,3 +547,87 @@ extension TimeSpan: WinRTBridgeable {
}
}

@_spi(WinRTInternal)
public class IAsyncActionMaker: MakeFromAbi {
public typealias SwiftType = AnyIAsyncAction
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IAsyncAction = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IAsyncActionBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IAsyncInfoMaker: MakeFromAbi {
public typealias SwiftType = AnyIAsyncInfo
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IAsyncInfo = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IAsyncInfoBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IClosableMaker: MakeFromAbi {
public typealias SwiftType = AnyIClosable
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IClosable = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IClosableBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IMemoryBufferMaker: MakeFromAbi {
public typealias SwiftType = AnyIMemoryBuffer
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IMemoryBuffer = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IMemoryBufferBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IMemoryBufferReferenceMaker: MakeFromAbi {
public typealias SwiftType = AnyIMemoryBufferReference
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IMemoryBufferReference = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IMemoryBufferReferenceBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IStringableMaker: MakeFromAbi {
public typealias SwiftType = AnyIStringable
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IStringable = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IStringableBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IWwwFormUrlDecoderEntryMaker: MakeFromAbi {
public typealias SwiftType = AnyIWwwFormUrlDecoderEntry
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation.IWwwFormUrlDecoderEntry = try! abi.QueryInterface()
return __IMPL_Windows_Foundation.IWwwFormUrlDecoderEntryBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class DeferralMaker: MakeFromAbi {
public typealias SwiftType = Deferral
public static func from(abi: test_component.IInspectable) -> SwiftType {
return Deferral(fromAbi: abi)
}
}
@_spi(WinRTInternal)
public class MemoryBufferMaker: MakeFromAbi {
public typealias SwiftType = MemoryBuffer
public static func from(abi: test_component.IInspectable) -> SwiftType {
return MemoryBuffer(fromAbi: abi)
}
}
@_spi(WinRTInternal)
public class UriMaker: MakeFromAbi {
public typealias SwiftType = Uri
public static func from(abi: test_component.IInspectable) -> SwiftType {
return Uri(fromAbi: abi)
}
}
@_spi(WinRTInternal)
public class WwwFormUrlDecoderMaker: MakeFromAbi {
public typealias SwiftType = WwwFormUrlDecoder
public static func from(abi: test_component.IInspectable) -> SwiftType {
return WwwFormUrlDecoder(fromAbi: abi)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,3 +152,40 @@ public enum __IMPL_Windows_Foundation_Collections {
}

}
@_spi(WinRTInternal)
public class IPropertySetMaker: MakeFromAbi {
public typealias SwiftType = AnyIPropertySet
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation_Collections.IPropertySet = try! abi.QueryInterface()
return __IMPL_Windows_Foundation_Collections.IPropertySetBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class IVectorChangedEventArgsMaker: MakeFromAbi {
public typealias SwiftType = AnyIVectorChangedEventArgs
public static func from(abi: test_component.IInspectable) -> SwiftType {
let swiftAbi: __ABI_Windows_Foundation_Collections.IVectorChangedEventArgs = try! abi.QueryInterface()
return __IMPL_Windows_Foundation_Collections.IVectorChangedEventArgsBridge.from(abi: RawPointer(swiftAbi))!
}
}
@_spi(WinRTInternal)
public class PropertySetMaker: MakeFromAbi {
public typealias SwiftType = PropertySet
public static func from(abi: test_component.IInspectable) -> SwiftType {
return PropertySet(fromAbi: abi)
}
}
@_spi(WinRTInternal)
public class StringMapMaker: MakeFromAbi {
public typealias SwiftType = StringMap
public static func from(abi: test_component.IInspectable) -> SwiftType {
return StringMap(fromAbi: abi)
}
}
@_spi(WinRTInternal)
public class ValueSetMaker: MakeFromAbi {
public typealias SwiftType = ValueSet
public static func from(abi: test_component.IInspectable) -> SwiftType {
return ValueSet(fromAbi: abi)
}
}
Loading