From 4bea2429be695454b3f7fd503f24982dbaa8f620 Mon Sep 17 00:00:00 2001 From: Arend van Beelen jr Date: Mon, 18 Jul 2022 15:30:37 +0200 Subject: [PATCH] Namespace imported types (#128) * Namespace imported types * Update CHANGELOG --- CHANGELOG.md | 1 + .../assets/ts_runtime_test/expected_index.ts | 201 ++++++++---------- fp-bindgen/src/generators/ts_runtime/mod.rs | 70 +++--- 3 files changed, 116 insertions(+), 156 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d9f6d4e2..155dfbf4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,3 +21,4 @@ exception of the compile-time only `Serializable` bound). - Fix #88: Deal with the Unit (`()`) type. - Use `any` type in TypeScript to represent `rmpv::Value`. +- Fix issue when TypeScript types conflicted with built-in JavaScript globals. diff --git a/examples/example-protocol/src/assets/ts_runtime_test/expected_index.ts b/examples/example-protocol/src/assets/ts_runtime_test/expected_index.ts index 4b06d539..8b69c971 100644 --- a/examples/example-protocol/src/assets/ts_runtime_test/expected_index.ts +++ b/examples/example-protocol/src/assets/ts_runtime_test/expected_index.ts @@ -7,52 +7,19 @@ import { encode, decode } from "https://unpkg.com/@msgpack/msgpack@2.7.2/mod.ts"; -import type { - Body, - DocExampleEnum, - DocExampleStruct, - ExplicitBoundPoint, - ExplicitedlyImportedType, - FlattenedStruct, - FloatingPoint, - FpAdjacentlyTagged, - FpFlatten, - FpInternallyTagged, - FpPropertyRenaming, - FpUntagged, - FpVariantRenaming, - GroupImportedType1, - GroupImportedType2, - HttpResult, - Int64, - MyDateTime, - Point, - ReduxAction, - Request, - RequestError, - Response, - Result, - SerdeAdjacentlyTagged, - SerdeFlatten, - SerdeInternallyTagged, - SerdePropertyRenaming, - SerdeUntagged, - SerdeVariantRenaming, - StateUpdate, - StructWithGenerics, -} from "./types.ts"; +import type * as types from "./types.ts"; type FatPtr = bigint; export type Imports = { - importExplicitBoundPoint: (arg: ExplicitBoundPoint) => void; - importFpAdjacentlyTagged: (arg: FpAdjacentlyTagged) => FpAdjacentlyTagged; - importFpEnum: (arg: FpVariantRenaming) => FpVariantRenaming; - importFpFlatten: (arg: FpFlatten) => FpFlatten; - importFpInternallyTagged: (arg: FpInternallyTagged) => FpInternallyTagged; - importFpStruct: (arg: FpPropertyRenaming) => FpPropertyRenaming; - importFpUntagged: (arg: FpUntagged) => FpUntagged; - importGenerics: (arg: StructWithGenerics) => StructWithGenerics; + importExplicitBoundPoint: (arg: types.ExplicitBoundPoint) => void; + importFpAdjacentlyTagged: (arg: types.FpAdjacentlyTagged) => types.FpAdjacentlyTagged; + importFpEnum: (arg: types.FpVariantRenaming) => types.FpVariantRenaming; + importFpFlatten: (arg: types.FpFlatten) => types.FpFlatten; + importFpInternallyTagged: (arg: types.FpInternallyTagged) => types.FpInternallyTagged; + importFpStruct: (arg: types.FpPropertyRenaming) => types.FpPropertyRenaming; + importFpUntagged: (arg: types.FpUntagged) => types.FpUntagged; + importGenerics: (arg: types.StructWithGenerics) => types.StructWithGenerics; importMultiplePrimitives: (arg1: number, arg2: string) => bigint; importPrimitiveBool: (arg: boolean) => boolean; importPrimitiveF32: (arg: number) => number; @@ -65,30 +32,30 @@ export type Imports = { importPrimitiveU32: (arg: number) => number; importPrimitiveU64: (arg: bigint) => bigint; importPrimitiveU8: (arg: number) => number; - importSerdeAdjacentlyTagged: (arg: SerdeAdjacentlyTagged) => SerdeAdjacentlyTagged; - importSerdeEnum: (arg: SerdeVariantRenaming) => SerdeVariantRenaming; - importSerdeFlatten: (arg: SerdeFlatten) => SerdeFlatten; - importSerdeInternallyTagged: (arg: SerdeInternallyTagged) => SerdeInternallyTagged; - importSerdeStruct: (arg: SerdePropertyRenaming) => SerdePropertyRenaming; - importSerdeUntagged: (arg: SerdeUntagged) => SerdeUntagged; + importSerdeAdjacentlyTagged: (arg: types.SerdeAdjacentlyTagged) => types.SerdeAdjacentlyTagged; + importSerdeEnum: (arg: types.SerdeVariantRenaming) => types.SerdeVariantRenaming; + importSerdeFlatten: (arg: types.SerdeFlatten) => types.SerdeFlatten; + importSerdeInternallyTagged: (arg: types.SerdeInternallyTagged) => types.SerdeInternallyTagged; + importSerdeStruct: (arg: types.SerdePropertyRenaming) => types.SerdePropertyRenaming; + importSerdeUntagged: (arg: types.SerdeUntagged) => types.SerdeUntagged; importString: (arg: string) => string; - importTimestamp: (arg: MyDateTime) => MyDateTime; + importTimestamp: (arg: types.MyDateTime) => types.MyDateTime; importVoidFunction: () => void; - importVoidFunctionEmptyResult: () => Result; + importVoidFunctionEmptyResult: () => types.Result; importVoidFunctionEmptyReturn: () => void; log: (message: string) => void; - makeHttpRequest: (request: Request) => Promise; + makeHttpRequest: (request: types.Request) => Promise; }; export type Exports = { - exportAsyncStruct?: (arg1: FpPropertyRenaming, arg2: bigint) => Promise; - exportFpAdjacentlyTagged?: (arg: FpAdjacentlyTagged) => FpAdjacentlyTagged; - exportFpEnum?: (arg: FpVariantRenaming) => FpVariantRenaming; - exportFpFlatten?: (arg: FpFlatten) => FpFlatten; - exportFpInternallyTagged?: (arg: FpInternallyTagged) => FpInternallyTagged; - exportFpStruct?: (arg: FpPropertyRenaming) => FpPropertyRenaming; - exportFpUntagged?: (arg: FpUntagged) => FpUntagged; - exportGenerics?: (arg: StructWithGenerics) => StructWithGenerics; + exportAsyncStruct?: (arg1: types.FpPropertyRenaming, arg2: bigint) => Promise; + exportFpAdjacentlyTagged?: (arg: types.FpAdjacentlyTagged) => types.FpAdjacentlyTagged; + exportFpEnum?: (arg: types.FpVariantRenaming) => types.FpVariantRenaming; + exportFpFlatten?: (arg: types.FpFlatten) => types.FpFlatten; + exportFpInternallyTagged?: (arg: types.FpInternallyTagged) => types.FpInternallyTagged; + exportFpStruct?: (arg: types.FpPropertyRenaming) => types.FpPropertyRenaming; + exportFpUntagged?: (arg: types.FpUntagged) => types.FpUntagged; + exportGenerics?: (arg: types.StructWithGenerics) => types.StructWithGenerics; exportMultiplePrimitives?: (arg1: number, arg2: string) => bigint; exportPrimitiveBool?: (arg: boolean) => boolean; exportPrimitiveF32?: (arg: number) => number; @@ -101,18 +68,18 @@ export type Exports = { exportPrimitiveU32?: (arg: number) => number; exportPrimitiveU64?: (arg: bigint) => bigint; exportPrimitiveU8?: (arg: number) => number; - exportSerdeAdjacentlyTagged?: (arg: SerdeAdjacentlyTagged) => SerdeAdjacentlyTagged; - exportSerdeEnum?: (arg: SerdeVariantRenaming) => SerdeVariantRenaming; - exportSerdeFlatten?: (arg: SerdeFlatten) => SerdeFlatten; - exportSerdeInternallyTagged?: (arg: SerdeInternallyTagged) => SerdeInternallyTagged; - exportSerdeStruct?: (arg: SerdePropertyRenaming) => SerdePropertyRenaming; - exportSerdeUntagged?: (arg: SerdeUntagged) => SerdeUntagged; + exportSerdeAdjacentlyTagged?: (arg: types.SerdeAdjacentlyTagged) => types.SerdeAdjacentlyTagged; + exportSerdeEnum?: (arg: types.SerdeVariantRenaming) => types.SerdeVariantRenaming; + exportSerdeFlatten?: (arg: types.SerdeFlatten) => types.SerdeFlatten; + exportSerdeInternallyTagged?: (arg: types.SerdeInternallyTagged) => types.SerdeInternallyTagged; + exportSerdeStruct?: (arg: types.SerdePropertyRenaming) => types.SerdePropertyRenaming; + exportSerdeUntagged?: (arg: types.SerdeUntagged) => types.SerdeUntagged; exportString?: (arg: string) => string; - exportTimestamp?: (arg: MyDateTime) => MyDateTime; + exportTimestamp?: (arg: types.MyDateTime) => types.MyDateTime; exportVoidFunction?: () => void; - fetchData?: (rType: string) => Promise>; + fetchData?: (rType: string) => Promise>; init?: () => void; - reducerBridge?: (action: ReduxAction) => StateUpdate; + reducerBridge?: (action: types.ReduxAction) => types.StateUpdate; exportAsyncStructRaw?: (arg1: Uint8Array, arg2: bigint) => Promise; exportFpAdjacentlyTaggedRaw?: (arg: Uint8Array) => Uint8Array; exportFpEnumRaw?: (arg: Uint8Array) => Uint8Array; @@ -250,35 +217,35 @@ export async function createRuntime( const { instance } = await WebAssembly.instantiate(plugin, { fp: { __fp_gen_import_explicit_bound_point: (arg_ptr: FatPtr) => { - const arg = parseObject>(arg_ptr); + const arg = parseObject>(arg_ptr); importFunctions.importExplicitBoundPoint(arg); }, __fp_gen_import_fp_adjacently_tagged: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importFpAdjacentlyTagged(arg)); }, __fp_gen_import_fp_enum: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importFpEnum(arg)); }, __fp_gen_import_fp_flatten: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importFpFlatten(arg)); }, __fp_gen_import_fp_internally_tagged: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importFpInternallyTagged(arg)); }, __fp_gen_import_fp_struct: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importFpStruct(arg)); }, __fp_gen_import_fp_untagged: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importFpUntagged(arg)); }, __fp_gen_import_generics: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject>(arg_ptr); + const arg = parseObject>(arg_ptr); return serializeObject(importFunctions.importGenerics(arg)); }, __fp_gen_import_multiple_primitives: (arg1: number, arg2_ptr: FatPtr): bigint => { @@ -319,27 +286,27 @@ export async function createRuntime( return importFunctions.importPrimitiveU8(arg); }, __fp_gen_import_serde_adjacently_tagged: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importSerdeAdjacentlyTagged(arg)); }, __fp_gen_import_serde_enum: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importSerdeEnum(arg)); }, __fp_gen_import_serde_flatten: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importSerdeFlatten(arg)); }, __fp_gen_import_serde_internally_tagged: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importSerdeInternallyTagged(arg)); }, __fp_gen_import_serde_struct: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importSerdeStruct(arg)); }, __fp_gen_import_serde_untagged: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importSerdeUntagged(arg)); }, __fp_gen_import_string: (arg_ptr: FatPtr): FatPtr => { @@ -347,7 +314,7 @@ export async function createRuntime( return serializeObject(importFunctions.importString(arg)); }, __fp_gen_import_timestamp: (arg_ptr: FatPtr): FatPtr => { - const arg = parseObject(arg_ptr); + const arg = parseObject(arg_ptr); return serializeObject(importFunctions.importTimestamp(arg)); }, __fp_gen_import_void_function: () => { @@ -364,7 +331,7 @@ export async function createRuntime( importFunctions.log(message); }, __fp_gen_make_http_request: (request_ptr: FatPtr): FatPtr => { - const request = parseObject(request_ptr); + const request = parseObject(request_ptr); const _async_result_ptr = createAsyncValue(); importFunctions.makeHttpRequest(request) .then((result) => { @@ -400,72 +367,72 @@ export async function createRuntime( const export_fn = instance.exports.__fp_gen_export_async_struct as any; if (!export_fn) return; - return (arg1: FpPropertyRenaming, arg2: bigint) => { + return (arg1: types.FpPropertyRenaming, arg2: bigint) => { const arg1_ptr = serializeObject(arg1); - return promiseFromPtr(export_fn(arg1_ptr, arg2)).then((ptr) => parseObject(ptr)); + return promiseFromPtr(export_fn(arg1_ptr, arg2)).then((ptr) => parseObject(ptr)); }; })(), exportFpAdjacentlyTagged: (() => { const export_fn = instance.exports.__fp_gen_export_fp_adjacently_tagged as any; if (!export_fn) return; - return (arg: FpAdjacentlyTagged) => { + return (arg: types.FpAdjacentlyTagged) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportFpEnum: (() => { const export_fn = instance.exports.__fp_gen_export_fp_enum as any; if (!export_fn) return; - return (arg: FpVariantRenaming) => { + return (arg: types.FpVariantRenaming) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportFpFlatten: (() => { const export_fn = instance.exports.__fp_gen_export_fp_flatten as any; if (!export_fn) return; - return (arg: FpFlatten) => { + return (arg: types.FpFlatten) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportFpInternallyTagged: (() => { const export_fn = instance.exports.__fp_gen_export_fp_internally_tagged as any; if (!export_fn) return; - return (arg: FpInternallyTagged) => { + return (arg: types.FpInternallyTagged) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportFpStruct: (() => { const export_fn = instance.exports.__fp_gen_export_fp_struct as any; if (!export_fn) return; - return (arg: FpPropertyRenaming) => { + return (arg: types.FpPropertyRenaming) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportFpUntagged: (() => { const export_fn = instance.exports.__fp_gen_export_fp_untagged as any; if (!export_fn) return; - return (arg: FpUntagged) => { + return (arg: types.FpUntagged) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportGenerics: (() => { const export_fn = instance.exports.__fp_gen_export_generics as any; if (!export_fn) return; - return (arg: StructWithGenerics) => { + return (arg: types.StructWithGenerics) => { const arg_ptr = serializeObject(arg); - return parseObject>(export_fn(arg_ptr)); + return parseObject>(export_fn(arg_ptr)); }; })(), exportMultiplePrimitives: (() => { @@ -517,54 +484,54 @@ export async function createRuntime( const export_fn = instance.exports.__fp_gen_export_serde_adjacently_tagged as any; if (!export_fn) return; - return (arg: SerdeAdjacentlyTagged) => { + return (arg: types.SerdeAdjacentlyTagged) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportSerdeEnum: (() => { const export_fn = instance.exports.__fp_gen_export_serde_enum as any; if (!export_fn) return; - return (arg: SerdeVariantRenaming) => { + return (arg: types.SerdeVariantRenaming) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportSerdeFlatten: (() => { const export_fn = instance.exports.__fp_gen_export_serde_flatten as any; if (!export_fn) return; - return (arg: SerdeFlatten) => { + return (arg: types.SerdeFlatten) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportSerdeInternallyTagged: (() => { const export_fn = instance.exports.__fp_gen_export_serde_internally_tagged as any; if (!export_fn) return; - return (arg: SerdeInternallyTagged) => { + return (arg: types.SerdeInternallyTagged) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportSerdeStruct: (() => { const export_fn = instance.exports.__fp_gen_export_serde_struct as any; if (!export_fn) return; - return (arg: SerdePropertyRenaming) => { + return (arg: types.SerdePropertyRenaming) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportSerdeUntagged: (() => { const export_fn = instance.exports.__fp_gen_export_serde_untagged as any; if (!export_fn) return; - return (arg: SerdeUntagged) => { + return (arg: types.SerdeUntagged) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportString: (() => { @@ -580,9 +547,9 @@ export async function createRuntime( const export_fn = instance.exports.__fp_gen_export_timestamp as any; if (!export_fn) return; - return (arg: MyDateTime) => { + return (arg: types.MyDateTime) => { const arg_ptr = serializeObject(arg); - return parseObject(export_fn(arg_ptr)); + return parseObject(export_fn(arg_ptr)); }; })(), exportVoidFunction: instance.exports.__fp_gen_export_void_function as any, @@ -592,7 +559,7 @@ export async function createRuntime( return (rType: string) => { const type_ptr = serializeObject(rType); - return promiseFromPtr(export_fn(type_ptr)).then((ptr) => parseObject>(ptr)); + return promiseFromPtr(export_fn(type_ptr)).then((ptr) => parseObject>(ptr)); }; })(), init: instance.exports.__fp_gen_init as any, @@ -600,9 +567,9 @@ export async function createRuntime( const export_fn = instance.exports.__fp_gen_reducer_bridge as any; if (!export_fn) return; - return (action: ReduxAction) => { + return (action: types.ReduxAction) => { const action_ptr = serializeObject(action); - return parseObject(export_fn(action_ptr)); + return parseObject(export_fn(action_ptr)); }; })(), exportAsyncStructRaw: (() => { diff --git a/fp-bindgen/src/generators/ts_runtime/mod.rs b/fp-bindgen/src/generators/ts_runtime/mod.rs index 8257feca..fc73f5e9 100644 --- a/fp-bindgen/src/generators/ts_runtime/mod.rs +++ b/fp-bindgen/src/generators/ts_runtime/mod.rs @@ -42,16 +42,6 @@ pub(crate) fn generate_bindings( Vec::new() }; - let type_names = types - .into_iter() - .filter_map(|(_, ty)| match ty { - Type::Alias(name, _) => Some(name), - Type::Enum(ty) => Some(ty.ident.name), - Type::Struct(ty) => Some(ty.ident.name), - _ => None, - }) - .collect::>(); - let contents = format!( "// ============================================= // // WebAssembly runtime for TypeScript // @@ -62,8 +52,7 @@ pub(crate) fn generate_bindings( import {{ encode, decode }} from \"{}\"; -import type {{ -{}}} from \"./types{}\"; +import type * as types from \"./types{}\"; type FatPtr = bigint; @@ -214,7 +203,6 @@ function toFatPtr(ptr: number, len: number): FatPtr {{ }} ", config.msgpack_module, - join_lines(&type_names, |line| format!(" {},", line)), // HACK: Import paths in TypeScript are a bit of a mess. Usually, you // shouldn't need an extension, but with some configurations you do. // For now, we just try to detect Deno users by looking at the @@ -274,7 +262,7 @@ fn format_function_declarations( format!( " => Promise<{}>", match &function.return_type { - Some(ty) => format_ident(ty, types), + Some(ty) => format_ident(ty, types, "types."), None => "void".to_owned(), } ) @@ -388,7 +376,7 @@ fn format_import_wrappers(import_functions: &FunctionList, types: &TypeMap) -> V Some(format!( "const {} = parseObject<{}>({});", arg.name.to_camel_case(), - format_ident(&arg.ty, types), + format_ident(&arg.ty, types, "types."), get_pointer_name(&arg.name) )) } @@ -535,7 +523,7 @@ fn format_export_wrappers(export_functions: &FunctionList, types: &TypeMap) -> V function .return_type .as_ref() - .map(|ty| format_ident(ty, types)) + .map(|ty| format_ident(ty, types, "types.")) .unwrap_or_else(|| "void".to_owned()), ) } else { @@ -547,7 +535,7 @@ fn format_export_wrappers(export_functions: &FunctionList, types: &TypeMap) -> V ), Some(ty) => format!( "return parseObject<{}>(export_fn({}));", - format_ident(ty, types), + format_ident(ty, types, "types."), call_args ), } @@ -676,7 +664,7 @@ fn generate_type_bindings(types: &TypeMap, path: &str) { // both cases: match ty.name.as_str() { "i64" | "u64" => "number | bigint".to_owned(), - _ => format_ident(ty, types), + _ => format_ident(ty, types, ""), } )), Type::Custom(CustomType { @@ -785,7 +773,7 @@ fn create_enum_definition(ty: &Enum, types: &TypeMap) -> String { Type::Tuple(items) if items.len() == 1 => { let item = items.first().unwrap(); if ty.options.untagged { - format!("| {}", format_ident(item, types)) + format!("| {}", format_ident(item, types, "")) } else { match (&ty.options.tag_prop_name, &ty.options.content_prop_name) { (Some(tag), Some(content)) => { @@ -794,7 +782,7 @@ fn create_enum_definition(ty: &Enum, types: &TypeMap) -> String { tag, variant_name, content, - format_ident(item, types) + format_ident(item, types, "") ) } (Some(tag), None) => { @@ -802,11 +790,15 @@ fn create_enum_definition(ty: &Enum, types: &TypeMap) -> String { "| {{ {}: \"{}\" }} & {}", tag, variant_name, - format_ident(item, types) + format_ident(item, types, "") ) } (None, _) => { - format!("| {{ {}: {} }}", variant_name, format_ident(item, types)) + format!( + "| {{ {}: {} }}", + variant_name, + format_ident(item, types, "") + ) } } } @@ -852,7 +844,7 @@ fn create_struct_definition(ty: &Struct, types: &TypeMap) -> String { ty.ident, ty.fields .first() - .map(|field| format_ident(&field.ty, types)) + .map(|field| format_ident(&field.ty, types, "")) .unwrap() ) } else { @@ -913,13 +905,13 @@ fn format_struct_fields(fields: &[Field], types: &TypeMap, casing: Casing) -> Ve "{}{}: {};", get_field_name(field, casing), optional, - format_ident(arg, types) + format_ident(arg, types, "") ) } _ => format!( "{}: {};", get_field_name(field, casing), - format_ident(&field.ty, types) + format_ident(&field.ty, types, "") ), }; if field.doc_lines.is_empty() { @@ -943,17 +935,17 @@ fn format_raw_type(ty: &TypeIdent) -> &str { } /// Formats a type so it's valid TypeScript. -fn format_ident(ident: &TypeIdent, types: &TypeMap) -> String { +fn format_ident(ident: &TypeIdent, types: &TypeMap, scope: &str) -> String { match types.get(ident) { - Some(ty) => format_type_with_ident(ty, ident, types), + Some(ty) => format_type_with_ident(ty, ident, types, scope), None => ident.to_string(), // Must be a generic. } } /// Formats a type so it's valid TypeScript. -fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap) -> String { +fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap, scope: &str) -> String { match ty { - Type::Alias(name, _) => name.clone(), + Type::Alias(name, _) => format!("{}{}", scope, name), Type::Container(name, _) => { let (arg, _) = ident .generic_args @@ -961,9 +953,9 @@ fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap) -> Stri .expect("Identifier was expected to contain a generic argument"); if name == "Option" { - format!("{} | null", format_ident(arg, types)) + format!("{} | null", format_ident(arg, types, scope)) } else { - format_ident(arg, types) + format_ident(arg, types, scope) } } Type::Custom(custom) => custom.ts_ty.clone(), @@ -971,12 +963,12 @@ fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap) -> Stri let args: Vec<_> = ident .generic_args .iter() - .map(|(arg, _)| format_ident(arg, types)) + .map(|(arg, _)| format_ident(arg, types, scope)) .collect(); if args.is_empty() { - ident.name.clone() + format!("{}{}", scope, ident.name) } else { - format!("{}<{}>", ident.name, args.join(", ")) + format!("{}{}<{}>", scope, ident.name, args.join(", ")) } } Type::List(_, _) => { @@ -984,7 +976,7 @@ fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap) -> Stri .generic_args .first() .expect("Identifier was expected to contain a generic argument"); - format!("Array<{}>", format_ident(arg, types)) + format!("Array<{}>", format_ident(arg, types, scope)) } Type::Map(_, _, _) => { let (arg1, _) = ident @@ -997,8 +989,8 @@ fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap) -> Stri .expect("Identifier was expected to contain two arguments"); format!( "Record<{}, {}>", - format_ident(arg1, types), - format_ident(arg2, types) + format_ident(arg1, types, scope), + format_ident(arg2, types, scope) ) } Type::Primitive(primitive) => format_encoded_primitive(*primitive).to_owned(), @@ -1007,7 +999,7 @@ fn format_type_with_ident(ty: &Type, ident: &TypeIdent, types: &TypeMap) -> Stri "[{}]", items .iter() - .map(|item| format_ident(item, types)) + .map(|item| format_ident(item, types, scope)) .collect::>() .join(", ") ), @@ -1035,7 +1027,7 @@ fn format_plain_primitive_or_ident(ident: &TypeIdent, types: &TypeMap) -> String if let Ok(primitive) = Primitive::from_str(&ident.name) { format_plain_primitive(primitive).to_owned() } else { - format_ident(ident, types) + format_ident(ident, types, "types.") } }