Skip to content

Commit

Permalink
Streamline TypeName to support pattern matching (#3040)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored May 15, 2024
1 parent a036ce6 commit 5b16029
Show file tree
Hide file tree
Showing 4 changed files with 76 additions and 86 deletions.
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,10 +186,10 @@ fn namespace(writer: &Writer, tree: &Tree) -> String {
match item {
metadata::Item::Type(def) => {
let type_name = def.type_name();
if writer.reader.remap_type(&type_name).is_some() {
if writer.reader.remap_type(type_name).is_some() {
continue;
}
if writer.reader.core_type(&type_name).is_some() {
if writer.reader.core_type(type_name).is_some() {
continue;
}
types.entry(def.kind()).or_default().entry(type_name.name()).or_default().combine(&writer.type_def(def));
Expand Down Expand Up @@ -230,7 +230,7 @@ fn namespace_impl(writer: &Writer, tree: &Tree) -> String {
for item in writer.reader.namespace_items(tree.namespace) {
if let metadata::Item::Type(def) = item {
let type_name = def.type_name();
if writer.reader.core_type(&type_name).is_some() {
if writer.reader.core_type(type_name).is_some() {
continue;
}
if def.kind() != metadata::TypeKind::Interface {
Expand Down
57 changes: 27 additions & 30 deletions crates/libs/metadata/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,15 +140,32 @@ impl Reader {
self.nested.get(&type_def).map(|map| map.values().copied()).into_iter().flatten()
}

pub fn remap_type(&self, type_name: &TypeName) -> Option<TypeName> {
REMAP_TYPES.iter().find_map(|(key, value)| (type_name == key).then(|| value.clone()))
pub fn remap_type(&self, name: TypeName) -> Option<TypeName> {
match name {
TypeName::D2D_MATRIX_3X2_F => Some(TypeName::Matrix3x2),
TypeName::D3DMATRIX => Some(TypeName::Matrix4x4),
TypeName::HRESULT => Some(TypeName::HResult),
_ => None,
}
}

pub fn core_type(&self, type_name: &TypeName) -> Option<Type> {
if self.sys {
SYS_CORE_TYPES.iter().find_map(|(key, value)| (type_name == key).then(|| value.clone()))
} else {
CORE_TYPES.iter().find_map(|(key, value)| (type_name == key).then(|| value.clone()))
pub fn core_type(&self, name: TypeName) -> Option<Type> {
match name {
TypeName::HSTRING => Some(Type::String),
TypeName::IInspectable => Some(Type::Object),
TypeName::CHAR => Some(Type::I8),

TypeName::GUID => Some(Type::Name(name)),
TypeName::IUnknown => Some(Type::Name(name)),
TypeName::HResult => Some(Type::Name(name)),
TypeName::BSTR => Some(Type::Name(name)),
TypeName::PSTR => Some(Type::Name(name)),
TypeName::PWSTR => Some(Type::Name(name)),
TypeName::Type => Some(Type::Name(name)),
TypeName::VARIANT if !self.sys => Some(Type::Name(name)),
TypeName::PROPVARIANT if !self.sys => Some(Type::Name(name)),

_ => None,
}
}

Expand All @@ -160,11 +177,11 @@ impl Reader {

let mut full_name = code.type_name();

if let Some(to) = self.remap_type(&full_name) {
full_name = to.clone();
if let Some(to) = self.remap_type(full_name) {
full_name = to;
}

if let Some(kind) = self.core_type(&full_name) {
if let Some(kind) = self.core_type(full_name) {
return kind;
}

Expand Down Expand Up @@ -258,23 +275,3 @@ impl Reader {
}
}
}

// TODO: this should be in riddle's Rust generator if at all - perhaps as convertible types rather than remapped types since there's already some precedent for that.
const REMAP_TYPES: [(TypeName, TypeName); 3] = [(TypeName::D2D_MATRIX_3X2_F, TypeName::Matrix3x2), (TypeName::D3DMATRIX, TypeName::Matrix4x4), (TypeName::HRESULT, TypeName::HResult)];

// TODO: get rid of at least the second tuple if not the whole thing.
const CORE_TYPES: [(TypeName, Type); 12] = [
(TypeName::GUID, Type::Name(TypeName::GUID)),
(TypeName::IUnknown, Type::Name(TypeName::IUnknown)),
(TypeName::HResult, Type::Name(TypeName::HResult)),
(TypeName::HSTRING, Type::String),
(TypeName::BSTR, Type::Name(TypeName::BSTR)),
(TypeName::IInspectable, Type::Object),
(TypeName::PSTR, Type::Name(TypeName::PSTR)),
(TypeName::PWSTR, Type::Name(TypeName::PWSTR)),
(TypeName::Type, Type::Name(TypeName::Type)),
(TypeName::CHAR, Type::I8),
(TypeName::VARIANT, Type::Name(TypeName::VARIANT)),
(TypeName::PROPVARIANT, Type::Name(TypeName::PROPVARIANT)),
];
const SYS_CORE_TYPES: [(TypeName, Type); 10] = [(TypeName::GUID, Type::Name(TypeName::GUID)), (TypeName::IUnknown, Type::Name(TypeName::IUnknown)), (TypeName::HResult, Type::Name(TypeName::HResult)), (TypeName::HSTRING, Type::String), (TypeName::BSTR, Type::Name(TypeName::BSTR)), (TypeName::IInspectable, Type::Object), (TypeName::PSTR, Type::Name(TypeName::PSTR)), (TypeName::PWSTR, Type::Name(TypeName::PWSTR)), (TypeName::Type, Type::Name(TypeName::Type)), (TypeName::CHAR, Type::I8)];
4 changes: 2 additions & 2 deletions crates/libs/metadata/src/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ impl TypeDef {
}

pub fn type_name(&self) -> TypeName {
TypeName::new(self.namespace(), self.name())
TypeName(self.namespace(), self.name())
}

pub fn extends(&self) -> Option<TypeName> {
Expand Down Expand Up @@ -413,7 +413,7 @@ impl TypeRef {
}

pub fn type_name(&self) -> TypeName {
TypeName::new(self.namespace(), self.name())
TypeName(self.namespace(), self.name())
}

pub fn resolution_scope(&self) -> ResolutionScope {
Expand Down
95 changes: 44 additions & 51 deletions crates/libs/metadata/src/type_name.rs
Original file line number Diff line number Diff line change
@@ -1,77 +1,70 @@
#![allow(non_upper_case_globals)]

#[derive(Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
pub struct TypeName {
namespace: &'static str,
name: &'static str,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, Ord, PartialOrd)]
pub struct TypeName(pub &'static str, pub &'static str);

impl TypeName {
pub const Enum: Self = Self::new("System", "Enum");
pub const Delegate: Self = Self::new("System", "MulticastDelegate");
pub const Struct: Self = Self::new("System", "ValueType");
pub const Object: Self = Self::new("System", "Object");
pub const GUID: Self = Self::new("System", "Guid");
pub const Type: Self = Self::new("System", "Type");
pub const Attribute: Self = Self::new("System", "Attribute");
pub const IsConst: Self = Self::new("System.Runtime.CompilerServices", "IsConst");

pub const HResult: Self = Self::new("Windows.Foundation", "HResult");
pub const IAsyncAction: Self = Self::new("Windows.Foundation", "IAsyncAction");
pub const IAsyncActionWithProgress: Self = Self::new("Windows.Foundation", "IAsyncActionWithProgress");
pub const IAsyncOperation: Self = Self::new("Windows.Foundation", "IAsyncOperation");
pub const IAsyncOperationWithProgress: Self = Self::new("Windows.Foundation", "IAsyncOperationWithProgress");
pub const Enum: Self = Self("System", "Enum");
pub const Delegate: Self = Self("System", "MulticastDelegate");
pub const Struct: Self = Self("System", "ValueType");
pub const Object: Self = Self("System", "Object");
pub const GUID: Self = Self("System", "Guid");
pub const Type: Self = Self("System", "Type");
pub const Attribute: Self = Self("System", "Attribute");
pub const IsConst: Self = Self("System.Runtime.CompilerServices", "IsConst");

pub const Matrix3x2: Self = Self::new("Windows.Foundation.Numerics", "Matrix3x2");
pub const Matrix4x4: Self = Self::new("Windows.Foundation.Numerics", "Matrix4x4");
pub const HResult: Self = Self("Windows.Foundation", "HResult");
pub const IAsyncAction: Self = Self("Windows.Foundation", "IAsyncAction");
pub const IAsyncActionWithProgress: Self = Self("Windows.Foundation", "IAsyncActionWithProgress");
pub const IAsyncOperation: Self = Self("Windows.Foundation", "IAsyncOperation");
pub const IAsyncOperationWithProgress: Self = Self("Windows.Foundation", "IAsyncOperationWithProgress");

pub const IIterable: Self = Self::new("Windows.Foundation.Collections", "IIterable");
pub const IIterator: Self = Self::new("Windows.Foundation.Collections", "IIterator");
pub const IVectorView: Self = Self::new("Windows.Foundation.Collections", "IVectorView");
pub const IVector: Self = Self::new("Windows.Foundation.Collections", "IVector");
pub const Matrix3x2: Self = Self("Windows.Foundation.Numerics", "Matrix3x2");
pub const Matrix4x4: Self = Self("Windows.Foundation.Numerics", "Matrix4x4");

pub const PWSTR: Self = Self::new("Windows.Win32.Foundation", "PWSTR");
pub const PSTR: Self = Self::new("Windows.Win32.Foundation", "PSTR");
pub const BSTR: Self = Self::new("Windows.Win32.Foundation", "BSTR");
pub const HANDLE: Self = Self::new("Windows.Win32.Foundation", "HANDLE");
pub const HRESULT: Self = Self::new("Windows.Win32.Foundation", "HRESULT");
pub const CHAR: Self = Self::new("Windows.Win32.Foundation", "CHAR");
pub const BOOL: Self = Self::new("Windows.Win32.Foundation", "BOOL");
pub const WIN32_ERROR: Self = Self::new("Windows.Win32.Foundation", "WIN32_ERROR");
pub const NTSTATUS: Self = Self::new("Windows.Win32.Foundation", "NTSTATUS");
pub const RPC_STATUS: Self = Self::new("Windows.Win32.System.Rpc", "RPC_STATUS");
pub const IIterable: Self = Self("Windows.Foundation.Collections", "IIterable");
pub const IIterator: Self = Self("Windows.Foundation.Collections", "IIterator");
pub const IVectorView: Self = Self("Windows.Foundation.Collections", "IVectorView");
pub const IVector: Self = Self("Windows.Foundation.Collections", "IVector");

pub const D2D_MATRIX_3X2_F: Self = Self::new("Windows.Win32.Graphics.Direct2D.Common", "D2D_MATRIX_3X2_F");
pub const D3DMATRIX: Self = Self::new("Windows.Win32.Graphics.Direct3D", "D3DMATRIX");
pub const IUnknown: Self = Self::new("Windows.Win32.System.Com", "IUnknown");
pub const HSTRING: Self = Self::new("Windows.Win32.System.WinRT", "HSTRING");
pub const IInspectable: Self = Self::new("Windows.Win32.System.WinRT", "IInspectable");
pub const IRestrictedErrorInfo: Self = Self::new("Windows.Win32.System.WinRT", "IRestrictedErrorInfo");
pub const IDispatch: Self = Self::new("Windows.Win32.System.Com", "IDispatch");
pub const PWSTR: Self = Self("Windows.Win32.Foundation", "PWSTR");
pub const PSTR: Self = Self("Windows.Win32.Foundation", "PSTR");
pub const BSTR: Self = Self("Windows.Win32.Foundation", "BSTR");
pub const HANDLE: Self = Self("Windows.Win32.Foundation", "HANDLE");
pub const HRESULT: Self = Self("Windows.Win32.Foundation", "HRESULT");
pub const CHAR: Self = Self("Windows.Win32.Foundation", "CHAR");
pub const BOOL: Self = Self("Windows.Win32.Foundation", "BOOL");
pub const WIN32_ERROR: Self = Self("Windows.Win32.Foundation", "WIN32_ERROR");
pub const NTSTATUS: Self = Self("Windows.Win32.Foundation", "NTSTATUS");
pub const RPC_STATUS: Self = Self("Windows.Win32.System.Rpc", "RPC_STATUS");

pub const VARIANT: Self = Self::new("Windows.Win32.System.Variant", "VARIANT");
pub const PROPVARIANT: Self = Self::new("Windows.Win32.System.Com.StructuredStorage", "PROPVARIANT");
pub const D2D_MATRIX_3X2_F: Self = Self("Windows.Win32.Graphics.Direct2D.Common", "D2D_MATRIX_3X2_F");
pub const D3DMATRIX: Self = Self("Windows.Win32.Graphics.Direct3D", "D3DMATRIX");
pub const IUnknown: Self = Self("Windows.Win32.System.Com", "IUnknown");
pub const HSTRING: Self = Self("Windows.Win32.System.WinRT", "HSTRING");
pub const IInspectable: Self = Self("Windows.Win32.System.WinRT", "IInspectable");
pub const IRestrictedErrorInfo: Self = Self("Windows.Win32.System.WinRT", "IRestrictedErrorInfo");
pub const IDispatch: Self = Self("Windows.Win32.System.Com", "IDispatch");

pub const fn new(namespace: &'static str, name: &'static str) -> Self {
Self { namespace, name }
}
pub const VARIANT: Self = Self("Windows.Win32.System.Variant", "VARIANT");
pub const PROPVARIANT: Self = Self("Windows.Win32.System.Com.StructuredStorage", "PROPVARIANT");

pub fn parse(full_name: &'static str) -> Self {
let index = full_name.rfind('.').expect("Expected full name separated with `.`");
Self::new(&full_name[0..index], &full_name[index + 1..])
Self(&full_name[0..index], &full_name[index + 1..])
}

pub fn namespace(&self) -> &'static str {
self.namespace
self.0
}

pub fn name(&self) -> &'static str {
self.name
self.1
}
}

impl std::fmt::Display for TypeName {
fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(fmt, "{}.{}", self.namespace, self.name)
write!(fmt, "{}.{}", self.0, self.1)
}
}

0 comments on commit 5b16029

Please sign in to comment.