• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
16import { CompileFileInfo, ModuleInfo } from '../types';
17import { BuildConfig } from '../types';
18import { Logger } from '../logger';
19import * as fs from 'fs';
20import * as path from 'path';
21import {
22  changeDeclgenFileExtension,
23  changeFileExtension,
24  createFileIfNotExists,
25  ensurePathExists
26} from '../utils';
27import {
28  DECL_ETS_SUFFIX,
29  DECL_TS_SUFFIX,
30  KOALA_WRAPPER_PATH_FROM_SDK,
31  STATIC_RECORD_FILE,
32  STATIC_RECORD_FILE_CONTENT,
33  TS_SUFFIX
34} from '../pre_define';
35import { PluginDriver, PluginHook } from '../plugins/plugins_driver';
36
37process.on('message', (message: {
38  taskList: CompileFileInfo[];
39  buildConfig: BuildConfig;
40  moduleInfos: Array<[string, ModuleInfo]>;
41}) => {
42  if (!process.send) {
43    throw new Error('process.send is undefined. This worker must be run as a forked process.');
44  }
45  const { taskList, buildConfig, moduleInfos } = message;
46  const moduleInfosMap = new Map<string, ModuleInfo>(moduleInfos);
47
48  const logger = Logger.getInstance(buildConfig);
49  const pluginDriver = PluginDriver.getInstance();
50  pluginDriver.initPlugins(buildConfig);
51
52  const koalaWrapperPath = path.resolve(buildConfig.buildSdkPath, KOALA_WRAPPER_PATH_FROM_SDK);
53  let { arkts, arktsGlobal } = require(koalaWrapperPath);
54
55  for (const fileInfo of taskList) {
56    let errorStatus = false;
57    try {
58      const source = fs.readFileSync(fileInfo.filePath, 'utf8');
59      let moduleInfo = moduleInfosMap.get(fileInfo.packageName)!;
60      let filePathFromModuleRoot: string = path.relative(moduleInfo.moduleRootPath, fileInfo.filePath);
61      let declEtsOutputPath: string = path.join(
62        moduleInfo.declgenV1OutPath as string,
63        moduleInfo.packageName,
64        filePathFromModuleRoot
65      );
66      declEtsOutputPath = changeFileExtension(declEtsOutputPath, DECL_ETS_SUFFIX);
67      let etsOutputPath: string = path.join(
68        moduleInfo.declgenBridgeCodePath as string,
69        moduleInfo.packageName,
70        filePathFromModuleRoot
71      );
72      etsOutputPath = changeFileExtension(etsOutputPath, TS_SUFFIX);
73
74      ensurePathExists(declEtsOutputPath);
75      ensurePathExists(etsOutputPath);
76
77      const staticRecordPath = path.join(
78        moduleInfo.declgenV1OutPath as string,
79        STATIC_RECORD_FILE
80      )
81      const declEtsOutputDir = path.dirname(declEtsOutputPath);
82      const staticRecordRelativePath = changeFileExtension(
83        path.relative(declEtsOutputDir, staticRecordPath).replaceAll(/\\/g, '\/'),
84        '',
85        DECL_TS_SUFFIX
86      );
87      createFileIfNotExists(staticRecordPath, STATIC_RECORD_FILE_CONTENT);
88
89      arktsGlobal.filePath = fileInfo.filePath;
90      arktsGlobal.config = arkts.Config.create([
91        '_',
92        '--extension',
93        'ets',
94        '--arktsconfig',
95        fileInfo.arktsConfigFile,
96        fileInfo.filePath
97      ]).peer;
98      arktsGlobal.compilerContext = arkts.Context.createFromString(source);
99      pluginDriver.getPluginContext().setArkTSProgram(arktsGlobal.compilerContext.program);
100
101      arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_PARSED, true);
102
103      let ast = arkts.EtsScript.fromContext();
104      pluginDriver.getPluginContext().setArkTSAst(ast);
105      pluginDriver.runPluginHook(PluginHook.PARSED);
106
107      arkts.proceedToState(arkts.Es2pandaContextState.ES2PANDA_STATE_CHECKED, true);
108
109      ast = arkts.EtsScript.fromContext();
110      pluginDriver.getPluginContext().setArkTSAst(ast);
111      pluginDriver.runPluginHook(PluginHook.CHECKED);
112
113      arkts.generateTsDeclarationsFromContext(
114        declEtsOutputPath,
115        etsOutputPath,
116        false,
117        staticRecordRelativePath
118      ); // Generate 1.0 declaration files & 1.0 glue code
119      logger.printInfo('declaration files generated');
120
121      process.send({ success: true, filePath: fileInfo.filePath });
122    } catch (error) {
123      errorStatus = true;
124      if (error instanceof Error) {
125        process.send({
126          success: false,
127          isDeclFile: true,
128          filePath: fileInfo.filePath,
129          error: 'Generate declaration files failed.\n' + error.message
130        });
131      }
132    } finally {
133      if (!errorStatus) {
134        // when error occur,wrapper will destroy context.
135        arktsGlobal.es2panda._DestroyContext(arktsGlobal.compilerContext.peer);
136      }
137      arkts.destroyConfig(arktsGlobal.config);
138    }
139  }
140  process.exit(0);
141});