@idlizer/arktscgen 2.1.10-arktscgen-5 → 2.1.10-arktscgen-7

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 (51) hide show
  1. package/build/libarkts-copy/generator/options.json5 +24 -47
  2. package/build/libarkts-copy/native/meson.build +29 -13
  3. package/build/libarkts-copy/native/meson_options.txt +9 -3
  4. package/build/libarkts-copy/native/mingw.cross +2 -0
  5. package/build/libarkts-copy/native/src/{bridges.cc → bridges.cpp} +31 -92
  6. package/build/libarkts-copy/native/src/{common.cc → common.cpp} +240 -107
  7. package/build/libarkts-copy/native/src/common.h +22 -22
  8. package/build/libarkts-copy/native/src/{memoryTracker.cc → memoryTracker.cpp} +45 -32
  9. package/build/libarkts-copy/package.json +13 -11
  10. package/build/libarkts-copy/src/Es2pandaNativeModule.ts +10 -63
  11. package/build/libarkts-copy/src/arkts-api/AbstractVisitor.ts +9 -3
  12. package/build/libarkts-copy/src/arkts-api/ImportStorage.ts +10 -7
  13. package/build/libarkts-copy/src/arkts-api/ProgramProvider.ts +14 -5
  14. package/build/libarkts-copy/src/arkts-api/class-by-peer.ts +19 -1
  15. package/build/libarkts-copy/src/arkts-api/factory/nodeFactory.ts +4 -0
  16. package/build/libarkts-copy/src/arkts-api/index.ts +0 -2
  17. package/build/libarkts-copy/src/arkts-api/node-cache.ts +12 -3
  18. package/build/libarkts-copy/src/arkts-api/node-utilities/ObjectExpression.ts +1 -1
  19. package/build/libarkts-copy/src/arkts-api/node-utilities/OverloadDeclaration.ts +29 -0
  20. package/build/libarkts-copy/src/arkts-api/node-utilities/ScriptFunction.ts +4 -4
  21. package/build/libarkts-copy/src/arkts-api/peers/AstNode.ts +0 -16
  22. package/build/libarkts-copy/src/arkts-api/peers/Config.ts +1 -1
  23. package/build/libarkts-copy/src/arkts-api/peers/Context.ts +9 -9
  24. package/build/libarkts-copy/src/arkts-api/plugins.ts +113 -15
  25. package/build/libarkts-copy/src/arkts-api/static/global.ts +1 -4
  26. package/build/libarkts-copy/src/arkts-api/static/profiler.ts +5 -5
  27. package/build/libarkts-copy/src/arkts-api/utilities/performance.ts +2 -1
  28. package/build/libarkts-copy/src/arkts-api/utilities/private.ts +11 -43
  29. package/build/libarkts-copy/src/arkts-api/utilities/public.ts +41 -9
  30. package/build/libarkts-copy/src/arkts-api/visitor.ts +4 -25
  31. package/build/libarkts-copy/src/checkSdk.ts +1 -1
  32. package/build/libarkts-copy/src/index.ts +1 -2
  33. package/build/libarkts-copy/src/memo-node-cache.ts +143 -0
  34. package/build/libarkts-copy/src/plugin-utils.ts +72 -40
  35. package/build/libarkts-copy/src/reexport-for-generated.ts +3 -1
  36. package/build/libarkts-copy/src/tracer.ts +2 -2
  37. package/build/libarkts-copy/src/utils.ts +10 -14
  38. package/build/libarkts-copy/tsconfig.json +0 -3
  39. package/lib/index.js +5517 -10446
  40. package/package.json +9 -7
  41. package/templates/{bridges.cc → bridges.cpp} +1 -1
  42. package/build/libarkts-copy/src/arkts-api/node-utilities/Program.ts +0 -45
  43. package/build/libarkts-copy/src/arkts-api/peers/DiagnosticKind.ts +0 -23
  44. package/build/libarkts-copy/src/ts-api/factory/nodeFactory.ts +0 -1250
  45. package/build/libarkts-copy/src/ts-api/factory/nodeTests.ts +0 -125
  46. package/build/libarkts-copy/src/ts-api/index.ts +0 -27
  47. package/build/libarkts-copy/src/ts-api/static/enums.ts +0 -18
  48. package/build/libarkts-copy/src/ts-api/types.ts +0 -1075
  49. package/build/libarkts-copy/src/ts-api/utilities/private.ts +0 -292
  50. package/build/libarkts-copy/src/ts-api/utilities/public.ts +0 -55
  51. package/build/libarkts-copy/src/ts-api/visitor/visitor.ts +0 -139
