@idlizer/arktscgen 2.1.10-arktscgen-5 → 2.1.10-arktscgen-6
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/build/libarkts-copy/generator/options.json5 +24 -47
- package/build/libarkts-copy/native/meson.build +25 -9
- package/build/libarkts-copy/native/meson_options.txt +9 -3
- package/build/libarkts-copy/native/mingw.cross +2 -0
- package/build/libarkts-copy/native/src/bridges.cc +20 -81
- package/build/libarkts-copy/native/src/common.cc +127 -49
- package/build/libarkts-copy/native/src/memoryTracker.cc +42 -35
- package/build/libarkts-copy/package.json +12 -10
- package/build/libarkts-copy/src/Es2pandaNativeModule.ts +10 -63
- package/build/libarkts-copy/src/arkts-api/AbstractVisitor.ts +9 -3
- package/build/libarkts-copy/src/arkts-api/ImportStorage.ts +2 -4
- package/build/libarkts-copy/src/arkts-api/ProgramProvider.ts +14 -5
- package/build/libarkts-copy/src/arkts-api/class-by-peer.ts +19 -1
- package/build/libarkts-copy/src/arkts-api/index.ts +0 -1
- package/build/libarkts-copy/src/arkts-api/node-cache.ts +12 -3
- package/build/libarkts-copy/src/arkts-api/node-utilities/ObjectExpression.ts +1 -1
- package/build/libarkts-copy/src/arkts-api/node-utilities/ScriptFunction.ts +4 -4
- package/build/libarkts-copy/src/arkts-api/peers/AstNode.ts +0 -16
- package/build/libarkts-copy/src/arkts-api/peers/Config.ts +1 -1
- package/build/libarkts-copy/src/arkts-api/peers/Context.ts +10 -9
- package/build/libarkts-copy/src/arkts-api/plugins.ts +110 -5
- package/build/libarkts-copy/src/arkts-api/static/global.ts +1 -1
- package/build/libarkts-copy/src/arkts-api/static/profiler.ts +1 -1
- package/build/libarkts-copy/src/arkts-api/utilities/performance.ts +2 -1
- package/build/libarkts-copy/src/arkts-api/utilities/private.ts +4 -9
- package/build/libarkts-copy/src/arkts-api/utilities/public.ts +41 -9
- package/build/libarkts-copy/src/arkts-api/visitor.ts +4 -25
- package/build/libarkts-copy/src/checkSdk.ts +1 -1
- package/build/libarkts-copy/src/index.ts +1 -1
- package/build/libarkts-copy/src/memo-node-cache.ts +143 -0
- package/build/libarkts-copy/src/plugin-utils.ts +19 -12
- package/build/libarkts-copy/src/reexport-for-generated.ts +2 -0
- package/build/libarkts-copy/src/tracer.ts +2 -2
- package/build/libarkts-copy/src/ts-api/factory/nodeFactory.ts +2 -2
- package/build/libarkts-copy/src/ts-api/utilities/private.ts +2 -2
- package/build/libarkts-copy/src/utils.ts +10 -14
- package/lib/index.js +5316 -10427
- package/package.json +9 -7
- package/build/libarkts-copy/src/arkts-api/peers/DiagnosticKind.ts +0 -23
|
@@ -19,6 +19,7 @@ import { ExternalSource } from './peers/ExternalSource';
|
|
|
19
19
|
import { KNativePointer, nullptr } from '@koalaui/interop';
|
|
20
20
|
import { global } from './static/global';
|
|
21
21
|
import { RunTransformerHooks } from '../plugin-utils';
|
|
22
|
+
import { Context } from './peers/Context';
|
|
22
23
|
|
|
23
24
|
export interface CompilationOptions {
|
|
24
25
|
readonly isProgramForCodegeneration: boolean;
|
|
@@ -62,16 +63,32 @@ export interface ProjectConfig {
|
|
|
62
63
|
isUi2abc?: boolean;
|
|
63
64
|
}
|
|
64
65
|
|
|
65
|
-
export interface
|
|
66
|
+
export interface PluginContextBase {
|
|
66
67
|
setParameter<V>(name: string, value: V): void;
|
|
67
68
|
parameter<V>(name: string): V | undefined;
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
export
|
|
71
|
-
|
|
71
|
+
export interface PluginContext extends PluginContextBase {
|
|
72
|
+
/**
|
|
73
|
+
* @deprecated
|
|
74
|
+
*/
|
|
75
|
+
setArkTSProgram(program: Program): void
|
|
72
76
|
|
|
73
|
-
|
|
74
|
-
|
|
77
|
+
/**
|
|
78
|
+
* @deprecated
|
|
79
|
+
*/
|
|
80
|
+
getArkTSProgram(): Program | undefined
|
|
81
|
+
|
|
82
|
+
setCodingFilePath(codingFilePath: string): void
|
|
83
|
+
|
|
84
|
+
getCodingFilePath(): string | undefined
|
|
85
|
+
|
|
86
|
+
isCoding(): boolean
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
export class PluginContextBaseImpl implements PluginContextBase {
|
|
91
|
+
map = new Map<string, object | undefined>();
|
|
75
92
|
|
|
76
93
|
parameter<V>(name: string): V | undefined {
|
|
77
94
|
return this.map.get(name) as V | undefined;
|
|
@@ -79,9 +96,38 @@ export class PluginContextImpl implements PluginContext {
|
|
|
79
96
|
setParameter<V>(name: string, value: V): void {
|
|
80
97
|
this.map.set(name, value as object);
|
|
81
98
|
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
// Temporary hack to use plugin context's parameters when compiling with driver
|
|
102
|
+
export function extendPluginContext(context: PluginContextImpl) {
|
|
103
|
+
if (typeof context.setParameter == "function") {
|
|
104
|
+
return
|
|
105
|
+
}
|
|
106
|
+
const pluginContextBaseImpl = new PluginContextBaseImpl()
|
|
107
|
+
context.map = pluginContextBaseImpl.map
|
|
108
|
+
context.setParameter = pluginContextBaseImpl.setParameter
|
|
109
|
+
context.parameter = pluginContextBaseImpl.parameter
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
export class PluginContextImpl extends PluginContextBaseImpl implements PluginContext {
|
|
113
|
+
private ast: ETSModule | undefined;
|
|
114
|
+
private projectConfig: ProjectConfig | undefined;
|
|
115
|
+
|
|
116
|
+
private program: Program | undefined;
|
|
117
|
+
private codingFilePath: string | undefined;
|
|
118
|
+
|
|
119
|
+
setContextPtr(ptr: KNativePointer): void {
|
|
120
|
+
if (!global.compilerContext) {
|
|
121
|
+
global.compilerContext = new Context(ptr);
|
|
122
|
+
} else {
|
|
123
|
+
global.compilerContext.peer = ptr;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
82
127
|
getContextPtr(): KNativePointer {
|
|
83
128
|
return global.compilerContext?.peer ?? nullptr;
|
|
84
129
|
}
|
|
130
|
+
|
|
85
131
|
public setProjectConfig(projectConfig: ProjectConfig): void {
|
|
86
132
|
this.projectConfig = projectConfig;
|
|
87
133
|
}
|
|
@@ -102,14 +148,73 @@ export class PluginContextImpl implements PluginContext {
|
|
|
102
148
|
public getArkTSAst(): ETSModule | undefined {
|
|
103
149
|
return this.ast;
|
|
104
150
|
}
|
|
151
|
+
|
|
152
|
+
/**
|
|
153
|
+
* @deprecated
|
|
154
|
+
*/
|
|
155
|
+
public setArkTSProgram(program: Program): void {
|
|
156
|
+
this.program = program;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**ProjectConfig
|
|
160
|
+
* @deprecated
|
|
161
|
+
*/
|
|
162
|
+
public getArkTSProgram(): Program | undefined {
|
|
163
|
+
return this.program;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
public setCodingFilePath(codingFilePath: string): void {
|
|
167
|
+
this.codingFilePath = codingFilePath;
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
public getCodingFilePath(): string | undefined {
|
|
171
|
+
return this.codingFilePath;
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
public isCoding(): boolean {
|
|
175
|
+
return this.codingFilePath !== undefined;
|
|
176
|
+
}
|
|
105
177
|
}
|
|
106
178
|
|
|
179
|
+
export type PluginHandlerFunction = () => void;
|
|
180
|
+
|
|
181
|
+
export type PluginHandlerObject = {
|
|
182
|
+
order: 'pre' | 'post' | undefined;
|
|
183
|
+
handler: PluginHandlerFunction;
|
|
184
|
+
};
|
|
185
|
+
|
|
186
|
+
export type PluginHandler = PluginHandlerFunction | PluginHandlerObject;
|
|
187
|
+
|
|
107
188
|
export type ProgramTransformer = (
|
|
108
189
|
program: Program,
|
|
109
190
|
compilationOptions: CompilationOptions,
|
|
110
191
|
context: PluginContext
|
|
111
192
|
) => void;
|
|
112
193
|
|
|
194
|
+
export interface Plugins {
|
|
195
|
+
name: string;
|
|
196
|
+
afterNew?: PluginHandler;
|
|
197
|
+
parsed?: PluginHandler;
|
|
198
|
+
scopeInited?: PluginHandler;
|
|
199
|
+
checked?: PluginHandler;
|
|
200
|
+
lowered?: PluginHandler;
|
|
201
|
+
asmGenerated?: PluginHandler;
|
|
202
|
+
binGenerated?: PluginHandler;
|
|
203
|
+
clean?: PluginHandler;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
export type PluginState = keyof Omit<Plugins, 'name'>;
|
|
207
|
+
|
|
208
|
+
export type PluginExecutor = {
|
|
209
|
+
name: string;
|
|
210
|
+
handler: PluginHandlerFunction;
|
|
211
|
+
};
|
|
212
|
+
|
|
213
|
+
export interface BuildConfig {
|
|
214
|
+
compileFiles: string[];
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
|
|
113
218
|
export function defaultFilter(name: string): boolean {
|
|
114
219
|
if (name.startsWith('std.')) return false;
|
|
115
220
|
if (name.startsWith('escompat')) return false;
|
|
@@ -54,7 +54,7 @@ export class global {
|
|
|
54
54
|
return global._config ?? throwError('Global.config not initialized');
|
|
55
55
|
}
|
|
56
56
|
public static configIsInitialized(): boolean {
|
|
57
|
-
return global._config
|
|
57
|
+
return !!global._config && global._config !== nullptr;
|
|
58
58
|
}
|
|
59
59
|
public static resetConfig(): void {
|
|
60
60
|
global._config = undefined;
|
|
@@ -13,6 +13,7 @@
|
|
|
13
13
|
* limitations under the License.
|
|
14
14
|
*/
|
|
15
15
|
|
|
16
|
+
const { performance } = require('perf_hooks');
|
|
16
17
|
import * as process from 'process';
|
|
17
18
|
import { global as localGlobal } from '../static/global';
|
|
18
19
|
|
|
@@ -286,7 +287,7 @@ export class Performance {
|
|
|
286
287
|
'[PERFORMANCE]',
|
|
287
288
|
`External | ${context.startMemory.external.toFixed(2)} | ${(endMemory.external / (BYTES_PER_KIBIBYTE * BYTES_PER_KIBIBYTE)).toFixed(2)} | ${memoryDiff.external.toFixed(2)}`
|
|
288
289
|
);
|
|
289
|
-
if (endMemory.arrayBuffers
|
|
290
|
+
if (!!endMemory.arrayBuffers) {
|
|
290
291
|
console.log(
|
|
291
292
|
`Array Buffers | ${context.startMemory.arrayBuffers.toFixed(2)} | ${((endMemory.arrayBuffers || 0) / (BYTES_PER_KIBIBYTE * BYTES_PER_KIBIBYTE)).toFixed(2)} | ${memoryDiff.arrayBuffers.toFixed(2)}`
|
|
292
293
|
);
|
|
@@ -17,7 +17,6 @@ import { global } from '../static/global';
|
|
|
17
17
|
import { isNumber, throwError } from '../../utils';
|
|
18
18
|
import { KInt, KNativePointer as KPtr, KNativePointer, nullptr, withString, withStringArray } from '@koalaui/interop';
|
|
19
19
|
import { NativePtrDecoder } from './nativePtrDecoder';
|
|
20
|
-
//import { OptimizedNativePtrDecoder as NativePtrDecoder } from "./nativePtrDecoder"
|
|
21
20
|
import {
|
|
22
21
|
Es2pandaAstNodeType,
|
|
23
22
|
Es2pandaModifierFlags,
|
|
@@ -71,13 +70,9 @@ export function acceptNativeObjectArrayResult<T extends ArktsObject>(
|
|
|
71
70
|
arrayObject: KNativePointer,
|
|
72
71
|
factory: (instance: KNativePointer) => T
|
|
73
72
|
): T[] {
|
|
74
|
-
//
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
// prev.push(factory(curr))
|
|
78
|
-
// return prev
|
|
79
|
-
//}, [] as T[])
|
|
80
|
-
return new NativePtrDecoder().decode(arrayObject).map(factory);
|
|
73
|
+
// OptimizedNativePtrDecoder:return decoded.reduce((prev, curr)=>{prev.push(factory(curr));return prev},[] as T[])
|
|
74
|
+
const decoded = new NativePtrDecoder().decode(arrayObject)
|
|
75
|
+
return decoded.map(factory);
|
|
81
76
|
}
|
|
82
77
|
|
|
83
78
|
export function unpackNonNullableNode<T extends AstNode>(peer: KNativePointer, typeHint?: Es2pandaAstNodeType): T {
|
|
@@ -112,7 +107,7 @@ export function unpackNodeArray<T extends AstNode>(nodesPtr: KNativePointer, typ
|
|
|
112
107
|
}
|
|
113
108
|
|
|
114
109
|
export function passNodeArray(nodes: readonly ArktsObject[] | undefined): BigUint64Array {
|
|
115
|
-
return new BigUint64Array(nodes?.filter((it) => it.peer
|
|
110
|
+
return new BigUint64Array(nodes?.filter((it) => (!!it.peer))?.map((node) => BigInt(node.peer)) ?? []);
|
|
116
111
|
}
|
|
117
112
|
|
|
118
113
|
export function unpackString(peer: KNativePointer): string {
|
|
@@ -63,13 +63,13 @@ import {
|
|
|
63
63
|
MemberExpression,
|
|
64
64
|
isMethodDefinition,
|
|
65
65
|
TypeNode,
|
|
66
|
+
DiagnosticKind
|
|
66
67
|
} from '../../../generated';
|
|
67
68
|
import { Config } from '../peers/Config';
|
|
68
69
|
import { Context } from '../peers/Context';
|
|
69
70
|
import { NodeCache } from '../node-cache';
|
|
70
71
|
import { factory } from '../factory/nodeFactory';
|
|
71
72
|
import { traceGlobal } from '../../tracer';
|
|
72
|
-
import { DiagnosticKind } from '../peers/DiagnosticKind';
|
|
73
73
|
|
|
74
74
|
/**
|
|
75
75
|
* Improve: Replace or remove with better naming
|
|
@@ -78,11 +78,11 @@ import { DiagnosticKind } from '../peers/DiagnosticKind';
|
|
|
78
78
|
*/
|
|
79
79
|
export function createETSModuleFromContext(): ETSModule {
|
|
80
80
|
let program = global.generatedEs2panda._ContextProgram(global.context);
|
|
81
|
-
if (program
|
|
81
|
+
if (program === nullptr || program === null) {
|
|
82
82
|
throw new Error(`Program is null for context ${global.context.toString(16)}`);
|
|
83
83
|
}
|
|
84
84
|
const ast = global.generatedEs2panda._ProgramAst(global.context, program);
|
|
85
|
-
if (ast
|
|
85
|
+
if (ast === nullptr || ast === null) {
|
|
86
86
|
throw new Error(`AST is null for program ${program.toString(16)}`);
|
|
87
87
|
}
|
|
88
88
|
return new ETSModule(ast, Es2pandaAstNodeType.AST_NODE_TYPE_ETS_MODULE);
|
|
@@ -122,10 +122,19 @@ export function checkErrors() {
|
|
|
122
122
|
traceGlobal(() => `Terminated due to compilation errors occured`);
|
|
123
123
|
console.log(unpackString(global.generatedEs2panda._GetAllErrorMessages(global.context)));
|
|
124
124
|
// global.es2panda._DestroyConfig(global.config)
|
|
125
|
-
|
|
125
|
+
throw new Error(`Compilation error`)
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
128
|
|
|
129
|
+
function format(value: number): string {
|
|
130
|
+
return `${(value / 1024 / 1024 / 1024).toFixed(4)} GB`
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
// Improve: move to profiler
|
|
134
|
+
function dumpMemoryProfilerInfo(str: string) {
|
|
135
|
+
console.log(str, format(process.memoryUsage().rss));
|
|
136
|
+
}
|
|
137
|
+
|
|
129
138
|
export function proceedToState(state: Es2pandaContextState): void {
|
|
130
139
|
if (state <= global.es2panda._ContextState(global.context)) {
|
|
131
140
|
return;
|
|
@@ -137,6 +146,9 @@ export function proceedToState(state: Es2pandaContextState): void {
|
|
|
137
146
|
traceGlobal(() => `Proceeding to state ${Es2pandaContextState[state]}: done`);
|
|
138
147
|
const after = Date.now();
|
|
139
148
|
global.profiler.proceededToState(after - before);
|
|
149
|
+
if (state == Es2pandaContextState.ES2PANDA_STATE_BIN_GENERATED) {
|
|
150
|
+
dumpMemoryProfilerInfo("Memory usage (rss) after proceed to bin:")
|
|
151
|
+
}
|
|
140
152
|
checkErrors();
|
|
141
153
|
}
|
|
142
154
|
|
|
@@ -372,7 +384,7 @@ export function generateTsDeclarationsFromContext(
|
|
|
372
384
|
recordFile: string,
|
|
373
385
|
genAnnotations: boolean
|
|
374
386
|
): KInt {
|
|
375
|
-
return global.
|
|
387
|
+
return global.generatedEs2panda._GenerateTsDeclarationsFromContext(
|
|
376
388
|
global.context,
|
|
377
389
|
passString(outputDeclEts),
|
|
378
390
|
passString(outputEts),
|
|
@@ -451,7 +463,7 @@ export function createDiagnosticInfo(
|
|
|
451
463
|
...args: string[]
|
|
452
464
|
): DiagnosticInfo {
|
|
453
465
|
return new DiagnosticInfo(
|
|
454
|
-
global.
|
|
466
|
+
global.generatedEs2panda._CreateDiagnosticInfo(
|
|
455
467
|
global.context,
|
|
456
468
|
kind.peer,
|
|
457
469
|
passStringArray(args),
|
|
@@ -469,7 +481,7 @@ export function createSuggestionInfo(
|
|
|
469
481
|
...args: string[]
|
|
470
482
|
): SuggestionInfo {
|
|
471
483
|
return new SuggestionInfo(
|
|
472
|
-
global.
|
|
484
|
+
global.generatedEs2panda._CreateSuggestionInfo(
|
|
473
485
|
global.context,
|
|
474
486
|
kind.peer,
|
|
475
487
|
passStringArray(args),
|
|
@@ -493,6 +505,26 @@ export function logDiagnosticWithSuggestion(diagnosticInfo: DiagnosticInfo, sugg
|
|
|
493
505
|
global.generatedEs2panda._LogDiagnosticWithSuggestion(global.context, diagnosticInfo.peer, suggestionInfo.peer);
|
|
494
506
|
}
|
|
495
507
|
|
|
496
|
-
export function filterNodes(node: AstNode, filter: string): AstNode[] {
|
|
497
|
-
return unpackNodeArray(global.es2panda._FilterNodes(global.context, passNode(node), filter));
|
|
508
|
+
export function filterNodes(node: AstNode, filter: string, deeperAfterMatch: boolean): AstNode[] {
|
|
509
|
+
return unpackNodeArray(global.es2panda._FilterNodes(global.context, passNode(node), filter, deeperAfterMatch));
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
export function filterNodesByType<T extends AstNode = AstNode>(node: AstNode, type: Es2pandaAstNodeType): T[] {
|
|
513
|
+
return unpackNodeArray(global.es2panda._FilterNodes2(global.context, passNode(node), type), type);
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
export function filterNodesByTypes(node: AstNode, types: Es2pandaAstNodeType[]): AstNode[] {
|
|
517
|
+
const typesArray = new Int32Array(types.length)
|
|
518
|
+
for (let i = 0; i < types.length; i++) {
|
|
519
|
+
typesArray[i] = types[i]
|
|
520
|
+
}
|
|
521
|
+
return unpackNodeArray(global.es2panda._FilterNodes3(global.context, passNode(node), typesArray, types.length));
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
export function MemInitialize() {
|
|
525
|
+
global.es2panda._MemInitialize()
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
export function MemFinalize() {
|
|
529
|
+
global.es2panda._MemFinalize()
|
|
498
530
|
}
|
|
@@ -258,34 +258,17 @@ function visitETSTypeReferencePart(node: ETSTypeReferencePart, visitor: Visitor)
|
|
|
258
258
|
function visitScriptFunction(node: ScriptFunction, visitor: Visitor): ScriptFunction {
|
|
259
259
|
global.updateTracker.push();
|
|
260
260
|
const newBody = nodeVisitor(node.body, visitor);
|
|
261
|
-
const
|
|
262
|
-
const newTypeParams = nodeVisitor(oldTypeParams, visitor);
|
|
261
|
+
const newTypeParams = nodeVisitor(node.typeParams, visitor);
|
|
263
262
|
const newParams: readonly Expression[] = nodesVisitor(node.params, visitor);
|
|
264
263
|
const newReturnTypeAnnotation = nodeVisitor(node.returnTypeAnnotation, visitor);
|
|
265
264
|
const newId = nodeVisitor(node.id, visitor);
|
|
266
265
|
const newAnnotations: readonly AnnotationUsage[] = nodesVisitor(node.annotations, visitor);
|
|
267
266
|
if (global.updateTracker.check()) {
|
|
268
|
-
if (!isSameNativeObject(newTypeParams, oldTypeParams)) {
|
|
269
|
-
const result = factory.createScriptFunction(
|
|
270
|
-
newBody,
|
|
271
|
-
newTypeParams,
|
|
272
|
-
newParams,
|
|
273
|
-
newReturnTypeAnnotation,
|
|
274
|
-
node.hasReceiver,
|
|
275
|
-
node.flags,
|
|
276
|
-
node.modifierFlags,
|
|
277
|
-
newId,
|
|
278
|
-
newAnnotations,
|
|
279
|
-
node.getSignaturePointer(),
|
|
280
|
-
node.getPreferredReturnTypePointer()
|
|
281
|
-
);
|
|
282
|
-
result.onUpdate(node);
|
|
283
|
-
return result;
|
|
284
|
-
}
|
|
285
267
|
node.setBody(newBody);
|
|
286
268
|
node.setParams(newParams);
|
|
269
|
+
node.setTypeParams(newTypeParams);
|
|
287
270
|
node.setReturnTypeAnnotation(newReturnTypeAnnotation);
|
|
288
|
-
|
|
271
|
+
node.setIdent(newId);
|
|
289
272
|
node.setAnnotations(newAnnotations);
|
|
290
273
|
}
|
|
291
274
|
return node;
|
|
@@ -314,7 +297,6 @@ function visitMethodDefinition(node: MethodDefinition, visitor: Visitor): Method
|
|
|
314
297
|
node.setOverloads(newOverloads);
|
|
315
298
|
newOverloads.forEach((it): void => {
|
|
316
299
|
it.setBaseOverloadMethod(node);
|
|
317
|
-
it.parent = node;
|
|
318
300
|
});
|
|
319
301
|
}
|
|
320
302
|
return node;
|
|
@@ -538,7 +520,6 @@ function visitIfStatement(node: IfStatement, visitor: Visitor): IfStatement {
|
|
|
538
520
|
return result;
|
|
539
521
|
}
|
|
540
522
|
node.setTest(newTest);
|
|
541
|
-
if (newTest) newTest.parent = node;
|
|
542
523
|
node.setAlternate(newAlternate);
|
|
543
524
|
}
|
|
544
525
|
return node;
|
|
@@ -828,7 +809,6 @@ function visitETSNewClassInstanceExpression(
|
|
|
828
809
|
return result;
|
|
829
810
|
}
|
|
830
811
|
node.setArguments(newArguments);
|
|
831
|
-
newArguments.forEach((it) => (it.parent = node));
|
|
832
812
|
}
|
|
833
813
|
return node;
|
|
834
814
|
}
|
|
@@ -865,7 +845,7 @@ function visitForUpdateStatement(node: ForUpdateStatement, visitor: Visitor): Fo
|
|
|
865
845
|
global.updateTracker.push();
|
|
866
846
|
const newInit = nodeVisitor(node.init, visitor);
|
|
867
847
|
const newTest = nodeVisitor(node.test, visitor);
|
|
868
|
-
const newUpdate = nodeVisitor(node.
|
|
848
|
+
const newUpdate = nodeVisitor(node.updateExpression, visitor);
|
|
869
849
|
const newBody = nodeVisitor(node.body, visitor);
|
|
870
850
|
if (global.updateTracker.check()) {
|
|
871
851
|
const result = factory.createForUpdateStatement(newInit, newTest, newUpdate, newBody);
|
|
@@ -922,7 +902,6 @@ function visitTSNonNullExpression(node: TSNonNullExpression, visitor: Visitor):
|
|
|
922
902
|
const newExpr = nodeVisitor(node.expr, visitor);
|
|
923
903
|
if (global.updateTracker.check()) {
|
|
924
904
|
node.setExpr(newExpr);
|
|
925
|
-
if (newExpr) newExpr.parent = node;
|
|
926
905
|
}
|
|
927
906
|
return node;
|
|
928
907
|
}
|
|
@@ -31,7 +31,7 @@ export function checkSDK() {
|
|
|
31
31
|
if (!version) reportErrorAndExit(`version is unknown`);
|
|
32
32
|
const packageJsonOur = JSON.parse(fs.readFileSync(path.join(__dirname, '..', 'package.json')).toString());
|
|
33
33
|
const expectedVersion = packageJsonOur.config.panda_sdk_version;
|
|
34
|
-
if (expectedVersion && expectedVersion
|
|
34
|
+
if (expectedVersion && expectedVersion !== 'next' && version !== expectedVersion)
|
|
35
35
|
console.log(`WARNING: Panda SDK version "${version}" doesn't match expected "${expectedVersion}"`);
|
|
36
36
|
else console.log(`Using Panda ${version}`);
|
|
37
37
|
}
|
|
@@ -38,10 +38,10 @@ export { GlobalContext } from './arkts-api/peers/Context';
|
|
|
38
38
|
export * from './arkts-api/peers/ExternalSource';
|
|
39
39
|
export * from './arkts-api/peers/ImportPathManager';
|
|
40
40
|
export * from './arkts-api/peers/Options';
|
|
41
|
-
export * from './arkts-api/peers/DiagnosticKind';
|
|
42
41
|
export { global as arktsGlobal } from './arkts-api/static/global';
|
|
43
42
|
export * from './arkts-api/static/globalUtils';
|
|
44
43
|
export * as arkts from './arkts-api';
|
|
45
44
|
|
|
46
45
|
export * from './plugin-utils';
|
|
47
46
|
export * from './tracer';
|
|
47
|
+
export * from './memo-node-cache';
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Copyright (c) 2025 Huawei Device Co., Ltd.
|
|
3
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
4
|
+
* you may not use this file except in compliance with the License.
|
|
5
|
+
* You may obtain a copy of the License at
|
|
6
|
+
*
|
|
7
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
8
|
+
*
|
|
9
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
10
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
11
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
|
+
* See the License for the specific language governing permissions and
|
|
13
|
+
* limitations under the License.
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { KNativePointer } from "@koalaui/interop";
|
|
17
|
+
import { AstNode, Es2pandaAstNodeType, factory, unpackString } from "./arkts-api";
|
|
18
|
+
import { global } from "./arkts-api/static/global";
|
|
19
|
+
|
|
20
|
+
// Improve: this should actually belong to plugin contexts, not to libarkts
|
|
21
|
+
|
|
22
|
+
export interface AstNodeCacheValue {
|
|
23
|
+
peer: KNativePointer;
|
|
24
|
+
type: Es2pandaAstNodeType;
|
|
25
|
+
metadata?: AstNodeCacheValueMetadata;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export interface AstNodeCacheValueMetadata {
|
|
29
|
+
callName?: string;
|
|
30
|
+
hasReceiver?: boolean;
|
|
31
|
+
isSetter?: boolean;
|
|
32
|
+
isGetter?: boolean;
|
|
33
|
+
forbidTypeRewrite?: boolean;
|
|
34
|
+
isWithinTypeParams?: boolean;
|
|
35
|
+
hasMemoSkip?: boolean;
|
|
36
|
+
hasMemoIntrinsic?: boolean;
|
|
37
|
+
hasMemoEntry?: boolean;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
export class MemoNodeCache {
|
|
41
|
+
private _isCollected: boolean = false;
|
|
42
|
+
private cacheMap: Map<KNativePointer, AstNodeCacheValue>;
|
|
43
|
+
private static instance: MemoNodeCache;
|
|
44
|
+
static disableMemoNodeCache = false;
|
|
45
|
+
|
|
46
|
+
private constructor() {
|
|
47
|
+
this.cacheMap = new Map();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
static getInstance(): MemoNodeCache {
|
|
51
|
+
if (!this.instance) {
|
|
52
|
+
this.instance = new MemoNodeCache();
|
|
53
|
+
}
|
|
54
|
+
if (this.disableMemoNodeCache) {
|
|
55
|
+
return this.instance
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
// Please provide the another way to force cache update on when node updates
|
|
59
|
+
wrapFuncWithNodeCache(this.instance, "updateArrowFunctionExpression")
|
|
60
|
+
wrapFuncWithNodeCache(this.instance, "updateBreakStatement")
|
|
61
|
+
wrapFuncWithNodeCache(this.instance, "updateCallExpression")
|
|
62
|
+
wrapFuncWithNodeCache(this.instance, "updateClassProperty")
|
|
63
|
+
wrapFuncWithNodeCache(this.instance, "updateETSFunctionType")
|
|
64
|
+
wrapFuncWithNodeCache(this.instance, "updateETSParameterExpression")
|
|
65
|
+
wrapFuncWithNodeCache(this.instance, "updateETSUnionType")
|
|
66
|
+
wrapFuncWithNodeCache(this.instance, "updateIdentifier")
|
|
67
|
+
wrapFuncWithNodeCache(this.instance, "updateMethodDefinition")
|
|
68
|
+
wrapFuncWithNodeCache(this.instance, "updateProperty")
|
|
69
|
+
wrapFuncWithNodeCache(this.instance, "updateReturnStatement")
|
|
70
|
+
wrapFuncWithNodeCache(this.instance, "updateScriptFunction")
|
|
71
|
+
wrapFuncWithNodeCache(this.instance, "updateTSTypeAliasDeclaration")
|
|
72
|
+
wrapFuncWithNodeCache(this.instance, "updateVariableDeclarator")
|
|
73
|
+
|
|
74
|
+
return this.instance;
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
collect(node: AstNode, metadata?: AstNodeCacheValueMetadata): void {
|
|
78
|
+
if (MemoNodeCache.disableMemoNodeCache) {
|
|
79
|
+
return
|
|
80
|
+
}
|
|
81
|
+
const peer = node.peer;
|
|
82
|
+
const type = global.generatedEs2panda._AstNodeTypeConst(global.context, node.peer);
|
|
83
|
+
let currMetadata: AstNodeCacheValueMetadata | undefined = metadata ?? {};
|
|
84
|
+
if (this.cacheMap.has(peer)) {
|
|
85
|
+
const oldMetadata = this.cacheMap.get(peer)!.metadata ?? {};
|
|
86
|
+
currMetadata = { ...oldMetadata, ...currMetadata };
|
|
87
|
+
}
|
|
88
|
+
currMetadata = Object.keys(currMetadata).length === 0 ? undefined : currMetadata;
|
|
89
|
+
this.cacheMap.set(peer, { peer, type, metadata: currMetadata });
|
|
90
|
+
this._isCollected = true;
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
refresh(original: AstNode, node: AstNode): void {
|
|
94
|
+
let metadata: AstNodeCacheValueMetadata | undefined;
|
|
95
|
+
if (this.has(original)) {
|
|
96
|
+
metadata = this.get(original)?.metadata;
|
|
97
|
+
this.cacheMap.delete(original.peer);
|
|
98
|
+
}
|
|
99
|
+
this.collect(node, metadata);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
isCollected(): boolean {
|
|
103
|
+
return this._isCollected;
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
has(node: AstNode): boolean {
|
|
107
|
+
return this.cacheMap.has(node.peer);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
get(node: AstNode): AstNodeCacheValue | undefined {
|
|
111
|
+
return this.cacheMap.get(node.peer);
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
clear(): void {
|
|
115
|
+
this.cacheMap.clear();
|
|
116
|
+
this._isCollected = false;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
visualize(): void {
|
|
120
|
+
Array.from(this.cacheMap.values()).forEach(({ peer, type, metadata }) => {
|
|
121
|
+
const src = global.generatedEs2panda._AstNodeDumpEtsSrcConst(global.context, peer)
|
|
122
|
+
console.log(
|
|
123
|
+
`[NODE CACHE] ptr ${peer}, type: ${type}, metadata: ${JSON.stringify(metadata)}, node: `,
|
|
124
|
+
unpackString(src)
|
|
125
|
+
);
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
function wrapFuncWithNodeCache(cache: MemoNodeCache, funcName: keyof typeof factory) {
|
|
131
|
+
if ((funcName+"__orig") in factory) return;
|
|
132
|
+
|
|
133
|
+
let orig = factory[funcName] as any;
|
|
134
|
+
let wrapped = function (this: any, original: AstNode, ...args: any[]) {
|
|
135
|
+
let newNode = orig.call(this, original, ...args);
|
|
136
|
+
if (cache.has(original)) {
|
|
137
|
+
cache.refresh(original, newNode);
|
|
138
|
+
}
|
|
139
|
+
return newNode
|
|
140
|
+
};
|
|
141
|
+
(factory as any)[funcName] = wrapped as any;
|
|
142
|
+
(factory as any)[funcName+"__orig"] = orig as any;
|
|
143
|
+
}
|
|
@@ -53,7 +53,7 @@ export class DumpingHooks implements RunTransformerHooks {
|
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
55
|
onProgramTransformStart(options: CompilationOptions, program: Program) {
|
|
56
|
-
if (this.dumpAst) {
|
|
56
|
+
if (this.dumpAst && !program.absoluteName.includes("absolute-sdk-patched")) {
|
|
57
57
|
console.log(`BEFORE ${this.pluginName}:`);
|
|
58
58
|
dumpProgramSrcFormatted(program, true);
|
|
59
59
|
}
|
|
@@ -61,7 +61,7 @@ export class DumpingHooks implements RunTransformerHooks {
|
|
|
61
61
|
}
|
|
62
62
|
onProgramTransformEnd(options: CompilationOptions, program: Program) {
|
|
63
63
|
if (!options.isProgramForCodegeneration) arktsGlobal.profiler.transformDepEnded(this.state, this.pluginName);
|
|
64
|
-
if (this.dumpAst) {
|
|
64
|
+
if (this.dumpAst && !program.absoluteName.includes("absolute-sdk-patched")) {
|
|
65
65
|
console.log(`AFTER ${this.pluginName}:`);
|
|
66
66
|
dumpProgramSrcFormatted(program, true);
|
|
67
67
|
}
|
|
@@ -73,7 +73,8 @@ export function runTransformerOnProgram(
|
|
|
73
73
|
options: CompilationOptions,
|
|
74
74
|
transform: ProgramTransformer | undefined,
|
|
75
75
|
pluginContext: PluginContext,
|
|
76
|
-
hooks: RunTransformerHooks = {}
|
|
76
|
+
hooks: RunTransformerHooks = {},
|
|
77
|
+
stableDeps: boolean = false,
|
|
77
78
|
) {
|
|
78
79
|
arktsGlobal.filePath = program.absoluteName;
|
|
79
80
|
|
|
@@ -82,14 +83,19 @@ export function runTransformerOnProgram(
|
|
|
82
83
|
// Perform some additional actions before the transformation start
|
|
83
84
|
hooks.onProgramTransformStart?.(options, program);
|
|
84
85
|
|
|
85
|
-
|
|
86
|
-
|
|
86
|
+
if (stableDeps) {
|
|
87
|
+
// Run the plugin itself
|
|
88
|
+
transform?.(program, options, pluginContext);
|
|
89
|
+
} else {
|
|
90
|
+
// Save currently existing imports in the program
|
|
91
|
+
const importStorage = new ImportStorage(program, options.state === Es2pandaContextState.ES2PANDA_STATE_PARSED);
|
|
87
92
|
|
|
88
|
-
|
|
89
|
-
|
|
93
|
+
// Run the plugin itself
|
|
94
|
+
transform?.(program, options, pluginContext);
|
|
90
95
|
|
|
91
|
-
|
|
92
|
-
|
|
96
|
+
// Update internal import information based on import modification by plugin
|
|
97
|
+
importStorage.update();
|
|
98
|
+
}
|
|
93
99
|
|
|
94
100
|
// Perform some additional actions after the transformation end
|
|
95
101
|
hooks.onProgramTransformEnd?.(options, program);
|
|
@@ -102,10 +108,11 @@ export function runTransformer(
|
|
|
102
108
|
state: Es2pandaContextState,
|
|
103
109
|
transform: ProgramTransformer | undefined,
|
|
104
110
|
pluginContext: PluginContext,
|
|
105
|
-
hooks: RunTransformerHooks = {}
|
|
111
|
+
hooks: RunTransformerHooks = {},
|
|
112
|
+
stableDeps: boolean = false,
|
|
106
113
|
) {
|
|
107
114
|
// Program provider used to provide programs to transformer dynamically relative to inserted imports
|
|
108
|
-
const provider = new ProgramProvider(prog);
|
|
115
|
+
const provider = new ProgramProvider(prog, stableDeps);
|
|
109
116
|
|
|
110
117
|
// The first program provided by program provider is the main program
|
|
111
118
|
let currentProgram = provider.next();
|
|
@@ -118,7 +125,7 @@ export function runTransformer(
|
|
|
118
125
|
state,
|
|
119
126
|
};
|
|
120
127
|
|
|
121
|
-
runTransformerOnProgram(currentProgram, options, transform, pluginContext, hooks);
|
|
128
|
+
runTransformerOnProgram(currentProgram, options, transform, pluginContext, hooks, stableDeps);
|
|
122
129
|
|
|
123
130
|
// The first program is always the main program
|
|
124
131
|
isMainProgram = false;
|
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
*/
|
|
15
15
|
export { KNativePointer } from '@koalaui/interop';
|
|
16
16
|
export { AstNode } from './arkts-api/peers/AstNode';
|
|
17
|
+
export { Config } from './arkts-api/peers/Config';
|
|
18
|
+
export { Context, GlobalContext } from './arkts-api/peers/Context';
|
|
17
19
|
export { ArktsObject, isSameNativeObject } from './arkts-api/peers/ArktsObject';
|
|
18
20
|
export { NodeCache } from './arkts-api/node-cache';
|
|
19
21
|
export {
|