Skip to content

Commit

Permalink
use a connected type rather than one single type (#201)
Browse files Browse the repository at this point in the history
* use a connected type rather than one single type

* remove makefromabi file
  • Loading branch information
stevenbrix authored Jan 24, 2025
1 parent 35e2ea1 commit b3d535c
Show file tree
Hide file tree
Showing 12 changed files with 693 additions and 550 deletions.
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

0 comments on commit b3d535c

Please sign in to comment.