@lakutata/ffi 0.0.0-stage → 3.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (129) hide show
  1. package/LICENSE +23 -0
  2. package/README.md +163 -2
  3. package/README.zh-CN.md +140 -0
  4. package/dist/cjs/components/NativeLibrary.d.ts +229 -0
  5. package/dist/cjs/components/NativeLibrary.js +346 -0
  6. package/dist/cjs/decorators/Library.d.ts +61 -0
  7. package/dist/cjs/decorators/Library.js +44 -0
  8. package/dist/cjs/decorators/Native.d.ts +69 -0
  9. package/dist/cjs/decorators/Native.js +90 -0
  10. package/dist/cjs/exceptions/NativeDeclarationException.d.ts +12 -0
  11. package/dist/cjs/exceptions/NativeDeclarationException.js +19 -0
  12. package/dist/cjs/exceptions/NativeLibraryClosedException.d.ts +12 -0
  13. package/dist/cjs/exceptions/NativeLibraryClosedException.js +19 -0
  14. package/dist/cjs/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
  15. package/dist/cjs/exceptions/NativeLibraryNotFoundException.js +18 -0
  16. package/dist/cjs/exceptions/NativeMemoryException.d.ts +11 -0
  17. package/dist/cjs/exceptions/NativeMemoryException.js +18 -0
  18. package/dist/cjs/exports/FFI.d.ts +12 -0
  19. package/dist/cjs/exports/FFI.js +40 -0
  20. package/dist/cjs/exports/Generator.d.ts +2 -0
  21. package/dist/cjs/exports/Generator.js +10 -0
  22. package/dist/cjs/lib/Memory.d.ts +188 -0
  23. package/dist/cjs/lib/Memory.js +227 -0
  24. package/dist/cjs/lib/Runtime.d.ts +98 -0
  25. package/dist/cjs/lib/Runtime.js +209 -0
  26. package/dist/cjs/lib/backend/Functions.d.ts +65 -0
  27. package/dist/cjs/lib/backend/Functions.js +214 -0
  28. package/dist/cjs/lib/backend/KoffiTypes.d.ts +53 -0
  29. package/dist/cjs/lib/backend/KoffiTypes.js +426 -0
  30. package/dist/cjs/lib/declarations/Builtins.d.ts +33 -0
  31. package/dist/cjs/lib/declarations/Builtins.js +179 -0
  32. package/dist/cjs/lib/declarations/Layout.d.ts +41 -0
  33. package/dist/cjs/lib/declarations/Layout.js +180 -0
  34. package/dist/cjs/lib/declarations/Lexer.d.ts +40 -0
  35. package/dist/cjs/lib/declarations/Lexer.js +325 -0
  36. package/dist/cjs/lib/declarations/Parser.d.ts +90 -0
  37. package/dist/cjs/lib/declarations/Parser.js +1425 -0
  38. package/dist/cjs/lib/declarations/Platform.d.ts +50 -0
  39. package/dist/cjs/lib/declarations/Platform.js +27 -0
  40. package/dist/cjs/lib/declarations/Types.d.ts +173 -0
  41. package/dist/cjs/lib/declarations/Types.js +179 -0
  42. package/dist/cjs/lib/generator/CText.d.ts +14 -0
  43. package/dist/cjs/lib/generator/CText.js +133 -0
  44. package/dist/cjs/lib/generator/Generator.d.ts +136 -0
  45. package/dist/cjs/lib/generator/Generator.js +395 -0
  46. package/dist/cjs/lib/generator/Preprocessor.d.ts +60 -0
  47. package/dist/cjs/lib/generator/Preprocessor.js +94 -0
  48. package/dist/cjs/lib/generator/TypeScriptTypes.d.ts +35 -0
  49. package/dist/cjs/lib/generator/TypeScriptTypes.js +153 -0
  50. package/dist/cjs/lib/library/NativeCallback.d.ts +44 -0
  51. package/dist/cjs/lib/library/NativeCallback.js +66 -0
  52. package/dist/cjs/lib/library/NativeLibraryHandle.d.ts +268 -0
  53. package/dist/cjs/lib/library/NativeLibraryHandle.js +540 -0
  54. package/dist/cjs/lib/library/Resolve.d.ts +49 -0
  55. package/dist/cjs/lib/library/Resolve.js +130 -0
  56. package/dist/cjs/lib/thread/NativeThreads.d.ts +80 -0
  57. package/dist/cjs/lib/thread/NativeThreads.js +384 -0
  58. package/dist/cjs/lib/thread/NativeWorker.d.ts +6 -0
  59. package/dist/cjs/lib/thread/NativeWorker.js +96 -0
  60. package/dist/cjs/lib/thread/NativeWorkerCode.d.ts +5 -0
  61. package/dist/cjs/lib/thread/NativeWorkerCode.js +4 -0
  62. package/dist/cjs/lib/thread/PackageRequire.d.ts +6 -0
  63. package/dist/cjs/lib/thread/PackageRequire.js +4 -0
  64. package/dist/cjs/lib/thread/ThreadProtocol.d.ts +77 -0
  65. package/dist/cjs/lib/thread/ThreadProtocol.js +2 -0
  66. package/dist/cjs/package.json +1 -0
  67. package/dist/esm/components/NativeLibrary.js +338 -0
  68. package/dist/esm/decorators/Library.js +40 -0
  69. package/dist/esm/decorators/Native.js +85 -0
  70. package/dist/esm/exceptions/NativeDeclarationException.js +15 -0
  71. package/dist/esm/exceptions/NativeLibraryClosedException.js +15 -0
  72. package/dist/esm/exceptions/NativeLibraryNotFoundException.js +14 -0
  73. package/dist/esm/exceptions/NativeMemoryException.js +14 -0
  74. package/dist/esm/exports/FFI.js +10 -0
  75. package/dist/esm/exports/Generator.js +2 -0
  76. package/dist/esm/lib/Memory.js +210 -0
  77. package/dist/esm/lib/Runtime.js +192 -0
  78. package/dist/esm/lib/backend/Functions.js +206 -0
  79. package/dist/esm/lib/backend/KoffiTypes.js +418 -0
  80. package/dist/esm/lib/declarations/Builtins.js +174 -0
  81. package/dist/esm/lib/declarations/Layout.js +175 -0
  82. package/dist/esm/lib/declarations/Lexer.js +321 -0
  83. package/dist/esm/lib/declarations/Parser.js +1421 -0
  84. package/dist/esm/lib/declarations/Platform.js +23 -0
  85. package/dist/esm/lib/declarations/Types.js +170 -0
  86. package/dist/esm/lib/generator/CText.js +129 -0
  87. package/dist/esm/lib/generator/Generator.js +388 -0
  88. package/dist/esm/lib/generator/Preprocessor.js +87 -0
  89. package/dist/esm/lib/generator/TypeScriptTypes.js +149 -0
  90. package/dist/esm/lib/library/NativeCallback.js +59 -0
  91. package/dist/esm/lib/library/NativeLibraryHandle.js +532 -0
  92. package/dist/esm/lib/library/Resolve.js +122 -0
  93. package/dist/esm/lib/thread/NativeThreads.js +377 -0
  94. package/dist/esm/lib/thread/NativeWorker.js +93 -0
  95. package/dist/esm/lib/thread/NativeWorkerCode.js +1 -0
  96. package/dist/esm/lib/thread/PackageRequire.js +2 -0
  97. package/dist/esm/lib/thread/ThreadProtocol.js +1 -0
  98. package/dist/types/components/NativeLibrary.d.ts +229 -0
  99. package/dist/types/decorators/Library.d.ts +61 -0
  100. package/dist/types/decorators/Native.d.ts +69 -0
  101. package/dist/types/exceptions/NativeDeclarationException.d.ts +12 -0
  102. package/dist/types/exceptions/NativeLibraryClosedException.d.ts +12 -0
  103. package/dist/types/exceptions/NativeLibraryNotFoundException.d.ts +11 -0
  104. package/dist/types/exceptions/NativeMemoryException.d.ts +11 -0
  105. package/dist/types/exports/FFI.d.ts +12 -0
  106. package/dist/types/exports/Generator.d.ts +2 -0
  107. package/dist/types/lib/Memory.d.ts +188 -0
  108. package/dist/types/lib/Runtime.d.ts +98 -0
  109. package/dist/types/lib/backend/Functions.d.ts +65 -0
  110. package/dist/types/lib/backend/KoffiTypes.d.ts +53 -0
  111. package/dist/types/lib/declarations/Builtins.d.ts +33 -0
  112. package/dist/types/lib/declarations/Layout.d.ts +41 -0
  113. package/dist/types/lib/declarations/Lexer.d.ts +40 -0
  114. package/dist/types/lib/declarations/Parser.d.ts +90 -0
  115. package/dist/types/lib/declarations/Platform.d.ts +50 -0
  116. package/dist/types/lib/declarations/Types.d.ts +173 -0
  117. package/dist/types/lib/generator/CText.d.ts +14 -0
  118. package/dist/types/lib/generator/Generator.d.ts +136 -0
  119. package/dist/types/lib/generator/Preprocessor.d.ts +60 -0
  120. package/dist/types/lib/generator/TypeScriptTypes.d.ts +35 -0
  121. package/dist/types/lib/library/NativeCallback.d.ts +44 -0
  122. package/dist/types/lib/library/NativeLibraryHandle.d.ts +268 -0
  123. package/dist/types/lib/library/Resolve.d.ts +49 -0
  124. package/dist/types/lib/thread/NativeThreads.d.ts +80 -0
  125. package/dist/types/lib/thread/NativeWorker.d.ts +6 -0
  126. package/dist/types/lib/thread/NativeWorkerCode.d.ts +5 -0
  127. package/dist/types/lib/thread/PackageRequire.d.ts +6 -0
  128. package/dist/types/lib/thread/ThreadProtocol.d.ts +77 -0
  129. package/package.json +85 -4
