mirror of
https://github.com/denoland/deno.git
synced 2024-11-24 15:19:26 -05:00
feat(ext/ffi): better type hints for Deno.dlopen (#16874)
This commit is contained in:
parent
0169949c29
commit
8b5b327b18
2 changed files with 34 additions and 19 deletions
17
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
17
cli/tsc/dts/lib.deno.unstable.d.ts
vendored
|
@ -443,7 +443,7 @@ declare namespace Deno {
|
|||
/** The definition of the function. */
|
||||
definition: Fn;
|
||||
|
||||
constructor(pointer: PointerValue, definition: Fn);
|
||||
constructor(pointer: PointerValue, definition: Const<Fn>);
|
||||
|
||||
/** Call the foreign function. */
|
||||
call: FromForeignFunction<Fn>;
|
||||
|
@ -494,7 +494,7 @@ declare namespace Deno {
|
|||
Definition extends UnsafeCallbackDefinition = UnsafeCallbackDefinition,
|
||||
> {
|
||||
constructor(
|
||||
definition: Definition,
|
||||
definition: Const<Definition>,
|
||||
callback: UnsafeCallbackFunction<
|
||||
Definition["parameters"],
|
||||
Definition["result"]
|
||||
|
@ -562,6 +562,17 @@ declare namespace Deno {
|
|||
close(): void;
|
||||
}
|
||||
|
||||
/**
|
||||
* This magic code used to implement better type hints for {@linkcode Deno.dlopen}
|
||||
*/
|
||||
type Cast<A, B> = A extends B ? A : B;
|
||||
type Const<T> = Cast<
|
||||
T,
|
||||
| (T extends string | number | bigint | boolean ? T : never)
|
||||
| { [K in keyof T]: Const<T[K]> }
|
||||
| []
|
||||
>;
|
||||
|
||||
/** **UNSTABLE**: New API, yet to be vetted.
|
||||
*
|
||||
* Opens an external dynamic library and registers symbols, making foreign
|
||||
|
@ -611,7 +622,7 @@ declare namespace Deno {
|
|||
*/
|
||||
export function dlopen<S extends ForeignLibraryInterface>(
|
||||
filename: string | URL,
|
||||
symbols: S,
|
||||
symbols: Const<S>,
|
||||
): DynamicLibrary<S>;
|
||||
|
||||
/** **UNSTABLE**: New API, yet to be vetted.
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
const remote = Deno.dlopen(
|
||||
"dummy_lib.so",
|
||||
{
|
||||
method1: { parameters: ["usize", "usize"], result: "void", callback: true },
|
||||
method1: { parameters: ["usize", "bool"], result: "void", callback: true },
|
||||
method2: { parameters: [], result: "void" },
|
||||
method3: { parameters: ["usize"], result: "void" },
|
||||
method4: { parameters: ["isize"], result: "void" },
|
||||
|
@ -61,16 +61,16 @@ const remote = Deno.dlopen(
|
|||
static13: { type: "f32" },
|
||||
static14: { type: "f64" },
|
||||
static15: { type: "bool" },
|
||||
} as const,
|
||||
},
|
||||
);
|
||||
|
||||
Deno.dlopen(
|
||||
"dummy_lib_2.so",
|
||||
// @ts-expect-error: Returning a function pointer
|
||||
// is declared using "pointer" or "function" + UnsafeFnPointer
|
||||
{
|
||||
wrong_method1: {
|
||||
parameters: [],
|
||||
// @ts-expect-error not assignable to type 'NativeResultType'
|
||||
result: {
|
||||
function: {
|
||||
parameters: [],
|
||||
|
@ -78,14 +78,18 @@ Deno.dlopen(
|
|||
},
|
||||
},
|
||||
},
|
||||
} as const,
|
||||
},
|
||||
);
|
||||
|
||||
// @ts-expect-error: Invalid argument
|
||||
remote.symbols.method1(0);
|
||||
// @ts-expect-error: Invalid argument
|
||||
remote.symbols.method1(0, 0);
|
||||
// @ts-expect-error: Invalid argument
|
||||
remote.symbols.method1(true, true);
|
||||
// @ts-expect-error: Invalid return type
|
||||
<number> remote.symbols.method1(0, 0);
|
||||
<void> remote.symbols.method1(0n, 0n);
|
||||
<number> remote.symbols.method1(0, true);
|
||||
<void> remote.symbols.method1(0n, true);
|
||||
|
||||
// @ts-expect-error: Expected 0 arguments, but got 1.
|
||||
remote.symbols.method2(null);
|
||||
|
@ -170,7 +174,7 @@ const fnptr = new Deno.UnsafeFnPointer(
|
|||
{
|
||||
parameters: ["u32", "pointer"],
|
||||
result: "void",
|
||||
} as const,
|
||||
},
|
||||
);
|
||||
// @ts-expect-error: Invalid argument
|
||||
fnptr.call(null, null);
|
||||
|
@ -180,7 +184,7 @@ const unsafe_callback_wrong1 = new Deno.UnsafeCallback(
|
|||
{
|
||||
parameters: ["i8"],
|
||||
result: "void",
|
||||
} as const,
|
||||
},
|
||||
// @ts-expect-error: i8 is not a pointer
|
||||
(_: bigint) => {},
|
||||
);
|
||||
|
@ -188,7 +192,7 @@ const unsafe_callback_wrong2 = new Deno.UnsafeCallback(
|
|||
{
|
||||
parameters: ["pointer"],
|
||||
result: "u64",
|
||||
} as const,
|
||||
},
|
||||
// @ts-expect-error: must return a number or bigint
|
||||
(_: Deno.UnsafePointer) => {},
|
||||
);
|
||||
|
@ -196,7 +200,7 @@ const unsafe_callback_wrong3 = new Deno.UnsafeCallback(
|
|||
{
|
||||
parameters: [],
|
||||
result: "void",
|
||||
} as const,
|
||||
},
|
||||
// @ts-expect-error: no parameters
|
||||
(_: Deno.UnsafePointer) => {},
|
||||
);
|
||||
|
@ -204,7 +208,7 @@ const unsafe_callback_wrong4 = new Deno.UnsafeCallback(
|
|||
{
|
||||
parameters: ["u64"],
|
||||
result: "void",
|
||||
} as const,
|
||||
},
|
||||
// @ts-expect-error: Callback's 64bit parameters are either number or bigint
|
||||
(_: number) => {},
|
||||
);
|
||||
|
@ -212,21 +216,21 @@ const unsafe_callback_right1 = new Deno.UnsafeCallback(
|
|||
{
|
||||
parameters: ["u8", "u32", "pointer"],
|
||||
result: "void",
|
||||
} as const,
|
||||
},
|
||||
(_1: number, _2: number, _3: Deno.PointerValue) => {},
|
||||
);
|
||||
const unsafe_callback_right2 = new Deno.UnsafeCallback(
|
||||
{
|
||||
parameters: [],
|
||||
result: "u8",
|
||||
} as const,
|
||||
},
|
||||
() => 3,
|
||||
);
|
||||
const unsafe_callback_right3 = new Deno.UnsafeCallback(
|
||||
{
|
||||
parameters: [],
|
||||
result: "function",
|
||||
} as const,
|
||||
},
|
||||
// Callbacks can return other callbacks' pointers, if really wanted.
|
||||
() => unsafe_callback_right2.pointer,
|
||||
);
|
||||
|
@ -234,14 +238,14 @@ const unsafe_callback_right4 = new Deno.UnsafeCallback(
|
|||
{
|
||||
parameters: ["u8", "u32", "pointer"],
|
||||
result: "u8",
|
||||
} as const,
|
||||
},
|
||||
(_1: number, _2: number, _3: Deno.PointerValue) => 3,
|
||||
);
|
||||
const unsafe_callback_right5 = new Deno.UnsafeCallback(
|
||||
{
|
||||
parameters: ["u8", "i32", "pointer"],
|
||||
result: "void",
|
||||
} as const,
|
||||
},
|
||||
(_1: number, _2: number, _3: Deno.PointerValue) => {},
|
||||
);
|
||||
|
||||
|
|
Loading…
Reference in a new issue