@isopodlabs/binary_libs 0.0.1 → 0.1.1

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.
package/transform.ts ADDED
@@ -0,0 +1,369 @@
1
+ import ts, { factory } from "typescript";
2
+
3
+ function isExported(node: ts.Declaration): boolean {
4
+ return (ts.getCombinedModifierFlags(node) & ts.ModifierFlags.Export) !== 0;
5
+ }
6
+
7
+ export function kind(node: ts.Node): string {
8
+ return ts.SyntaxKind[node.kind];
9
+ }
10
+
11
+ function hasSingleTypeParameter(node: ts.FunctionDeclaration | ts.MethodDeclaration): ts.ParameterDeclaration|undefined {
12
+ if (node.typeParameters && node.typeParameters.length == 1) {
13
+ const typeParam = node.typeParameters[0];
14
+
15
+ if (ts.isTypeParameterDeclaration(typeParam) && typeParam.constraint) {
16
+ let param: ts.ParameterDeclaration | undefined;
17
+
18
+ for (const p of node.parameters) {
19
+ if (p.type && ts.isTypeReferenceNode(p.type) && p.type.typeName.getText() === typeParam.name.text) {
20
+ if (param)
21
+ return;
22
+ param = p;
23
+ }
24
+ }
25
+
26
+ return param;
27
+ }
28
+ }
29
+ }
30
+
31
+ function createParameters(node: ts.FunctionDeclaration | ts.MethodDeclaration, param: ts.ParameterDeclaration, member: ts.TypeNode) {
32
+ return node.parameters.map(p => {
33
+ if (p === param) {
34
+ p = factory.createParameterDeclaration(
35
+ undefined, //modifiers
36
+ undefined, //dotDotDotToken
37
+ param.name, //name
38
+ undefined, //questionToken
39
+ member, //type
40
+ );
41
+ (p.type as any).parent = p;
42
+ }
43
+ return p;
44
+ });
45
+ }
46
+
47
+ function resolveTypesTransformer(program: ts.Program): ts.TransformerFactory<ts.SourceFile> | undefined {
48
+ console.log("Resolving Types");
49
+ const typeChecker = program.getTypeChecker();
50
+
51
+ function getMembersOfConstraintType(constraint: ts.TypeNode): ts.TypeNode[] {
52
+ const type = typeChecker.getTypeAtLocation(constraint);
53
+
54
+ const declarations = type.getSymbol()?.getDeclarations();
55
+ if (declarations) {
56
+ let declaration: ts.EnumDeclaration|undefined;
57
+ for (const i of declarations) {
58
+ if (ts.isEnumDeclaration(i)) {
59
+ declaration = i;
60
+ break;
61
+ }
62
+ }
63
+ if (declaration) {
64
+ const prefix = typeChecker.typeToString(type, declaration);
65
+ return declaration.members.map(i => factory.createTypeReferenceNode(
66
+ factory.createQualifiedName(factory.createIdentifier(prefix), i.name.getText()),
67
+ undefined
68
+ ));
69
+ }
70
+ }
71
+
72
+ if (type.isUnion()) {
73
+ if (type.types.every(i => i.isNumberLiteral()))
74
+ return type.types.map(i => factory.createLiteralTypeNode(factory.createNumericLiteral(i.value)));
75
+
76
+ if (type.types.every(i => i.isStringLiteral()))
77
+ return type.types.map(i => factory.createLiteralTypeNode(factory.createStringLiteral(i.value)));
78
+ }
79
+ return [];
80
+ }
81
+
82
+ return (context: ts.TransformationContext) => {
83
+ return (sourceFile: ts.SourceFile) => {
84
+ //TO DISABLE:
85
+ //return sourceFile;
86
+
87
+ let typeformatflags = ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope|ts.TypeFormatFlags.NoTruncation|ts.TypeFormatFlags.MultilineObjectLiterals;
88
+ let exported = false;
89
+ let depth = 0;
90
+ let declaration: ts.Declaration | undefined;
91
+ const inherited: ts.ExpressionWithTypeArguments[] = [];
92
+
93
+ // Create a cache for module resolution
94
+ const moduleResolutionCache = ts.createModuleResolutionCache(
95
+ process.cwd(), // Current working directory
96
+ fileName => fileName // Normalize file names
97
+ );
98
+
99
+ const moduleMap: Record<string, string> = {};
100
+
101
+ function serializeNode(node: ts.Node): string {
102
+ const printer = ts.createPrinter();
103
+ const result = printer.printNode(ts.EmitHint.Unspecified, node, sourceFile);
104
+ return result;
105
+ }
106
+
107
+ function print(x: string) {
108
+ console.log(' '.repeat(depth), x);
109
+ }
110
+
111
+ function fixParents(node: ts.Node) {
112
+ let parent = node;
113
+ function visit(node: ts.Node): ts.Node {
114
+ const save = parent;
115
+ parent = node;
116
+ node = ts.visitEachChild(node, visit, context);
117
+ (node as any).parent = parent = save;
118
+ return node;
119
+ }
120
+ return ts.visitEachChild(node, visit, context);
121
+ }
122
+ function templateSubstitute(node: ts.Node, param: string, replacement: ts.TypeNode) {
123
+ function visit(node: ts.Node): ts.Node {
124
+ if (ts.isTypeReferenceNode(node)) {
125
+ // If the type node is a reference to the type parameter, replace it
126
+ if (ts.isIdentifier(node.typeName) && node.typeName.text === param)
127
+ return replacement;
128
+ }
129
+ return ts.visitEachChild(node, visit, context);
130
+ }
131
+ return ts.visitNode(node, visit);
132
+ }
133
+
134
+ function createReturn(node: ts.FunctionDeclaration | ts.MethodDeclaration, member: ts.TypeNode) {
135
+ const ret = fixParents(templateSubstitute(node.type!, node.typeParameters![0].name.getText(), member));
136
+ const obj = ret as any;
137
+ //(ret as any).original = undefined;
138
+ obj.flags &= ~16;
139
+ obj.parent = obj.original.parent;
140
+ return ret as ts.TypeNode;
141
+ }
142
+
143
+
144
+ //various type fixing
145
+ function visitSubType(node: ts.Node): ts.Node {
146
+ //print(kind(node));
147
+
148
+ if (ts.isQualifiedName(node))
149
+ return node;
150
+
151
+ // add module prefix if missing
152
+ if (ts.isIdentifier(node)) {
153
+ const symbol = (node as any).symbol;
154
+ if (symbol) {
155
+ const declarations = symbol.getDeclarations();
156
+ if (declarations && declarations.length > 0) {
157
+ const prefix = moduleMap[declarations[0].getSourceFile().fileName];
158
+ if (prefix)
159
+ return factory.createQualifiedName(factory.createIdentifier(prefix), node.text);
160
+ }
161
+ }
162
+ }
163
+
164
+ ++depth;
165
+ node = ts.visitEachChild(node, visitSubType, context);
166
+ --depth;
167
+
168
+ // strip {}'s from intersection
169
+ if (ts.isIntersectionTypeNode(node)) {
170
+ const filtered = node.types.filter(n => !ts.isTypeLiteralNode(n) || n.members.length);
171
+ if (filtered.length === 1)
172
+ return filtered[0];
173
+ return ts.factory.updateIntersectionTypeNode(node, ts.factory.createNodeArray(filtered));
174
+ }
175
+
176
+ // remove parentheses if not needed
177
+ if (ts.isParenthesizedTypeNode(node)) {
178
+ if (ts.isTypeLiteralNode(node.type))
179
+ return node.type;
180
+ }
181
+
182
+ return node;
183
+ }
184
+
185
+ //finds types
186
+ function visitType(node: ts.Node): ts.Node | undefined {
187
+ if (ts.isTypeNode(node)) {
188
+ const type = typeChecker.getTypeAtLocation(node);
189
+ const typetext = typeChecker.typeToString(type, declaration);
190
+ //print('"'+typetext+'"');
191
+
192
+ let node1 = typetext === 'any' ? node : typeChecker.typeToTypeNode(type, declaration, typeformatflags);
193
+
194
+ if (node1 && !ts.isTypeReferenceNode(node1)) {
195
+ node1 = visitSubType(node1) as ts.TypeNode;
196
+ const text2 = serializeNode(node1);
197
+ //console.log("**AFTER**" + text2);
198
+ if (text2 !== 'any')
199
+ return node1;
200
+ }
201
+
202
+ return node;
203
+ }
204
+ return ts.visitEachChild(node, visitType, context);
205
+ }
206
+
207
+ function fixTypes(node: ts.Declaration) {
208
+ const save = declaration;
209
+ declaration = node;
210
+ //fixParents(node);
211
+ node = ts.visitEachChild(node, visitType, context);
212
+ declaration = save;
213
+ return node;
214
+ }
215
+
216
+ // VISIT
217
+ function visit(node: ts.Node): ts.Node | undefined {
218
+ //print(kind(node));
219
+
220
+ if (ts.isVariableDeclaration(node)) {
221
+ if (isExported(node)) {
222
+ exported = true;
223
+ return node;
224
+ }
225
+ for (const i of inherited) {
226
+ if (i.expression === node.name) {
227
+ declaration = node;
228
+ exported = true;
229
+ //return node;
230
+ return fixTypes(node);
231
+ }
232
+ }
233
+ return undefined; // Remove the node
234
+ }
235
+
236
+ if (ts.isVariableStatement(node)) {
237
+ exported = false;
238
+ node = ts.visitEachChild(node, visit, context);
239
+ return exported ? node : undefined;
240
+ }
241
+
242
+ if (ts.isTypeAliasDeclaration(node)) {
243
+ declaration = node;
244
+ //print("++TYPEDEF");
245
+ const save = typeformatflags;
246
+ typeformatflags = (typeformatflags & ~ts.TypeFormatFlags.UseAliasDefinedOutsideCurrentScope) | ts.TypeFormatFlags.InTypeAlias | ts.TypeFormatFlags.MultilineObjectLiterals;
247
+ node = fixTypes(node);
248
+ typeformatflags = save;
249
+ //print("--TYPEDEF");
250
+ return node;
251
+ }
252
+
253
+ if (ts.isClassDeclaration(node)) {
254
+ const newMembers: ts.ClassElement[] = [];
255
+ let update = false;
256
+ for (const member of node.members) {
257
+ const param = ts.isMethodDeclaration(member) && hasSingleTypeParameter(member);
258
+ if (param) {
259
+ update = true;
260
+ const members = getMembersOfConstraintType(member.typeParameters![0].constraint!);
261
+ const overloads = members.map(i => factory.createMethodDeclaration(
262
+ undefined, // modifiers
263
+ undefined, // asteriskToken
264
+ member.name, // name
265
+ undefined, // questionToken
266
+ undefined, // typeParameters
267
+ createParameters(member, param, i), // parameters
268
+ createReturn(member, i), //type
269
+ undefined //body
270
+ ));
271
+ // Add the overloads to the class members
272
+ newMembers.push(...overloads);
273
+ } else {
274
+ // Add the original member to the class
275
+ newMembers.push(member);
276
+ }
277
+ }
278
+ if (update) {
279
+ // Update the class declaration with the new members
280
+ node = factory.updateClassDeclaration(
281
+ node,
282
+ node.modifiers,
283
+ node.name,
284
+ node.typeParameters,
285
+ node.heritageClauses,
286
+ newMembers
287
+ );
288
+ }
289
+ }
290
+
291
+ if (ts.isMethodDeclaration(node))
292
+ return fixTypes(node);
293
+
294
+ if (ts.isPropertyDeclaration(node))
295
+ return fixTypes(node);
296
+
297
+ if (ts.isFunctionDeclaration(node))
298
+ return fixTypes(node);
299
+
300
+ ++depth;
301
+ node = ts.visitEachChild(node, visit, context);
302
+ --depth;
303
+ return node;
304
+ //return ts.visitEachChild(node, visit, context);
305
+ }
306
+
307
+ //SourceFile:
308
+ const newStatements: ts.Statement[] = [];
309
+
310
+ for (const statement of sourceFile.statements) {
311
+ //check for inheriting consts
312
+ if (ts.isClassDeclaration(statement)) {
313
+ const heritageClauses = statement.heritageClauses;
314
+ if (heritageClauses) {
315
+ for (const i of heritageClauses) {
316
+ if (i.token === ts.SyntaxKind.ExtendsKeyword)
317
+ inherited.push(...i.types);
318
+ }
319
+ }
320
+
321
+ } else if (ts.isImportDeclaration(statement)) {
322
+ const importClause = statement.importClause;
323
+ if (importClause && importClause.namedBindings && ts.isNamespaceImport(importClause.namedBindings)) {
324
+ const module = statement.moduleSpecifier;
325
+ if (ts.isStringLiteral(module)) {
326
+ // Resolve the module name to its file path
327
+ const resolved = ts.resolveModuleName(
328
+ module.text,
329
+ sourceFile.fileName,
330
+ program.getCompilerOptions(),
331
+ {
332
+ fileExists: ts.sys.fileExists, // File system methods
333
+ readFile: ts.sys.readFile,
334
+ },
335
+ moduleResolutionCache
336
+ );
337
+
338
+ if (resolved.resolvedModule)
339
+ moduleMap[resolved.resolvedModule.resolvedFileName] = importClause.namedBindings.name.text;
340
+ }
341
+ }
342
+
343
+ } else if (ts.isFunctionDeclaration(statement)) {
344
+ const param = hasSingleTypeParameter(statement);
345
+ if (param) {
346
+ console.log("hi");
347
+ const members = getMembersOfConstraintType(statement.typeParameters![0].constraint!);
348
+ const overloads = members.map(i => factory.createFunctionDeclaration(
349
+ [factory.createModifier(ts.SyntaxKind.ExportKeyword)], // Add export
350
+ undefined, //asteriskToken
351
+ statement.name, //name
352
+ undefined, //type params
353
+ createParameters(statement, param, i),
354
+ createReturn(statement, i), //type
355
+ undefined //body
356
+ ));
357
+ newStatements.push(...overloads);
358
+ continue;
359
+ }
360
+ }
361
+
362
+ newStatements.push(statement);
363
+ }
364
+ return ts.visitEachChild(factory.updateSourceFile(sourceFile, newStatements), visit, context);
365
+ };
366
+ };
367
+ }
368
+
369
+ export default resolveTypesTransformer;
package/tsconfig.json CHANGED
@@ -4,12 +4,19 @@
4
4
  "module": "commonjs",
