From 3960f8c6660cab2cbcf4597cc268aca7dda7eeb2 Mon Sep 17 00:00:00 2001 From: kleene Date: Wed, 23 Jul 2025 11:04:09 +0800 Subject: [PATCH] refactor entry of ets2bundle when mixcompile Issue: ICODVB Signed-off-by: kleene Change-Id: Id3b40f96832844b347de1d4f2f32df0fa4431aee --- compiler/compile_plugin.js | 17 ++++ compiler/src/interop/main.js | 6 +- .../ark_compiler/interop/interop_manager.ts | 82 ++++++++++++++++--- .../ark_compiler/interop/pre_define.ts | 9 +- .../fast_build/ark_compiler/interop/type.ts | 11 ++- .../fast_build/ark_compiler/interop/utils.ts | 25 ++++++ .../common/process_project_config.ts | 2 +- .../interop/interop_manager.test.ts | 47 ++++++++++- 8 files changed, 179 insertions(+), 20 deletions(-) create mode 100644 compiler/src/interop/src/fast_build/ark_compiler/interop/utils.ts diff --git a/compiler/compile_plugin.js b/compiler/compile_plugin.js index 675dae30d..73297fc82 100644 --- a/compiler/compile_plugin.js +++ b/compiler/compile_plugin.js @@ -28,7 +28,24 @@ const { generateConsumerObConfigFile } = require('./lib/fast_build/ark_compiler/ const { etsStandaloneChecker } = require('./lib/ets_checker'); const { memoryMonitor } = require('./lib/fast_build/meomry_monitor/rollup-plugin-memory-monitor'); +let initConfigForInterop = (interopConfig) => { + return {}; +}; + +try { + ({ initConfigForInterop } = require('./lib/fast_build/ark_compiler/interop/interop_manager')); +} catch (err) { + if (err.code !== 'MODULE_NOT_FOUND') { + throw err; + } +} + +function initInteropConfig(interopConfig) { + return initConfigForInterop(interopConfig); +} + exports.initConfig = initConfig; +exports.initInteropConfig = initInteropConfig; exports.getCleanConfig = getCleanConfig; exports.generateConsumerObConfigFile = generateConsumerObConfigFile; exports.etsStandaloneChecker = etsStandaloneChecker; diff --git a/compiler/src/interop/main.js b/compiler/src/interop/main.js index 36cbe76f2..2e7a8bced 100644 --- a/compiler/src/interop/main.js +++ b/compiler/src/interop/main.js @@ -51,7 +51,7 @@ const { } = require('./lib/fast_build/ark_compiler/interop/interop_manager'); const { - ARKTS_1_2 + ARKTS_MODE } = require('./lib/fast_build/ark_compiler/interop/pre_define'); configure({ @@ -505,7 +505,7 @@ function readAbilityEntrance(moduleJson) { if (moduleJson.module) { const moduleSrcEntrance = moduleJson.module.srcEntrance; const moduleSrcEntry = moduleJson.module.srcEntry; - const isStatic = moduleJson.module?.abilityStageCodeLanguage === ARKTS_1_2; + const isStatic = moduleJson.module?.arkTSMode === ARKTS_MODE.STATIC; if (moduleSrcEntry) { abilityPages.push(moduleSrcEntry); @@ -530,7 +530,7 @@ function readAbilityEntrance(moduleJson) { function setEntrance(abilityConfig, abilityPages) { if (abilityConfig && abilityConfig.length > 0) { abilityConfig.forEach(ability => { - const isStatic = ability.codeLanguage === ARKTS_1_2; + const isStatic = ability.arkTSMode === ARKTS_MODE.STATIC; if (ability.srcEntry) { abilityPages.push(ability.srcEntry); entryFileLanguageInfo.set(ability.srcEntry, isStatic); diff --git a/compiler/src/interop/src/fast_build/ark_compiler/interop/interop_manager.ts b/compiler/src/interop/src/fast_build/ark_compiler/interop/interop_manager.ts index 3fe736afd..097d28555 100644 --- a/compiler/src/interop/src/fast_build/ark_compiler/interop/interop_manager.ts +++ b/compiler/src/interop/src/fast_build/ark_compiler/interop/interop_manager.ts @@ -17,14 +17,23 @@ import fs from 'fs'; import path from 'path'; import { + globalModulePaths, + initBuildInfo, + loadEntryObj, + loadModuleInfo, + loadWorker, projectConfig, + readAppResource, + readPatchConfig, + readWorkerFile, sdkConfigs } from '../../../../main'; import { toUnixPath } from '../../../utils'; import { ArkTSEvolutionModule, FileInfo, - AliasConfig + AliasConfig, + InteropConfig } from './type'; import { hasExistingPaths, @@ -46,8 +55,11 @@ import { ARKTS_1_2, ARKTS_HYBRID } from './pre_define'; +import { readFirstLineSync } from './utils'; export let entryFileLanguageInfo = new Map(); +export let workerFile = null; +export let mixCompile = undefined; export class FileManager { private static instance: FileManager | undefined = undefined; @@ -218,6 +230,7 @@ export class FileManager { FileManager.aliasConfig?.clear(); FileManager.mixCompile = false; entryFileLanguageInfo.clear(); + mixCompile = undefined; } getLanguageVersionByFilePath(filePath: string): { @@ -433,15 +446,6 @@ export function collectSDKInfo(share: Object): { }; } -function readFirstLineSync(filePath: string): string { - const buffer = fs.readFileSync(filePath, 'utf-8'); - const newlineIndex = buffer.indexOf('\n'); - if (newlineIndex === -1) { - return buffer.trim(); - } - return buffer.substring(0, newlineIndex).trim(); -} - export function isBridgeCode(filePath: string, projectConfig: Object): boolean { if (!projectConfig?.mixCompile) { return false; @@ -455,6 +459,9 @@ export function isBridgeCode(filePath: string, projectConfig: Object): boolean { } export function isMixCompile(): boolean { + if (typeof mixCompile === 'boolean') { + return mixCompile; + } return process.env.mixCompile === 'true'; } @@ -545,7 +552,7 @@ export function getApiPathForInterop(apiDirs: string[], languageVersion: string) apiDirs.unshift(...staticPaths); } -export function rebuildEntryObj(projectConfig: Object): void { +export function rebuildEntryObj(projectConfig: Object, interopConfig: InteropConfig): void { const entryObj = projectConfig.entryObj; const removeExt = (p: string): string => p.replace(/\.[^/.]+$/, ''); @@ -562,7 +569,7 @@ export function rebuildEntryObj(projectConfig: Object): void { if (!firstLine.includes('use static')) { newEntry[newKey] = rawPath; } else if (rawPath.startsWith(projectConfig.projectRootPath)) { - const bridgePath = process.env.entryBridgeCodePath; + const bridgePath = getBrdigeCodeRootPath(rawPath, interopConfig); if (!bridgePath) { const errInfo = LogDataFactory.newInstance( ErrorCode.ETS2BUNDLE_INTERNAL_MISSING_BRIDGECODE_PATH_INFO, @@ -580,3 +587,54 @@ export function rebuildEntryObj(projectConfig: Object): void { return newEntry; }, {} as Record); } + + +/** + * corresponds to compiler/src/fast_build/common/init_config.ts - initConfig() + */ +export function initConfigForInterop(interopConfig: InteropConfig): Object { + function getEntryObj(): void { + loadEntryObj(projectConfig); + initBuildInfo(); + readPatchConfig(); + loadModuleInfo(projectConfig); + workerFile = readWorkerFile(); + if (!projectConfig.isPreview) { + loadWorker(projectConfig, workerFile); + } + if (isMixCompile()) { + rebuildEntryObj(projectConfig, interopConfig); + return; + } + projectConfig.entryObj = Object.keys(projectConfig.entryObj).reduce((newEntry, key) => { + const newKey: string = key.replace(/^\.\//, ''); + newEntry[newKey] = projectConfig.entryObj[key].replace('?entry', ''); + return newEntry; + }, {}); + } + mixCompile = interopConfig.mixCompile; + getEntryObj(); + if (process.env.appResource) { + readAppResource(process.env.appResource); + } + return { + entryObj: Object.assign({}, projectConfig.entryObj, projectConfig.otherCompileFiles), + cardEntryObj: projectConfig.cardEntryObj, + workerFile: workerFile, + globalModulePaths: globalModulePaths + }; +} + +export function getBrdigeCodeRootPath(filePath: string, interopConfig: InteropConfig): string | undefined { + if (!interopConfig) { + return process.env.entryBridgeCodePath; + } + + for (const [moduleRootPath, InteropInfo] of interopConfig.interopModuleInfo) { + if (isSubPathOf(filePath, moduleRootPath)) { + return InteropInfo.declgenBridgeCodePath; + } + } + + return undefined; +} \ No newline at end of file diff --git a/compiler/src/interop/src/fast_build/ark_compiler/interop/pre_define.ts b/compiler/src/interop/src/fast_build/ark_compiler/interop/pre_define.ts index eaa908d41..82aaebb55 100644 --- a/compiler/src/interop/src/fast_build/ark_compiler/interop/pre_define.ts +++ b/compiler/src/interop/src/fast_build/ark_compiler/interop/pre_define.ts @@ -16,4 +16,11 @@ export const ARKTS_1_2: string = '1.2'; export const ARKTS_1_1: string = '1.1'; export const ARKTS_1_0: string = '1.0'; -export const ARKTS_HYBRID: string = 'hybrid'; \ No newline at end of file +export const ARKTS_HYBRID: string = 'hybrid'; + +export const DECLGEN_CACHE_FILE = 'declgen_cache.json'; + +export enum ARKTS_MODE { + STATIC = 'static', + DYNAMIC = 'dynamic' +} \ No newline at end of file diff --git a/compiler/src/interop/src/fast_build/ark_compiler/interop/type.ts b/compiler/src/interop/src/fast_build/ark_compiler/interop/type.ts index 3a3dc2a11..e1b177985 100644 --- a/compiler/src/interop/src/fast_build/ark_compiler/interop/type.ts +++ b/compiler/src/interop/src/fast_build/ark_compiler/interop/type.ts @@ -112,4 +112,13 @@ export interface FileInfo { baseUrl: string; abstractPath: string; } -export const DECLGEN_CACHE_FILE = 'declgen_cache.json'; + +export interface InteropInfo { + declgenBridgeCodePath: string; + declgenV1OutPath: string; +} + +export interface InteropConfig { + mixCompile: boolean; + interopModuleInfo: Map; +} diff --git a/compiler/src/interop/src/fast_build/ark_compiler/interop/utils.ts b/compiler/src/interop/src/fast_build/ark_compiler/interop/utils.ts new file mode 100644 index 000000000..757c30f8d --- /dev/null +++ b/compiler/src/interop/src/fast_build/ark_compiler/interop/utils.ts @@ -0,0 +1,25 @@ +/* + * Copyright (c) 2025 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +import fs from 'fs'; + +export function readFirstLineSync(filePath: string): string { + const buffer = fs.readFileSync(filePath, 'utf-8'); + const newlineIndex = buffer.indexOf('\n'); + if (newlineIndex === -1) { + return buffer.trim(); + } + return buffer.substring(0, newlineIndex).trim(); +} \ No newline at end of file diff --git a/compiler/src/interop/src/fast_build/common/process_project_config.ts b/compiler/src/interop/src/fast_build/common/process_project_config.ts index 5d11fed17..ac5860870 100644 --- a/compiler/src/interop/src/fast_build/common/process_project_config.ts +++ b/compiler/src/interop/src/fast_build/common/process_project_config.ts @@ -14,11 +14,11 @@ */ import fs from 'fs'; import path from 'path'; + import { isMixCompile, rebuildEntryObj } from '../ark_compiler/interop/interop_manager'; - const { projectConfig, loadEntryObj, diff --git a/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts b/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts index edef58a15..ddb250c9b 100644 --- a/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts +++ b/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts @@ -20,7 +20,8 @@ import path from "path"; import { FileManager, collectSDKInfo, - isBridgeCode + isBridgeCode, + getBrdigeCodeRootPath } from '../../../lib/fast_build/ark_compiler/interop/interop_manager'; import { ARKTS_1_1, ARKTS_1_2, ARKTS_HYBRID } from '../../../lib/fast_build/ark_compiler/interop/pre_define'; import { sdkConfigs } from '../../../main'; @@ -309,4 +310,46 @@ mocha.describe('isBridgeCode', function () { const filePath = path.resolve('path/one/module.ts'); expect(isBridgeCode(filePath, config)).to.be.true; }); -}); \ No newline at end of file +}); + +mocha.describe('test getBrdigeCodeRootPath api', function () { + mocha.it('1-1: should return bridgeCodePath from interopConfig when filePath matches moduleRootPath', function () { + const filePath = '/a/b/c/file.ts'; + const mockConfig: InteropConfig = { + mixCompile: false, + interopModuleInfo: new Map([ + ['/a/b', { + declgenBridgeCodePath: '/bridge/a/b', + declgenV1OutPath: '/v1' + }] + ]) + }; + + const result = getBrdigeCodeRootPath(filePath, mockConfig); + expect(result).to.equal('/bridge/a/b'); + }); + + mocha.it('1-2: should return undefined when filePath does not match any moduleRootPath', function () { + const filePath = '/x/y/z/file.ts'; + const mockConfig: InteropConfig = { + mixCompile: false, + interopModuleInfo: new Map([ + ['/a/b', { + declgenBridgeCodePath: '/bridge/a/b', + declgenV1OutPath: '/v1' + }] + ]) + }; + + const result = getBrdigeCodeRootPath(filePath, mockConfig); + expect(result).to.be.undefined; + }); + + mocha.it('1-3: should return process.env.entryBridgeCodePath when interopConfig is null', function () { + process.env.entryBridgeCodePath = '/default/bridge/path'; + const filePath = '/any/file.ts'; + + const result = getBrdigeCodeRootPath(filePath, undefined as any); + expect(result).to.equal('/default/bridge/path'); + }); +}); -- Gitee