diff --git a/src/generate/cs_members.rs b/src/generate/cs_members.rs index cc8fb6de9..5cfd97f3b 100644 --- a/src/generate/cs_members.rs +++ b/src/generate/cs_members.rs @@ -11,6 +11,7 @@ use super::cs_type_tag::CsTypeTag; #[derive(Debug, Eq, Hash, PartialEq, Clone, Default, PartialOrd, Ord)] pub struct CsGenericTemplate { pub names: Vec<(CsGenericTemplateType, String)>, + pub indices: Vec } #[derive(Debug, Eq, Hash, PartialEq, Clone, Default, PartialOrd, Ord)] @@ -21,20 +22,22 @@ pub enum CsGenericTemplateType { } impl CsGenericTemplate { - pub fn make_typenames(names: impl Iterator) -> Self { + pub fn make_typenames(names: impl Iterator, indices: impl Iterator) -> Self { CsGenericTemplate { names: names .into_iter() .map(|s| (CsGenericTemplateType::AnyType, s)) .collect(), + indices: indices.collect() } } - pub fn make_ref_types(names: impl Iterator) -> Self { + pub fn make_ref_types(names: impl Iterator, indices: impl Iterator) -> Self { CsGenericTemplate { names: names .into_iter() .map(|s| (CsGenericTemplateType::ReferenceType, s)) .collect(), + indices: indices.collect() } } diff --git a/src/generate/cs_type.rs b/src/generate/cs_type.rs index 13bff2401..49fa51b2f 100644 --- a/src/generate/cs_type.rs +++ b/src/generate/cs_type.rs @@ -7,7 +7,7 @@ use byteorder::ReadBytesExt; use brocolib::{ global_metadata::{ - FieldIndex, Il2CppFieldDefinition, Il2CppTypeDefinition, MethodIndex, ParameterIndex, + FieldIndex, Il2CppFieldDefinition, Il2CppTypeDefinition, Il2CppGenericContainer, MethodIndex, ParameterIndex, TypeDefinitionIndex, }, runtime_metadata::{Il2CppMethodSpec, Il2CppType, Il2CppTypeEnum, TypeData}, @@ -168,6 +168,11 @@ impl CsType { self } + fn make_generic_arg_indices(container: &Il2CppGenericContainer) -> impl Iterator { + let start = container.generic_parameter_start.index() as u16; + return start..start+(container.type_argc as u16); + } + pub fn make_cs_type( metadata: &CordlMetadata, tdi: TypeDefinitionIndex, @@ -195,6 +200,7 @@ impl CsType { let cpp_template = generics.as_ref().map(|g| { CsGenericTemplate::make_typenames( g.iter().map(|g| g.name(metadata.metadata).to_string()), + Self::make_generic_arg_indices(t.generic_container(metadata.metadata)) ) }); @@ -718,16 +724,19 @@ impl CsType { .generic_container_index .is_valid() .then(|| match generic_inst.is_some() { - true => Some(CsGenericTemplate { names: vec![] }), + true => Some(CsGenericTemplate { names: vec![], indices: vec![] }), false => { - let generics = method - .generic_container(metadata.metadata) - .unwrap() + let container = method.generic_container(metadata.metadata).unwrap(); + let generics = container .generic_parameters(metadata.metadata) .iter() .map(|param| param.name(metadata.metadata).to_string()); - Some(CsGenericTemplate::make_typenames(generics)) + + Some(CsGenericTemplate::make_typenames( + generics, + Self::make_generic_arg_indices(container) + )) } }) .flatten(); diff --git a/src/generate/json/json_gen.rs b/src/generate/json/json_gen.rs index 10cbcce24..aa42bc4e5 100644 --- a/src/generate/json/json_gen.rs +++ b/src/generate/json/json_gen.rs @@ -86,7 +86,14 @@ pub enum JsonGenericArgumentType { ReferenceType, } -type JsonTemplate = Vec<(JsonGenericArgumentType, String)>; +#[derive(Debug, Clone, Serialize, Deserialize)] +pub struct JsonGenericArgument { + pub r#type: JsonGenericArgumentType, + pub index: u16, // generic argument index + pub name: String, +} + +type JsonTemplate = Vec; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct JsonMethod { @@ -180,19 +187,18 @@ fn make_param(param: &CsParam, name_resolver: &JsonNameResolver) -> JsonParam { } fn make_template(template: &CsGenericTemplate) -> JsonTemplate { - // note: I'm not good at rust so there may be a better way to do this - zip - // (feel free to remove this comment if this is fine) - return template - .names + return template.names .iter() - .map(|p| { - ( - match (p.0) { + .zip(template.indices.iter()) + .map(|((ty, name), index)| { + JsonGenericArgument { + r#type: match ty { CsGenericTemplateType::AnyType => JsonGenericArgumentType::AnyType, CsGenericTemplateType::ReferenceType => JsonGenericArgumentType::ReferenceType, }, - p.1.clone(), - ) + name: name.clone(), + index: *index + } }) .collect_vec(); }