@@ -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
+ }
@@ -13,6 +13,8 @@
13
13
  * limitations under the License.
14
14
  */
15
15
 
16
+ import * as fs from "node:fs";
17
+ import * as path from "node:path";
16
18
  import {
17
19
  Es2pandaContextState,
18
20
  PluginContext,
@@ -22,49 +24,24 @@ import {
22
24
  Program,
23
25
  ProgramProvider,
24
26
  CompilationOptions,
25
- dumpProgramSrcFormatted,
27
+ PluginContextImpl,
26
28
  } from './arkts-api';
27
29
  import { Tracer } from './tracer';
30
+ import { global } from "./arkts-api/static/global";
28
31
 
29
32
  export interface RunTransformerHooks {
30
33
  onProgramTransformStart?(options: CompilationOptions, program: Program): void;
31
34
  onProgramTransformEnd?(options: CompilationOptions, program: Program): void;
32
35
  }
33
36
 
34
- class ASTCache {
35
- processedPrograms = new Set<string>();
36
- constructor() {}
37
- find(program: Program): boolean {
38
- return this.processedPrograms.has(program.absoluteName);
39
- }
40
- update(program: Program) {
41
- this.processedPrograms.add(program.absoluteName);
42
- }
43
- }
44
-
45
- export class DumpingHooks implements RunTransformerHooks {
46
- constructor(
47
- private state: Es2pandaContextState,
48
- private pluginName: string,
49
- private dumpAst: boolean = false
50
- ) {
51
- if (process.env.KOALA_DUMP_PLUGIN_AST) {
52
- this.dumpAst = true;
53
- }
37
+ export class ProfilerHooks implements RunTransformerHooks {
38
+ constructor() {
54
39
  }
55
40
  onProgramTransformStart(options: CompilationOptions, program: Program) {
56
- if (this.dumpAst) {
57
- console.log(`BEFORE ${this.pluginName}:`);
58
- dumpProgramSrcFormatted(program, true);
59
- }
60
41
  if (!options.isProgramForCodegeneration) arktsGlobal.profiler.transformDepStarted();
61
42
  }
62
43
  onProgramTransformEnd(options: CompilationOptions, program: Program) {
63
- if (!options.isProgramForCodegeneration) arktsGlobal.profiler.transformDepEnded(this.state, this.pluginName);
64
- if (this.dumpAst) {
65
- console.log(`AFTER ${this.pluginName}:`);
66
- dumpProgramSrcFormatted(program, true);
67
- }
44
+ if (!options.isProgramForCodegeneration) arktsGlobal.profiler.transformDepEnded();
68
45
  }
69
46
  }
70
47
 
@@ -73,7 +50,8 @@ export function runTransformerOnProgram(
73
50
  options: CompilationOptions,
74
51
  transform: ProgramTransformer | undefined,
75
52
  pluginContext: PluginContext,
76
- hooks: RunTransformerHooks = {}
53
+ hooks: RunTransformerHooks,
54
+ stableDeps: boolean,
77
55
  ) {
78
56
  arktsGlobal.filePath = program.absoluteName;
79
57
 
@@ -82,14 +60,19 @@ export function runTransformerOnProgram(
82
60
  // Perform some additional actions before the transformation start
83
61
  hooks.onProgramTransformStart?.(options, program);
84
62
 
85
- // Save currently existing imports in the program
86
- const importStorage = new ImportStorage(program, options.state == Es2pandaContextState.ES2PANDA_STATE_PARSED);
63
+ if (stableDeps) {
64
+ // Run the plugin itself
65
+ transform?.(program, options, pluginContext);
66
+ } else {
67
+ // Save currently existing imports in the program
68
+ const importStorage = new ImportStorage(program, options.state === Es2pandaContextState.ES2PANDA_STATE_PARSED);
87
69
 
88
- // Run the plugin itself
89
- transform?.(program, options, pluginContext);
70
+ // Run the plugin itself
71
+ transform?.(program, options, pluginContext);
90
72
 
91
- // Update internal import information based on import modification by plugin
92
- importStorage.update();
73
+ // Update internal import information based on import modification by plugin
74
+ importStorage.update();
75
+ }
93
76
 
94
77
  // Perform some additional actions after the transformation end
95
78
  hooks.onProgramTransformEnd?.(options, program);
@@ -102,10 +85,12 @@ export function runTransformer(
102
85
  state: Es2pandaContextState,
103
86
  transform: ProgramTransformer | undefined,
104
87
  pluginContext: PluginContext,
105
- hooks: RunTransformerHooks = {}
88
+ stableDeps: boolean = false,
106
89
  ) {
90
+ const hooks = new ProfilerHooks()
91
+
107
92
  // Program provider used to provide programs to transformer dynamically relative to inserted imports
108
- const provider = new ProgramProvider(prog);
93
+ const provider = new ProgramProvider(prog, stableDeps);
109
94
 
110
95
  // The first program provided by program provider is the main program
111
96
  let currentProgram = provider.next();
@@ -118,7 +103,7 @@ export function runTransformer(
118
103
  state,
119
104
  };
120
105
 
121
- runTransformerOnProgram(currentProgram, options, transform, pluginContext, hooks);
106
+ runTransformerOnProgram(currentProgram, options, transform, pluginContext, hooks, stableDeps);
122
107
 
123
108
  // The first program is always the main program
124
109
  isMainProgram = false;
@@ -134,3 +119,50 @@ function isProgramForCodegeneration(program: Program, isMainProgram: boolean): b
134
119
  }
135
120
  return program.isGenAbcForExternal;
136
121
  }
122
+
123
+ const isDebugDump: boolean = false;
124
+
125
+ function checkDebugDump() {
126
+ return isDebugDump || process.env.KOALA_DUMP_PLUGIN_AST == "1";
127
+ }
128
+
129
+ export function debugDump(
130
+ dumpDir: string | undefined,
131
+ state: Es2pandaContextState,
132
+ pluginName: string,
133
+ isAfter: boolean,
134
+ program: Program,
135
+ ) {
136
+ if (!checkDebugDump()) {
137
+ return;
138
+ }
139
+ if (!dumpDir) {
140
+ const outDir = global.arktsconfig?.outDir
141
+ if (outDir) {
142
+ dumpDir = path.join(outDir, "../dist/cache")
143
+ } else {
144
+ dumpDir = "dist/cache"
145
+ }
146
+ }
147
+ const baseDir = path.join(dumpDir,
148
+ `${state}_${isAfter ? "" : "ORI"}_${pluginName}`
149
+ );
150
+ runTransformer(
151
+ program,
152
+ state,
153
+ (program: Program) => {
154
+ if (program.absoluteName == "") {
155
+ return
156
+ }
157
+ const dumpFilePath = path.join(baseDir, path.sep + program.absoluteName)
158
+ fs.mkdirSync(path.dirname(dumpFilePath), { recursive: true })
159
+ fs.writeFileSync(
160
+ dumpFilePath,
161
+ program.ast.dumpSrc(),
162
+ 'utf-8',
163
+ )
164
+ },
165
+ new PluginContextImpl(),
166
+ true,
167
+ )
168
+ }
@@ -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 {
@@ -24,8 +26,8 @@ export {
24
26
  passStringArray,
25
27
  unpackNode,
26
28
  unpackString,
27
- assertValidPeer,
28
29
  updateNodeByNode,
30
+ unpackNativeObjectArray,
29
31
  } from './arkts-api/utilities/private';
30
32
  export { nodeByType } from './arkts-api/class-by-peer';
31
33
  export { global } from './arkts-api/static/global';
@@ -41,7 +41,7 @@ export class Tracer {
41
41
  return;
42
42
  }
43
43
  const programPath = program.absoluteName;
44
- if (programPath == '') {
44
+ if (!programPath.length) {
45
45
  return;
46
46
  }
47
47
  const suggestedTracer = Tracer.Tracers.get(programPath);
@@ -123,7 +123,7 @@ export class Tracer {
123
123
  this.trace(`${`Event "${event}"`.padEnd(maxLength)}: ${eventCnt}`);
124
124
  this.eventsPerContext?.forEach((localizedEventsMap: Map<string, number>, context: string) => {
125
125
  localizedEventsMap.forEach((localizedEventCnt: number, localizedEvent: string) => {
126
- if (localizedEvent == event) {
126
+ if (localizedEvent === event) {
127
127
  this.trace(`${` in context [${context}]`.padEnd(maxLength)}: ${localizedEventCnt}`);
128
128
  }
129
129
  });
@@ -22,7 +22,7 @@ export function withWarning<T>(value: T, message: string): T {
22
22
  return value;
23
23
  }
24
24
 
25
- export function isNumber(value: any): value is number {
25
+ export function isNumber(value: unknown): value is number {
26
26
  return typeof value === `number`;
27
27
  }
28
28
 
@@ -72,11 +72,11 @@ function replaceIllegalHashes(code: string): string {
72
72
  function replaceGensymWrappers(code: string): string {
73
73
  const indices = [...code.matchAll(/\({let/g)].map((it) => it.index);
74
74
  const replacements: string[][] = [];
75
- for (var i of indices) {
75
+ for (let i of indices) {
76
76
  if (!i) {
77
77
  continue;
78
78
  }
79
- var j = i + 1,
79
+ let j: number = i + 1,
80
80
  depth = 1;
81
81
  while (j < code.length) {
82
82
  if (code[j] == '(') {
@@ -91,7 +91,7 @@ function replaceGensymWrappers(code: string): string {
91
91
  j++;
92
92
  }
93
93
 
94
- if (j == code.length) {
94
+ if (j === code.length) {
95
95
  continue;
96
96
  }
97
97
 
@@ -104,7 +104,7 @@ function replaceGensymWrappers(code: string): string {
104
104
  /^\({let ([_%a-zA-Z0-9]+?) = (?!\({let)([\s\S]*?);\n([\s\S]*?)}\)$/g,
105
105
  (match, name: string, val: string, expr: string) => {
106
106
  let rightExpr = expr.slice(expr.lastIndexOf(name) + name.length, -1);
107
- if (rightExpr[0] != '.') {
107
+ if (rightExpr[0] !== '.') {
108
108
  rightExpr = `.${rightExpr}`;
109
109
  }
110
110
  return `(${val}?${rightExpr})`;
@@ -112,7 +112,7 @@ function replaceGensymWrappers(code: string): string {
112
112
  );
113
113
  replacements.push([base, fixed]);
114
114
  }
115
- for (var [b, f] of replacements) {
115
+ for (let [b, f] of replacements) {
116
116
  code = code.replace(b, f);
117
117
  }
118
118
  return code;
@@ -153,7 +153,7 @@ function addExports(code: string): string {
153
153
  ['export @memo_stable()', '@memo_stable() export'],
154
154
  ['export class OhosRouter', 'export default class OhosRouter'],
155
155
  ];
156
- for (var [f, t] of fix) {
156
+ for (let [f, t] of fix) {
157
157
  code = code.replaceAll(f, t);
158
158
  }
159
159
  return code.replaceAll('\nexport function main()', '\nfunction main()');
@@ -179,15 +179,15 @@ function fixEnums(code: string) {
179
179
  }
180
180
  enums.forEach((name) => {
181
181
  const regexp = new RegExp(`${name}\\.(\\w+)(.)`, `g`);
182
- code = code.replaceAll(regexp, (match, p1, p2) => {
183
- if (!p1.startsWith('_') && p2 == ':') {
182
+ code = code.replaceAll(regexp, (match: string, p1: string, p2: string) => {
183
+ if (!p1.startsWith('_') && p2 === ':') {
184
184
  // this colon is for switch case, not for type
185
185
  return `${name}.${p1}.valueOf()${p2}`;
186
186
  }
187
187
  return match;
188
188
  });
189
189
  const idents = [...code.matchAll(new RegExp(`(\\w+?)([\\W])(\\w+?): ${name}`, `g`))]
190
- .filter((it) => it[1] != 'readonly' && it[1] != '_get')
190
+ .filter((it) => it[1] !== 'readonly' && it[1] !== '_get')
191
191
  .map((it) => it[3]);
192
192
  // work manually with a couple of cases not to write one more bracket parser
193
193
  if (code.includes(`const eventKind = (deserializer.readInt32() as CallbackEventKind);`)) {
@@ -245,7 +245,3 @@ export function filterSource(text: string): string {
245
245
  // console.error(dumperUnwrappers.reduceRight((code, f) => f(code), text).split('\n').map((it, index) => `${`${index + 1}`.padStart(4)} |${it}`).join('\n'))
246
246
  return dumperUnwrappers.reduceRight((code, f) => f(code), text);
247
247
  }
248
-
249
- export function getEnumName(enumType: any, value: number): string | undefined {
250
- return enumType[value];
251
- }
@@ -10,8 +10,5 @@
10
10
  "include": [
11
11
  "./src/**/*.ts",
12
12
  "./generated/**/*.ts"
13
- ],
14
- "exclude": [
15
- "./src/ts-api/**/*.ts"
16
13
  ]
17
14
  }