Skip to content

Commit

Permalink
Prep for type name deferral (#2955)
Browse files Browse the repository at this point in the history
  • Loading branch information
kennykerr authored Mar 26, 2024
1 parent fcb6f2b commit 927aa84
Show file tree
Hide file tree
Showing 14 changed files with 104 additions and 108 deletions.
16 changes: 8 additions & 8 deletions crates/libs/bindgen/src/metadata.rs
Original file line number Diff line number Diff line change
Expand Up @@ -418,10 +418,10 @@ pub fn type_def_has_callback(row: TypeDef) -> bool {
false
}
let type_name = row.type_name();
if type_name.namespace.is_empty() {
if type_name.namespace().is_empty() {
check(row)
} else {
for row in row.reader().get_type_def(type_name.namespace, type_name.name) {
for row in row.reader().get_type_def(type_name.namespace(), type_name.name()) {
if check(row) {
return true;
}
Expand Down Expand Up @@ -473,7 +473,7 @@ pub fn type_interfaces(ty: &Type) -> Vec<Interface> {
"StaticAttribute" | "ActivatableAttribute" => {
for (_, arg) in attribute.args() {
if let Value::TypeName(type_name) = arg {
let def = row.reader().get_type_def(type_name.namespace, type_name.name).next().expect("Type not found");
let def = row.reader().get_type_def(type_name.namespace(), type_name.name()).next().expect("Type not found");
result.push(Interface { ty: Type::TypeDef(def, Vec::new()), kind: InterfaceKind::Static });
break;
}
Expand Down Expand Up @@ -601,10 +601,10 @@ pub fn type_def_has_explicit_layout(row: TypeDef) -> bool {
false
}
let type_name = row.type_name();
if type_name.namespace.is_empty() {
if type_name.namespace().is_empty() {
check(row)
} else {
for row in row.reader().get_type_def(type_name.namespace, type_name.name) {
for row in row.reader().get_type_def(type_name.namespace(), type_name.name()) {
if check(row) {
return true;
}
Expand Down Expand Up @@ -635,10 +635,10 @@ pub fn type_def_has_packing(row: TypeDef) -> bool {
false
}
let type_name = row.type_name();
if type_name.namespace.is_empty() {
if type_name.namespace().is_empty() {
check(row)
} else {
for row in row.reader().get_type_def(type_name.namespace, type_name.name) {
for row in row.reader().get_type_def(type_name.namespace(), type_name.name()) {
if check(row) {
return true;
}
Expand Down Expand Up @@ -741,7 +741,7 @@ pub fn type_def_bases(mut row: TypeDef) -> Vec<TypeDef> {
loop {
match row.extends() {
Some(base) if base != TypeName::Object => {
row = row.reader().get_type_def(base.namespace, base.name).next().expect("Type not found");
row = row.reader().get_type_def(base.namespace(), base.name()).next().expect("Type not found");
bases.push(row);
}
_ => break,
Expand Down
16 changes: 8 additions & 8 deletions crates/libs/bindgen/src/rdl/from_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,12 @@ impl Writer {

fn type_def(&self, def: metadata::TypeDef) -> TokenStream {
if let Some(extends) = def.extends() {
if extends.namespace == "System" {
if extends.name == "Enum" {
if extends.namespace() == "System" {
if extends.name() == "Enum" {
self.enum_def(def)
} else if extends.name == "ValueType" {
} else if extends.name() == "ValueType" {
self.struct_def(def)
} else if extends.name == "MulticastDelegate" {
} else if extends.name() == "MulticastDelegate" {
self.delegate_def(def)
} else {
self.class_def(def)
Expand Down Expand Up @@ -294,8 +294,8 @@ impl Writer {

if let Some(type_name) = def.extends() {
if type_name != metadata::TypeName::Object {
let namespace = self.namespace(type_name.namespace);
let name = to_ident(type_name.name);
let namespace = self.namespace(type_name.namespace());
let name = to_ident(type_name.name());
// TODO: ideally the "class" contextual keyword wouldn't be needed here
// but currently there's no way to tell the base class apart from a required interface.
types.insert(0, quote! { class #namespace #name });
Expand Down Expand Up @@ -356,8 +356,8 @@ impl Writer {
}

metadata::Type::TypeRef(type_name) => {
let namespace = self.namespace(type_name.namespace);
let name = to_ident(type_name.name);
let namespace = self.namespace(type_name.namespace());
let name = to_ident(type_name.name());
quote! { #namespace #name }
}

Expand Down
6 changes: 3 additions & 3 deletions crates/libs/bindgen/src/rust/cfg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@ pub fn type_def_cfg_combine(writer: &Writer, row: metadata::TypeDef, generics: &
type_cfg_combine(writer, generic, cfg);
}

if cfg.types.entry(type_name.namespace).or_default().insert(row) {
if cfg.types.entry(type_name.namespace()).or_default().insert(row) {
match type_kind {
metadata::TypeKind::Class => {
if let Some(default_interface) = metadata::type_def_default_interface(row) {
Expand All @@ -98,8 +98,8 @@ pub fn type_def_cfg_combine(writer: &Writer, row: metadata::TypeDef, generics: &
}
metadata::TypeKind::Struct => {
row.fields().for_each(|field| field_cfg_combine(writer, field, Some(row), cfg));
if !type_name.namespace.is_empty() {
for def in row.reader().get_type_def(type_name.namespace, type_name.name) {
if !type_name.namespace().is_empty() {
for def in row.reader().get_type_def(type_name.namespace(), type_name.name()) {
if def != row {
type_def_cfg_combine(writer, def, &[], cfg);
}
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/rust/enums.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ use metadata::HasAttributes;

pub fn writer(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
let type_name = def.type_name();
let ident = to_ident(type_name.name);
let ident = to_ident(type_name.name());
let underlying_type = def.underlying_type();
let underlying_type = writer.type_name(&underlying_type);

Expand Down Expand Up @@ -72,7 +72,7 @@ pub fn writer(writer: &Writer, def: metadata::TypeDef) -> TokenStream {
}

if !writer.sys {
let name = type_name.name;
let name = type_name.name();
tokens.combine(&quote! {
#features
impl windows_core::TypeKind for #ident {
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/rust/handles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,8 @@ pub fn gen_win_handle(writer: &Writer, def: metadata::TypeDef) -> TokenStream {

if let Some(dependency) = type_def_usable_for(def) {
let type_name = dependency.type_name();
let mut dependency = writer.namespace(type_name.namespace);
dependency.push_str(type_name.name);
let mut dependency = writer.namespace(type_name.namespace());
dependency.push_str(type_name.name());

tokens.combine(&quote! {
impl windows_core::CanInto<#dependency> for #ident {}
Expand Down
10 changes: 5 additions & 5 deletions crates/libs/bindgen/src/rust/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -186,13 +186,13 @@ fn namespace(writer: &Writer, tree: &Tree) -> String {
match item {
metadata::Item::Type(def) => {
let type_name = def.type_name();
if writer.reader.remap_types().any(|(x, _)| x == &type_name) {
if writer.reader.remap_type(&type_name).is_some() {
continue;
}
if writer.reader.core_types().any(|(x, _)| x == &type_name) {
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));
types.entry(def.kind()).or_default().entry(type_name.name()).or_default().combine(&writer.type_def(def));
}
metadata::Item::Fn(def, namespace) => {
let name = def.name();
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_types().any(|(x, _)| x == &type_name) {
if writer.reader.core_type(&type_name).is_some() {
continue;
}
if def.kind() != metadata::TypeKind::Interface {
Expand All @@ -239,7 +239,7 @@ fn namespace_impl(writer: &Writer, tree: &Tree) -> String {
let tokens = implements::writer(writer, def);

if !tokens.is_empty() {
types.insert(type_name.name, tokens);
types.insert(type_name.name(), tokens);
}
}
}
Expand Down
4 changes: 2 additions & 2 deletions crates/libs/bindgen/src/rust/standalone.rs
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ fn type_collect_standalone(writer: &Writer, ty: &metadata::Type, set: &mut std::
// Note this is a bit overeager as we can collect a typedef that is used
// by one architecture but not by another
let type_name = def.type_name();
if !type_name.namespace.is_empty() {
for row in def.reader().get_type_def(type_name.namespace, type_name.name) {
if !type_name.namespace().is_empty() {
for row in def.reader().get_type_def(type_name.namespace(), type_name.name()) {
if def != row {
type_collect_standalone(writer, &metadata::Type::TypeDef(row, Vec::new()), set);
}
Expand Down
8 changes: 4 additions & 4 deletions crates/libs/bindgen/src/rust/writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ impl Writer {
pub fn type_def_name_imp(&self, def: metadata::TypeDef, generics: &[metadata::Type], suffix: &str) -> TokenStream {
let type_name = def.type_name();

if type_name.namespace.is_empty() {
if type_name.namespace().is_empty() {
to_ident(&self.scoped_name(def))
} else {
let mut namespace = self.namespace(type_name.namespace);
let mut name = to_ident(type_name.name);
let mut namespace = self.namespace(type_name.namespace());
let mut name = to_ident(type_name.name());
name.push_str(suffix);

if generics.is_empty() || self.sys {
Expand Down Expand Up @@ -106,7 +106,7 @@ impl Writer {
} else {
let kind = self.type_name(ty);

if ty.is_generic() {
if matches!(ty, metadata::Type::GenericParam(_)) {
quote! { <#kind as windows_core::Type<#kind>>::Default }
} else if metadata::type_is_nullable(ty) && !self.sys {
quote! { Option<#kind> }
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/bindgen/src/winmd/from_reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn from_reader(reader: &metadata::Reader, config: std::collections::BTreeMap

let generics = &metadata::type_def_generics(def);

let extends = if let Some(extends) = def.extends() { writer.insert_type_ref(extends.namespace, extends.name) } else { TypeDefOrRef::none() };
let extends = if let Some(extends) = def.extends() { writer.insert_type_ref(extends.namespace(), extends.name()) } else { TypeDefOrRef::none() };

writer.tables.TypeDef.push(TypeDef {
Extends: extends,
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/metadata/src/filter.rs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ mod tests {

fn includes_type_name(filter: &Filter, full_name: &'static str) -> bool {
let type_name = crate::TypeName::parse(full_name);
filter.includes_type_name(type_name.namespace, type_name.name)
filter.includes_type_name(type_name.namespace(), type_name.name())
}

#[test]
Expand Down
37 changes: 17 additions & 20 deletions crates/libs/metadata/src/reader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,19 +140,19 @@ impl Reader {
self.nested.get(&type_def).map(|map| map.values().copied()).into_iter().flatten()
}

pub fn remap_types(&self) -> impl Iterator<Item = &(TypeName, TypeName)> + '_ {
pub fn remap_type(&self, type_name: &TypeName) -> Option<TypeName> {
if self.sys {
[].iter()
None
} else {
REMAP_TYPES.iter()
REMAP_TYPES.iter().find_map(|(key, value)| (type_name == key).then(|| value.clone()))
}
}

pub fn core_types(&self) -> impl Iterator<Item = &(TypeName, Type)> + '_ {
pub fn core_type(&self, type_name: &TypeName) -> Option<Type> {
if self.sys {
SYS_CORE_TYPES.iter()
SYS_CORE_TYPES.iter().find_map(|(key, value)| (type_name == key).then(|| value.clone()))
} else {
CORE_TYPES.iter()
CORE_TYPES.iter().find_map(|(key, value)| (type_name == key).then(|| value.clone()))
}
}

Expand All @@ -164,30 +164,27 @@ impl Reader {

let mut full_name = code.type_name();

for (known_name, kind) in self.core_types() {
if full_name == *known_name {
return kind.clone();
}
if let Some(to) = self.remap_type(&full_name) {
full_name = to.clone();
}

for (from, to) in self.remap_types() {
if full_name == *from {
full_name = *to;
break;
}
if let Some(kind) = self.core_type(&full_name) {
return kind;
}

// TODO: this needs to be deferred via a TypeName's optional nested type name?
if let Some(outer) = enclosing {
if full_name.namespace.is_empty() {
if full_name.namespace().is_empty() {
let nested = &self.nested[&outer];
let Some(inner) = nested.get(full_name.name) else {
panic!("Nested type not found: {}.{}", outer.type_name(), full_name.name);
let Some(inner) = nested.get(full_name.name()) else {
panic!("Nested type not found: {}.{}", outer.type_name(), full_name.name());
};
return Type::TypeDef(*inner, Vec::new());
}
}

if let Some(def) = self.get_type_def(full_name.namespace, full_name.name).next() {
// TODO: this needs to just return a TypeRef and avoid resolving as its too early to bake in the type
if let Some(def) = self.get_type_def(full_name.namespace(), full_name.name()).next() {
Type::TypeDef(def, Vec::new())
} else {
Type::TypeRef(full_name)
Expand Down Expand Up @@ -252,7 +249,7 @@ impl Reader {
blob.read_usize(); // ELEMENT_TYPE_VALUETYPE or ELEMENT_TYPE_CLASS

let type_name = TypeDefOrRef::decode(blob.file, blob.read_usize()).type_name();
let def = self.get_type_def(type_name.namespace, type_name.name).next().unwrap_or_else(|| panic!("Type not found: {}", type_name));
let def = self.get_type_def(type_name.namespace(), type_name.name()).next().unwrap_or_else(|| panic!("Type not found: {}", type_name));
let mut args = Vec::with_capacity(blob.read_usize());

for _ in 0..args.capacity() {
Expand Down
2 changes: 1 addition & 1 deletion crates/libs/metadata/src/tables.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ impl Attribute {
0x50 => Value::TypeName(TypeName::parse(values.read_str())),
0x55 => {
let type_name = TypeName::parse(name);
let def = reader.get_type_def(type_name.namespace, type_name.name).next().expect("Type not found");
let def = reader.get_type_def(type_name.namespace(), type_name.name()).next().expect("Type not found");
name = values.read_str();
Value::EnumDef(def, Box::new(values.read_integer(def.underlying_type())))
}
Expand Down
5 changes: 0 additions & 5 deletions crates/libs/metadata/src/type.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,11 +144,6 @@ impl Type {
matches!(self, Type::ConstRef(_))
}

/// Returns `true` if the `Type` is a generic parameter.
pub fn is_generic(&self) -> bool {
matches!(self, Type::GenericParam(_))
}

/// Returns `true` if the `Type` is a pointer.
pub fn is_pointer(&self) -> bool {
matches!(self, Type::ConstPtr(_, _) | Type::MutPtr(_, _))
Expand Down
Loading

0 comments on commit 927aa84

Please sign in to comment.