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

Prep for type name deferral #2955

Merged
merged 1 commit into from
Mar 26, 2024
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
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