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});