@@ -0,0 +1,50 @@
1
+ /**
2
+ * What the sizes of the C types and the layout of the structs depend on
3
+ */
4
+ export interface Platform {
5
+ /**
6
+ * The operating system, as process.platform names it
7
+ */
8
+ readonly os: string;
9
+ /**
10
+ * The architecture, as process.arch names it
11
+ */
12
+ readonly arch: string;
13
+ /**
14
+ * The size of a pointer (and of size_t), in bytes
15
+ */
16
+ readonly pointerSize: 4 | 8;
17
+ /**
18
+ * The size of long: 8 on 64-bit Unix systems (LP64), 4 on Windows (LLP64) and on 32-bit systems
19
+ */
20
+ readonly longSize: 4 | 8;
21
+ /**
22
+ * The size of wchar_t: 2 on Windows, 4 elsewhere
23
+ */
24
+ readonly wcharSize: 2 | 4;
25
+ /**
26
+ * The alignment of the 8-byte types (long long, double) as members: 4 on 32-bit Linux (i386), 8 elsewhere
27
+ */
28
+ readonly int64Alignment: 4 | 8;
29
+ /**
30
+ * How bitfields are laid out: by the rules of GCC and Clang (sysv), of the ARM procedure call standard where the
31
+ * type of every bitfield aligns the struct, the unnamed and the empty ones too (aapcs: ARM but on Apple systems), or
32
+ * of the compiler of Microsoft (msvc)
33
+ */
34
+ readonly bitfields: 'sysv' | 'aapcs' | 'msvc';
35
+ /**
36
+ * Whether the symbols of the C functions start with an underscore in the binaries (macOS): the labels of __asm
37
+ * name them so
38
+ */
39
+ readonly underscoredSymbols: boolean;
40
+ }
41
+ /**
42
+ * The platform of a system and an architecture
43
+ * @param os
44
+ * @param arch
45
+ */
46
+ export declare function platformOf(os: string, arch: string): Platform;
47
+ /**
48
+ * The platform the process runs on
49
+ */
50
+ export declare const CURRENT_PLATFORM: Platform;
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CURRENT_PLATFORM = void 0;
4
+ exports.platformOf = platformOf;
5
+ /**
6
+ * The platform of a system and an architecture
7
+ * @param os
8
+ * @param arch
9
+ */
10
+ function platformOf(os, arch) {
11
+ const bits64 = !['ia32', 'arm', 'x32'].includes(arch);
12
+ const windows = os === 'win32';
13
+ return {
14
+ os: os,
15
+ arch: arch,
16
+ pointerSize: bits64 ? 8 : 4,
17
+ longSize: bits64 && !windows ? 8 : 4,
18
+ wcharSize: windows ? 2 : 4,
19
+ int64Alignment: !bits64 && !windows && arch === 'ia32' ? 4 : 8,
20
+ bitfields: windows ? 'msvc' : (arch === 'arm' || arch === 'arm64') && os !== 'darwin' ? 'aapcs' : 'sysv',
21
+ underscoredSymbols: os === 'darwin'
22
+ };
23
+ }
24
+ /**
25
+ * The platform the process runs on
26
+ */
27
+ exports.CURRENT_PLATFORM = platformOf(process.platform, process.arch);
@@ -0,0 +1,173 @@
1
+ import type { Platform } from './Platform.js';
2
+ /**
3
+ * The arithmetic types of C, by their meaning (long is not int64: their sizes differ between the platforms)
4
+ */
5
+ export type PrimitiveName = 'void' | 'bool' | 'char' | 'schar' | 'uchar' | 'short' | 'ushort' | 'int' | 'uint' | 'long' | 'ulong' | 'longlong' | 'ulonglong' | 'int8' | 'uint8' | 'int16' | 'uint16' | 'int32' | 'uint32' | 'int64' | 'uint64' | 'size' | 'ssize' | 'intptr' | 'uintptr' | 'ptrdiff' | 'char16' | 'char32' | 'wchar' | 'float' | 'double';
6
+ /**
7
+ * How the arguments of a function are passed: different on 32-bit Windows only
8
+ */
9
+ export type CallingConvention = 'cdecl' | 'stdcall' | 'fastcall' | 'thiscall';
10
+ /**
11
+ * Which way a pointer argument carries its value: into the function, out of it (the object or the array given is
12
+ * filled once it returns), or both
13
+ */
14
+ export type Direction = 'in' | 'out' | 'inout';
15
+ export interface PrimitiveType {
16
+ readonly kind: 'primitive';
17
+ readonly name: PrimitiveName;
18
+ }
19
+ export interface PointerType {
20
+ readonly kind: 'pointer';
21
+ readonly to: CType;
22
+ /**
23
+ * Whether what it points to is const (const char * is a string given to the function)
24
+ */
25
+ readonly constTarget: boolean;
26
+ }
27
+ export interface ArrayType {
28
+ readonly kind: 'array';
29
+ readonly of: CType;
30
+ readonly length: number;
31
+ }
32
+ export interface Member {
33
+ /**
34
+ * Its name; the anonymous structs and unions inside a struct are named _0, _1… in the order of the struct
35
+ */
36
+ readonly name: string;
37
+ readonly type: CType;
38
+ /**
39
+ * The width of a bitfield
40
+ */
41
+ readonly bits?: number;
42
+ /**
43
+ * The alignment its aligned attribute asks for, in bytes
44
+ */
45
+ readonly align?: number;
46
+ }
47
+ /**
48
+ * A struct or a union. One without members is opaque (declared, not defined); it is completed in place when defined
49
+ */
50
+ export interface RecordType {
51
+ readonly kind: 'struct' | 'union';
52
+ readonly tag?: string;
53
+ members?: Member[];
54
+ /**
55
+ * The alignment its members are capped at (#pragma pack, the packed attribute)
56
+ */
57
+ pack?: number;
58
+ /**
59
+ * The alignment its aligned attribute asks for, in bytes
60
+ */
61
+ align?: number;
62
+ }
63
+ export interface EnumType {
64
+ readonly kind: 'enum';
65
+ readonly tag?: string;
66
+ /**
67
+ * The integer type holding its values
68
+ */
69
+ readonly base: PrimitiveName;
70
+ readonly values: ReadonlyMap<string, bigint>;
71
+ }
72
+ export interface Parameter {
73
+ readonly name?: string;
74
+ readonly type: CType;
75
+ readonly direction: Direction;
76
+ }
77
+ export interface FunctionType {
78
+ readonly kind: 'function';
79
+ readonly result: CType;
80
+ readonly parameters: readonly Parameter[];
81
+ readonly variadic: boolean;
82
+ readonly convention: CallingConvention;
83
+ }
84
+ /**
85
+ * A C type, as the declarations describe it
86
+ */
87
+ export type CType = PrimitiveType | PointerType | ArrayType | RecordType | EnumType | FunctionType;
88
+ /**
89
+ * A function the library exports
90
+ */
91
+ export interface FunctionDeclaration {
92
+ readonly name: string;
93
+ /**
94
+ * The name of its symbol in the library: its name, or the one of its __asm label
95
+ */
96
+ readonly symbol: string;
97
+ readonly type: FunctionType;
98
+ }
99
+ /**
100
+ * A variable the library exports
101
+ */
102
+ export interface VariableDeclaration {
103
+ readonly name: string;
104
+ readonly symbol: string;
105
+ readonly type: CType;
106
+ readonly constant: boolean;
107
+ }
108
+ /**
109
+ * What a text of declarations declares
110
+ */
111
+ export interface Declarations {
112
+ /**
113
+ * The typedefs
114
+ */
115
+ readonly types: Map<string, CType>;
116
+ /**
117
+ * The tags of the structs, unions and enums ("struct timeval")
118
+ */
119
+ readonly tags: Map<string, RecordType | EnumType>;
120
+ readonly functions: Map<string, FunctionDeclaration>;
121
+ readonly variables: Map<string, VariableDeclaration>;
122
+ /**
123
+ * The values of the enumerations, of the static constants and of the macros whose value is an integer
124
+ */
125
+ readonly constants: Map<string, bigint>;
126
+ /**
127
+ * The macros without arguments (#define): their tokens, empty for the ones that are removed where used (the
128
+ * markers of exported functions); null for the macros with arguments, which cannot be used
129
+ */
130
+ readonly macros: Map<string, MacroToken[] | null>;
131
+ }
132
+ /**
133
+ * A token of a macro: its kind and its text (and its value, for a number or a character)
134
+ */
135
+ export interface MacroToken {
136
+ readonly kind: 'identifier' | 'number' | 'char' | 'string' | 'punctuator';
137
+ readonly text: string;
138
+ readonly value?: bigint;
139
+ readonly float?: boolean;
140
+ }
141
+ /**
142
+ * An empty set of declarations
143
+ */
144
+ export declare function emptyDeclarations(): Declarations;
145
+ export declare const VOID: PrimitiveType;
146
+ /**
147
+ * The size of an arithmetic type, in bytes
148
+ * @param name
149
+ * @param platform
150
+ */
151
+ export declare function primitiveSize(name: PrimitiveName, platform: Platform): number;
152
+ /**
153
+ * Whether an arithmetic type is signed
154
+ * @param name
155
+ * @param platform
156
+ */
157
+ export declare function primitiveSigned(name: PrimitiveName, platform: Platform): boolean;
158
+ /**
159
+ * Whether an arithmetic type is an integer
160
+ * @param name
161
+ */
162
+ export declare function primitiveInteger(name: PrimitiveName): boolean;
163
+ /**
164
+ * Whether an integer type is 64-bit on one of the platforms at least: its values are bigints (long is 64-bit but on
165
+ * Windows, size_t but on 32-bit systems)
166
+ * @param name
167
+ */
168
+ export declare function primitiveBig(name: PrimitiveName): boolean;
169
+ /**
170
+ * A type, as C writes it (for the messages)
171
+ * @param type
172
+ */
173
+ export declare function typeText(type: CType): string;
@@ -0,0 +1,179 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VOID = void 0;
4
+ exports.emptyDeclarations = emptyDeclarations;
5
+ exports.primitiveSize = primitiveSize;
6
+ exports.primitiveSigned = primitiveSigned;
7
+ exports.primitiveInteger = primitiveInteger;
8
+ exports.primitiveBig = primitiveBig;
9
+ exports.typeText = typeText;
10
+ /**
11
+ * An empty set of declarations
12
+ */
13
+ function emptyDeclarations() {
14
+ return { types: new Map(), tags: new Map(), functions: new Map(), variables: new Map(), constants: new Map(), macros: new Map() };
15
+ }
16
+ exports.VOID = { kind: 'primitive', name: 'void' };
17
+ /**
18
+ * The size of an arithmetic type, in bytes
19
+ * @param name
20
+ * @param platform
21
+ */
22
+ function primitiveSize(name, platform) {
23
+ switch (name) {
24
+ case 'void':
25
+ return 0;
26
+ case 'bool':
27
+ case 'char':
28
+ case 'schar':
29
+ case 'uchar':
30
+ case 'int8':
31
+ case 'uint8':
32
+ return 1;
33
+ case 'short':
34
+ case 'ushort':
35
+ case 'int16':
36
+ case 'uint16':
37
+ case 'char16':
38
+ return 2;
39
+ case 'int':
40
+ case 'uint':
41
+ case 'int32':
42
+ case 'uint32':
43
+ case 'char32':
44
+ case 'float':
45
+ return 4;
46
+ case 'long':
47
+ case 'ulong':
48
+ return platform.longSize;
49
+ case 'longlong':
50
+ case 'ulonglong':
51
+ case 'int64':
52
+ case 'uint64':
53
+ case 'double':
54
+ return 8;
55
+ case 'size':
56
+ case 'ssize':
57
+ case 'intptr':
58
+ case 'uintptr':
59
+ case 'ptrdiff':
60
+ return platform.pointerSize;
61
+ case 'wchar':
62
+ return platform.wcharSize;
63
+ }
64
+ }
65
+ /**
66
+ * Whether an arithmetic type is signed
67
+ * @param name
68
+ * @param platform
69
+ */
70
+ function primitiveSigned(name, platform) {
71
+ switch (name) {
72
+ case 'char':
73
+ //char is signed but on the ARM systems other than Apple's and Microsoft's (koffi reads it as signed everywhere)
74
+ return true;
75
+ case 'schar':
76
+ case 'short':
77
+ case 'int':
78
+ case 'long':
79
+ case 'longlong':
80
+ case 'int8':
81
+ case 'int16':
82
+ case 'int32':
83
+ case 'int64':
84
+ case 'ssize':
85
+ case 'intptr':
86
+ case 'ptrdiff':
87
+ case 'float':
88
+ case 'double':
89
+ return true;
90
+ case 'wchar':
91
+ return platform.os !== 'win32';
92
+ default:
93
+ return false;
94
+ }
95
+ }
96
+ /**
97
+ * Whether an arithmetic type is an integer
98
+ * @param name
99
+ */
100
+ function primitiveInteger(name) {
101
+ return name !== 'void' && name !== 'float' && name !== 'double';
102
+ }
103
+ /**
104
+ * Whether an integer type is 64-bit on one of the platforms at least: its values are bigints (long is 64-bit but on
105
+ * Windows, size_t but on 32-bit systems)
106
+ * @param name
107
+ */
108
+ function primitiveBig(name) {
109
+ switch (name) {
110
+ case 'long':
111
+ case 'ulong':
112
+ case 'longlong':
113
+ case 'ulonglong':
114
+ case 'int64':
115
+ case 'uint64':
116
+ case 'size':
117
+ case 'ssize':
118
+ case 'intptr':
119
+ case 'uintptr':
120
+ case 'ptrdiff':
121
+ return true;
122
+ default:
123
+ return false;
124
+ }
125
+ }
126
+ /**
127
+ * A type, as C writes it (for the messages)
128
+ * @param type
129
+ */
130
+ function typeText(type) {
131
+ switch (type.kind) {
132
+ case 'primitive':
133
+ return PRIMITIVE_TEXT[type.name];
134
+ case 'pointer':
135
+ return `${type.constTarget ? 'const ' : ''}${typeText(type.to)} *`;
136
+ case 'array':
137
+ return `${typeText(type.of)}[${type.length}]`;
138
+ case 'struct':
139
+ case 'union':
140
+ return `${type.kind} ${type.tag ?? '(anonymous)'}`;
141
+ case 'enum':
142
+ return `enum ${type.tag ?? '(anonymous)'}`;
143
+ case 'function':
144
+ return `${typeText(type.result)} (${type.parameters.map((parameter) => typeText(parameter.type)).concat(type.variadic ? ['...'] : []).join(', ')})`;
145
+ }
146
+ }
147
+ const PRIMITIVE_TEXT = {
148
+ void: 'void',
149
+ bool: 'bool',
150
+ char: 'char',
151
+ schar: 'signed char',
152
+ uchar: 'unsigned char',
153
+ short: 'short',
154
+ ushort: 'unsigned short',
155
+ int: 'int',
156
+ uint: 'unsigned int',
157
+ long: 'long',
158
+ ulong: 'unsigned long',
159
+ longlong: 'long long',
160
+ ulonglong: 'unsigned long long',
161
+ int8: 'int8_t',
162
+ uint8: 'uint8_t',
163
+ int16: 'int16_t',
164
+ uint16: 'uint16_t',
165
+ int32: 'int32_t',
166
+ uint32: 'uint32_t',
167
+ int64: 'int64_t',
168
+ uint64: 'uint64_t',
169
+ size: 'size_t',
170
+ ssize: 'ssize_t',
171
+ intptr: 'intptr_t',
172
+ uintptr: 'uintptr_t',
173
+ ptrdiff: 'ptrdiff_t',
174
+ char16: 'char16_t',
175
+ char32: 'char32_t',
176
+ wchar: 'wchar_t',
177
+ float: 'float',
178
+ double: 'double'
179
+ };
@@ -0,0 +1,14 @@
1
+ import type { Token } from '../declarations/Lexer.js';
2
+ /**
3
+ * The tokens of a declaration without what changes nothing of what it declares: the attributes but packed and aligned,
4
+ * the __declspec but align, the qualifiers the parser ignores
5
+ * @param tokens
6
+ */
7
+ export declare function prunedTokens(tokens: readonly Token[]): Token[];
8
+ /**
9
+ * A declaration written as C, one member of a struct or a value of an enum by line
10
+ * @param tokens Its tokens.
11
+ * @param indent The indentation of a level.
12
+ * @returns Its lines.
13
+ */
14
+ export declare function declarationText(tokens: readonly Token[], indent?: string): string[];
@@ -0,0 +1,133 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.prunedTokens = prunedTokens;
4
+ exports.declarationText = declarationText;
5
+ /**
6
+ * The words that change nothing of what a declaration declares, removed from the declarations written
7
+ */
8
+ const NOISE = new Set([
9
+ '__extension__', '__restrict', '__restrict__', 'restrict', '_Nullable', '_Nonnull', '_Null_unspecified', '__nullable', '__nonnull',
10
+ '__null_unspecified', '_Nullable_result', '__ptr32', '__ptr64', '__unaligned', '__w64'
11
+ ]);
12
+ /**
13
+ * The words that can follow the parenthesis of a declarator of a pointer to a function: void (*f)(void), void (__stdcall *f)(void)
14
+ */
15
+ const DECLARATOR_STARTS = new Set(['*', '__stdcall', '_stdcall', '__cdecl', '_cdecl', '__fastcall', '_fastcall', '__thiscall', '__vectorcall', '__clrcall']);
16
+ /**
17
+ * The end of the balanced brackets opened at an index: the index of the closing one
18
+ * @param tokens
19
+ * @param open
20
+ */
21
+ function closing(tokens, open) {
22
+ let depth = 0;
23
+ for (let index = open; index < tokens.length; index++) {
24
+ const token = tokens[index];
25
+ if (token.kind !== 'punctuator')
26
+ continue;
27
+ if (token.text === '(' || token.text === '[' || token.text === '{')
28
+ depth++;
29
+ else if ((token.text === ')' || token.text === ']' || token.text === '}') && --depth === 0)
30
+ return index;
31
+ }
32
+ return tokens.length - 1;
33
+ }
34
+ /**
35
+ * The tokens of a declaration without what changes nothing of what it declares: the attributes but packed and aligned,
36
+ * the __declspec but align, the qualifiers the parser ignores
37
+ * @param tokens
38
+ */
39
+ function prunedTokens(tokens) {
40
+ const kept = [];
41
+ for (let index = 0; index < tokens.length; index++) {
42
+ const token = tokens[index];
43
+ if (token.kind === 'identifier' && NOISE.has(token.text))
44
+ continue;
45
+ const attribute = token.kind === 'identifier' && (token.text === '__attribute__' || token.text === '__attribute' || token.text === '__declspec');
46
+ if (attribute && tokens[index + 1]?.text === '(') {
47
+ const end = closing(tokens, index + 1);
48
+ const inner = tokens.slice(index + 2, end).map((part) => part.text.replace(/^__|__$/g, ''));
49
+ const meaningful = token.text === '__declspec' ? inner.includes('align') : inner.includes('packed') || inner.includes('aligned');
50
+ if (meaningful)
51
+ kept.push(...tokens.slice(index, end + 1));
52
+ index = end;
53
+ continue;
54
+ }
55
+ kept.push(token);
56
+ }
57
+ return kept;
58
+ }
59
+ /**
60
+ * The text of a token as C writes it
61
+ * @param token
62
+ */
63
+ function textOf(token) {
64
+ if (token.kind === 'string')
65
+ return token.source ?? JSON.stringify(token.text);
66
+ if (token.kind === 'pragma')
67
+ return `#pragma ${token.text}`;
68
+ return token.text;
69
+ }
70
+ /**
71
+ * A declaration written as C, one member of a struct or a value of an enum by line
72
+ * @param tokens Its tokens.
73
+ * @param indent The indentation of a level.
74
+ * @returns Its lines.
75
+ */
76
+ function declarationText(tokens, indent = ' ') {
77
+ const lines = [];
78
+ let line = '';
79
+ //The braces open: whether each one is the body of an enum
80
+ const braces = [];
81
+ let parens = 0;
82
+ const breakLine = () => {
83
+ if (line.trim())
84
+ lines.push(line.replace(/\s+$/, ''));
85
+ line = indent.repeat(braces.length);
86
+ };
87
+ let previous;
88
+ for (let index = 0; index < tokens.length; index++) {
89
+ const token = tokens[index];
90
+ const text = textOf(token);
91
+ if (token.kind === 'pragma') {
92
+ breakLine();
93
+ line += text;
94
+ breakLine();
95
+ previous = undefined;
96
+ continue;
97
+ }
98
+ const punctuator = token.kind === 'punctuator' ? token.text : undefined;
99
+ if (punctuator === '{') {
100
+ const enumBody = tokens.slice(Math.max(0, index - 2), index).some((part) => part.kind === 'identifier' && part.text === 'enum');
101
+ line += `${line.trim() ? ' ' : ''}{`;
102
+ braces.push(enumBody);
103
+ breakLine();
104
+ previous = token;
105
+ continue;
106
+ }
107
+ if (punctuator === '}') {
108
+ braces.pop();
109
+ breakLine();
110
+ line += '}';
111
+ previous = token;
112
+ continue;
113
+ }
114
+ if (punctuator === '(' || punctuator === '[')
115
+ parens++;
116
+ if (punctuator === ')' || punctuator === ']')
117
+ parens--;
118
+ const glued = !previous
119
+ || [',', ';', ')', ']', '['].includes(punctuator ?? '')
120
+ || (previous.kind === 'punctuator' && ['(', '[', '*', '~', '!'].includes(previous.text))
121
+ || (punctuator === '(' && (previous.kind === 'identifier' || previous.text === ')') && !DECLARATOR_STARTS.has(tokens[index + 1]?.text ?? ''))
122
+ || !line.trim();
123
+ line += `${glued ? '' : ' '}${text}`;
124
+ previous = token;
125
+ //A member of a struct, a value of an enum: one by line
126
+ if (braces.length && !parens && (punctuator === ';' || (punctuator === ',' && braces[braces.length - 1]))) {
127
+ breakLine();
128
+ previous = undefined;
129
+ }
130
+ }
131
+ breakLine();
132
+ return lines;
133
+ }