5
5
  "strict": true,
6
6
  "declaration": true,
7
+ "stripInternal": true,
7
8
  "esModuleInterop": true,
8
9
  "skipLibCheck": true,
9
10
  "forceConsistentCasingInFileNames": true,
10
11
  "outDir": "./dist",
11
- "rootDir": "./src"
12
- },
12
+ "rootDir": "./src",
13
+ "plugins": [
14
+ {
15
+ "transform": "./transform.ts",
16
+ "afterDeclarations": true
17
+ }
18
+ ]
19
+ },
13
20
  "include": [
14
21
  "src/**/*.ts"
15
22
  ],
@@ -17,4 +24,4 @@
17
24
  "node_modules",
18
25
  "**/*.spec.ts"
19
26
  ]
20
- }
27
+ }
@@ -0,0 +1 @@
1
+ {"root":["./src/compounddocument.ts","./src/arch.ts","./src/clr.ts","./src/elf.ts","./src/mach.ts","./src/pe.ts"],"errors":true,"version":"5.9.0-dev"}
@@ -1,129 +0,0 @@
1
- import * as binary from '@isopodlabs/binary';
2
- declare class FAT {
3
- shift: number;
4
- sectors: Uint8Array;
5
- fat: Int32Array;
6
- freed: number[];
7
- dirty_fat: Set<number>;
8
- dirty_sec: Set<number>;
9
- constructor(size: number, shift: number, sectors: Uint8Array);
10
- private free;
11
- private alloc;
12
- get_chain(id: number): number[];
13
- resize_chain(chain: number[], data_size: number): void;
14
- clear_dirty(): void;
15
- read_chain(chain: number[], dest: Uint8Array): void;
16
- read_chain_alloc(chain: number[]): Uint8Array;
17
- read(id: number, dest: Uint8Array): void;
18
- write_chain(chain: number[], source: Uint8Array): void;
19
- dirty_chain_part(chain: number[], offset: number): Uint8Array;
20
- }
21
- declare const Header_base: (new (s: binary._stream) => {
22
- magic: bigint;
23
- id: any;
24
- revision: number;
25
- version: number;
26
- byteorder: number;
27
- sector_shift: number;
28
- mini_shift: number;
29
- unused1: void;
30
- num_directory: number;
31
- num_fat: number;
32
- first_directory: number;
33
- transaction: void;
34
- mini_cutoff: number;
35
- first_mini: number;
36
- num_mini: number;
37
- first_difat: number;
38
- num_difat: number;
39
- difat: any;
40
- } & {} & {
41
- write(w: binary._stream): void;
42
- }) & {
43
- get: (s: binary._stream) => {
44
- magic: bigint;
45
- id: any;
46
- revision: number;
47
- version: number;
48
- byteorder: number;
49
- sector_shift: number;
50
- mini_shift: number;
51
- unused1: void;
52
- num_directory: number;
53
- num_fat: number;
54
- first_directory: number;
55
- transaction: void;
56
- mini_cutoff: number;
57
- first_mini: number;
58
- num_mini: number;
59
- first_difat: number;
60
- num_difat: number;
61
- difat: any;
62
- } & {};
63
- put: (s: binary._stream, v: any) => void;
64
- };
65
- export declare class Header extends Header_base {
66
- sector_size(): number;
67
- use_mini(size: number): boolean;
68
- valid(): boolean;
69
- }
70
- declare const DirEntry_base: (new (s: binary._stream) => {
71
- name: string;
72
- name_size: number;
73
- type: number;
74
- colour: number;
75
- left: number;
76
- right: number;
77
- root: number;
78
- guid: any;
79
- flags: number;
80
- creation: bigint;
81
- modification: bigint;
82
- sec_id: number;
83
- size: number;
84
- unused: number;
85
- } & {} & {
86
- write(w: binary._stream): void;
87
- }) & {
88
- get: (s: binary._stream) => {
89
- name: string;
90
- name_size: number;
91
- type: number;
92
- colour: number;
93
- left: number;
94
- right: number;
95
- root: number;
96
- guid: any;
97
- flags: number;
98
- creation: bigint;
99
- modification: bigint;
100
- sec_id: number;
101
- size: number;
102
- unused: number;
103
- } & {};
104
- put: (s: binary._stream, v: any) => void;
105
- };
106
- declare class DirEntry extends DirEntry_base {
107
- index: number;
108
- constructor(index: number, r: binary.stream);
109
- load(fat: FAT): Uint8Array;
110
- }
111
- export declare class Master {
112
- header: Header;
113
- difat: Int32Array;
114
- fat: FAT;
115
- mini_fat: FAT;
116
- mini_chain: number[];
117
- constructor(sectors: Uint8Array, header: Header);
118
- get_fat(mini: boolean): FAT;
119
- flush(filename: string): Promise<void>;
120
- }
121
- export declare class Reader extends Master {
122
- entries: DirEntry[];
123
- private entry_chain;
124
- constructor(sectors: Uint8Array, header: Header);
125
- find(name: string, i?: number): DirEntry | undefined;
126
- read(e: DirEntry): Uint8Array;
127
- write(e: DirEntry, data: Uint8Array): void;
128
- }
129
- export {};