From d5a12cc2e6a64eef7ea8f4d4a21825fb1c2dcd57 Mon Sep 17 00:00:00 2001 From: zenghang Date: Fri, 13 Jun 2025 17:35:59 +0800 Subject: [PATCH] fix declgen bugs Issue: ICF2UU Signed-off-by: zenghang Change-Id: I454dcfc5950cc773243e5fa54211caa19731d105 --- compiler/main.js | 26 ++-- .../src/fast_build/ark_compiler/error_code.ts | 1 + .../ark_compiler/interop/interop_manager.ts | 145 ++++++++++++------ .../interop/run_declgen_standalone.ts | 3 +- .../fast_build/ark_compiler/interop/type.ts | 15 -- compiler/src/fast_build/ark_compiler/utils.ts | 6 + .../ets_ui/rollup-plugin-ets-checker.ts | 18 ++- .../test/ark_compiler_ut/common/utils.test.ts | 51 +++++- .../interop/interop_manager.test.ts | 120 ++++++++++++++- 9 files changed, 303 insertions(+), 82 deletions(-) diff --git a/compiler/main.js b/compiler/main.js index 22dbce8fa..c272569a3 100644 --- a/compiler/main.js +++ b/compiler/main.js @@ -31,7 +31,8 @@ const { FAIL, TEST_RUNNER_DIR_SET, TS2ABC, - WORKERS_DIR + WORKERS_DIR, + ARKTS_1_2 } = require('./lib/pre_define'); const { @@ -419,7 +420,7 @@ function setAbilityPages(projectConfig) { if (projectConfig.aceModuleJsonPath && fs.existsSync(projectConfig.aceModuleJsonPath)) { const moduleJson = JSON.parse(fs.readFileSync(projectConfig.aceModuleJsonPath).toString()); abilityPages = readAbilityEntrance(moduleJson); - setAbilityFile(projectConfig, abilityPages, moduleJson.module?.codeLanguage); + setAbilityFile(projectConfig, abilityPages); setBundleModuleInfo(projectConfig, moduleJson); } } @@ -486,16 +487,13 @@ function setBundleModuleInfo(projectConfig, moduleJson) { } } -function setAbilityFile(projectConfig, abilityPages, codeLanguage) { +function setAbilityFile(projectConfig, abilityPages) { abilityPages.forEach(abilityPath => { const projectAbilityPath = path.resolve(projectConfig.projectPath, '../', abilityPath); if (path.isAbsolute(abilityPath)) { abilityPath = '.' + abilityPath.slice(projectConfig.projectPath.length); } const entryPageKey = abilityPath.replace(/^\.\/ets\//, './').replace(/\.ts$/, '').replace(/\.ets$/, ''); - if (codeLanguage === '1.2') { - return; - } if (fs.existsSync(projectAbilityPath)) { abilityConfig.projectAbilityPath.push(projectAbilityPath); projectConfig.entryObj[entryPageKey] = projectAbilityPath + '?entry'; @@ -513,10 +511,13 @@ function readAbilityEntrance(moduleJson) { if (moduleJson.module) { const moduleSrcEntrance = moduleJson.module.srcEntrance; const moduleSrcEntry = moduleJson.module.srcEntry; - if (moduleSrcEntry) { + // In a mixed compilation project, we only collect entries and abilities for version 1.1. + // When the field is missing or explicitly set to 1.1, the file is treated as a 1.1 file. + const isStatic = moduleJson.module?.abilityStageCodeLanguage === ARKTS_1_2; + if (moduleSrcEntry && !isStatic) { abilityPages.push(moduleSrcEntry); abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, moduleSrcEntry)); - } else if (moduleSrcEntrance) { + } else if (moduleSrcEntrance && !isStatic) { abilityPages.push(moduleSrcEntrance); abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, moduleSrcEntrance)); } @@ -530,10 +531,17 @@ function readAbilityEntrance(moduleJson) { } return abilityPages; } - +/** + * In a mixed compilation project, we only collect entries and abilities for version 1.1. + * When the field is missing or explicitly set to 1.1, the file is treated as a 1.1 file. + */ function setEntrance(abilityConfig, abilityPages) { if (abilityConfig && abilityConfig.length > 0) { abilityConfig.forEach(ability => { + const isStatic = ability.codeLanguage === ARKTS_1_2; + if (isStatic) { + return; + } if (ability.srcEntry) { abilityPages.push(ability.srcEntry); abilityPagesFullPath.add(getAbilityFullPath(projectConfig.projectPath, ability.srcEntry)); diff --git a/compiler/src/fast_build/ark_compiler/error_code.ts b/compiler/src/fast_build/ark_compiler/error_code.ts index 29dd70e20..ec00bd97b 100644 --- a/compiler/src/fast_build/ark_compiler/error_code.ts +++ b/compiler/src/fast_build/ark_compiler/error_code.ts @@ -63,6 +63,7 @@ export enum ErrorCode { ETS2BUNDLE_EXTERNAL_CLASS_HAS_NO_CONSTRUCTOR_WITHOUT_ARGS = '10311012', ETS2BUNDLE_EXTERNAL_UNION_TYPE_AMBIGUITY = '10311013', ETS2BUNDLE_EXTERNAL_ALIAS_CONFIG_FORMAT_INVALID = '10311014', + ETS2BUNDLE_EXTERNAL_GET_LANGUAGE_VERSION_FAILED = '10311015', // CONSTANTS FOR ES2ABC ERROR CODE ES2ABC_SYNTAX_ERROR_ERROR_CODE = '10705000', ES2ABC_PATCH_FIX_ERROR_ERROR_CODE = '10706001' diff --git a/compiler/src/fast_build/ark_compiler/interop/interop_manager.ts b/compiler/src/fast_build/ark_compiler/interop/interop_manager.ts index ca0a6042a..691ec3101 100644 --- a/compiler/src/fast_build/ark_compiler/interop/interop_manager.ts +++ b/compiler/src/fast_build/ark_compiler/interop/interop_manager.ts @@ -26,7 +26,10 @@ import { FileInfo, AliasConfig } from './type'; -import { hasExistingPaths } from '../utils'; +import { + hasExistingPaths, + isSubPathOf +} from '../utils'; import { CommonLogger, LogData, @@ -103,6 +106,8 @@ export class FileManager { const convertedMap = new Map(); for (const [key, module] of dependentModuleMap) { + module.dynamicFiles = module.dynamicFiles?.map(toUnixPath); + module.staticFiles = module.staticFiles?.map(toUnixPath); const convertedModule: ArkTSEvolutionModule = { ...module, modulePath: toUnixPath(module.modulePath), @@ -168,19 +173,17 @@ export class FileManager { staticSDKGlueCodePaths?: Set, checkFileExist: boolean = true ): void { - const isDynamicValid = !dynamicSDKPath || hasExistingPaths(dynamicSDKPath); - const isStaticBaseValid = !staticSDKBaseUrl || hasExistingPaths(staticSDKBaseUrl); - const isGlueCodeValid = !staticSDKGlueCodePaths || hasExistingPaths(staticSDKGlueCodePaths); - FileManager.isInteropSDKEnabled = isDynamicValid && isStaticBaseValid && isGlueCodeValid; - if (!FileManager.isInteropSDKEnabled && checkFileExist) { - return; - } - if (dynamicSDKPath) { for (const path of dynamicSDKPath) { FileManager.dynamicLibPath.add(toUnixPath(path)); } } + const isStaticBaseValid = !staticSDKBaseUrl || hasExistingPaths(staticSDKBaseUrl); + const isGlueCodeValid = !staticSDKGlueCodePaths || hasExistingPaths(staticSDKGlueCodePaths); + FileManager.isInteropSDKEnabled = isStaticBaseValid && isGlueCodeValid; + if (!FileManager.isInteropSDKEnabled && checkFileExist) { + return; + } if (staticSDKBaseUrl) { for (const path of staticSDKBaseUrl) { FileManager.staticSDKDeclPath.add(toUnixPath(path)); @@ -198,11 +201,12 @@ export class FileManager { this.instance = undefined; } - FileManager.arkTSModuleMap.clear(); - FileManager.dynamicLibPath.clear(); - FileManager.staticSDKDeclPath.clear(); - FileManager.staticSDKGlueCodePath.clear(); - FileManager.glueCodeFileInfos.clear(); + FileManager.arkTSModuleMap?.clear(); + FileManager.dynamicLibPath?.clear(); + FileManager.staticSDKDeclPath?.clear(); + FileManager.staticSDKGlueCodePath?.clear(); + FileManager.glueCodeFileInfos?.clear(); + FileManager.aliasConfig?.clear(); FileManager.mixCompile = false; } @@ -221,51 +225,67 @@ export class FileManager { if (sdkMatch) { return sdkMatch; } - - return undefined; + const firstLine = readFirstLineSync(filePath); + if (firstLine.includes('use static')) { + return { + languageVersion: ARKTS_1_2, + pkgName: '' + }; + } + return { + languageVersion: ARKTS_1_1, + pkgName: '' + }; } private static matchModulePath(path: string): { languageVersion: string, pkgName: string } | undefined { - for (const [_, moduleInfo] of FileManager.arkTSModuleMap) { - if (!path.startsWith(moduleInfo.modulePath)) { - continue; + let matchedModuleInfo: ArkTSEvolutionModule; + + for (const [, moduleInfo] of FileManager.arkTSModuleMap) { + if (isSubPathOf(path, moduleInfo.modulePath)) { + matchedModuleInfo = moduleInfo; + break; } + } - const isHybrid = moduleInfo.language === HYBRID; - const pkgName = moduleInfo.packageName; + if (!matchedModuleInfo) { + return undefined; + } - if (!isHybrid) { - return { - languageVersion: moduleInfo.language, - pkgName - }; - } + const isHybrid = matchedModuleInfo.language === HYBRID; + const pkgName = matchedModuleInfo.packageName; + + if (!isHybrid) { + return { + languageVersion: matchedModuleInfo.language, + pkgName + }; + } - const isDynamic = - moduleInfo.dynamicFiles.includes(path) || - (moduleInfo.declgenV2OutPath && path.startsWith(moduleInfo.declgenV2OutPath)); + const isDynamic = + matchedModuleInfo.dynamicFiles.includes(path) || + (matchedModuleInfo.declgenV2OutPath && isSubPathOf(path, matchedModuleInfo.declgenV2OutPath)); - if (isDynamic) { - return { - languageVersion: ARKTS_1_1, - pkgName - }; - } + if (isDynamic) { + return { + languageVersion: ARKTS_1_1, + pkgName + }; + } - const isStatic = - moduleInfo.staticFiles.includes(path) || - (moduleInfo.declgenV1OutPath && path.startsWith(moduleInfo.declgenV1OutPath)) || - (moduleInfo.declgenBridgeCodePath && path.startsWith(moduleInfo.declgenBridgeCodePath)); + const isStatic = + matchedModuleInfo.staticFiles.includes(path) || + (matchedModuleInfo.declgenV1OutPath && isSubPathOf(path, matchedModuleInfo.declgenV1OutPath)) || + (matchedModuleInfo.declgenBridgeCodePath && isSubPathOf(path, matchedModuleInfo.declgenBridgeCodePath)); - if (isStatic) { - return { - languageVersion: ARKTS_1_2, - pkgName - }; - } + if (isStatic) { + return { + languageVersion: ARKTS_1_2, + pkgName + }; } return undefined; @@ -291,7 +311,7 @@ export class FileManager { for (const [paths, version] of sdkMatches) { const isMatch = paths && Array.from(paths).some( - p => p && (path.startsWith(p + '/') || path === p) + p => p && (isSubPathOf(path, p)) ); if (isMatch) { return { languageVersion: version, pkgName: 'SDK' }; @@ -301,6 +321,12 @@ export class FileManager { } queryOriginApiName(moduleName: string, containingFile: string): AliasConfig { + if (!FileManager.mixCompile) { + return undefined; + } + if (!FileManager.isInteropSDKEnabled) { + return undefined; + } const result = this.getLanguageVersionByFilePath(containingFile); if (!result) { return undefined; @@ -331,7 +357,6 @@ export class FileManager { return undefined; } - } export function initFileManagerInRollup(share: Object): void { @@ -352,7 +377,7 @@ export function initFileManagerInRollup(share: Object): void { FileManager.setRollUpObj(share); } -function collectSDKInfo(share: Object): { +export function collectSDKInfo(share: Object): { dynamicSDKPath: Set, staticSDKInteropDecl: Set, staticSDKGlueCodePath: Set @@ -385,6 +410,7 @@ function collectSDKInfo(share: Object): { dynamicSDKPath.add(declarationsPath); dynamicSDKPath.add(componentPath); dynamicSDKPath.add(etsComponentPath); + dynamicSDKPath.add(toUnixPath(share.projectConfig.etsLoaderPath)); sdkConfigs.forEach(({ apiPath }) => { apiPath.forEach(path => { dynamicSDKPath.add(toUnixPath(path)); @@ -395,4 +421,25 @@ function collectSDKInfo(share: Object): { staticSDKInteropDecl: staticSDKInteropDecl, staticSDKGlueCodePath: staticSDKGlueCodePath }; +} + +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; + } + for (const [pkgName, dependentModuleInfo] of projectConfig.dependentModuleMap) { + if (isSubPathOf(filePath, dependentModuleInfo.declgenBridgeCodePath)) { + return true; + } + } + return false; } \ No newline at end of file diff --git a/compiler/src/fast_build/ark_compiler/interop/run_declgen_standalone.ts b/compiler/src/fast_build/ark_compiler/interop/run_declgen_standalone.ts index ee3223223..418b0b5ec 100644 --- a/compiler/src/fast_build/ark_compiler/interop/run_declgen_standalone.ts +++ b/compiler/src/fast_build/ark_compiler/interop/run_declgen_standalone.ts @@ -41,7 +41,7 @@ export function run(param: Params): boolean { DeclfileProductor.init(param); param.tasks.forEach(task => { const moduleInfo = FileManager.arkTSModuleMap.get(task.packageName); - if (moduleInfo.dynamicFileList.length <= 0) { + if (moduleInfo?.dynamicFiles.length <= 0) { return; } if (task.buildTask === BuildType.DECLGEN) { @@ -52,6 +52,7 @@ export function run(param: Params): boolean { //todo } }); + FileManager.cleanFileManagerObject(); return true; } diff --git a/compiler/src/fast_build/ark_compiler/interop/type.ts b/compiler/src/fast_build/ark_compiler/interop/type.ts index 61e90bfde..fdb5abe79 100644 --- a/compiler/src/fast_build/ark_compiler/interop/type.ts +++ b/compiler/src/fast_build/ark_compiler/interop/type.ts @@ -89,21 +89,6 @@ interface DeclFileConfig { declPath: string; ohmUrl: string; } -export interface ArkTSEvolutionModule { - language: string; - packageName: string; - pkgPath: string; - moduleName: string; - modulePath: string; - declgenV1OutPath?: string; - declgenV2OutPath?: string; - declgenBridgeCodePath?: string; - declFilesPath?: string; - dynamicFileList: string[]; - staticFileList: string[]; - cachePath: string; - byteCodeHarInfo?: Object; -} export const ARKTS_1_2: string = '1.2'; export const ARKTS_1_1: string = '1.1'; diff --git a/compiler/src/fast_build/ark_compiler/utils.ts b/compiler/src/fast_build/ark_compiler/utils.ts index 5d60da558..9b2bde4be 100644 --- a/compiler/src/fast_build/ark_compiler/utils.ts +++ b/compiler/src/fast_build/ark_compiler/utils.ts @@ -317,4 +317,10 @@ export function hasExistingPaths(paths: Set): boolean { } } return false; +} + +export function isSubPathOf(targetPath: string, parentDir: string): boolean { + const resolvedParent = toUnixPath(path.resolve(parentDir)); + const resolvedTarget = toUnixPath(path.resolve(targetPath)); + return resolvedTarget === resolvedParent || resolvedTarget.startsWith(resolvedParent + '/'); } \ No newline at end of file diff --git a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts index 3b71ae831..bd886b3fd 100644 --- a/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts +++ b/compiler/src/fast_build/ets_ui/rollup-plugin-ets-checker.ts @@ -50,7 +50,7 @@ import { ErrorCodeModule } from '../../hvigor_error_code/const/error_code_module import { collectArkTSEvolutionModuleInfo } from '../../process_arkts_evolution'; import { initFileManagerInRollup, - FileManager + isBridgeCode } from '../ark_compiler/interop/interop_manager'; export let tsWatchEmitter: EventEmitter | undefined = undefined; @@ -104,7 +104,7 @@ export function etsChecker() { const logger = this.share.getLogger('etsChecker'); const rootFileNames: string[] = []; const resolveModulePaths: string[] = []; - rootFileNamesCollect(rootFileNames); + rootFileNamesCollect(rootFileNames, this.share); if (this.share && this.share.projectConfig && this.share.projectConfig.resolveModulePaths && Array.isArray(this.share.projectConfig.resolveModulePaths)) { resolveModulePaths.push(...this.share.projectConfig.resolveModulePaths); @@ -158,9 +158,21 @@ function getErrorCodeLogger(code: string, share: Object): Object | undefined { return !!share?.getHvigorConsoleLogger ? share?.getHvigorConsoleLogger(code) : undefined; } -function rootFileNamesCollect(rootFileNames: string[]): void { +/** + * In mixed compilation scenarios, + * hvigor is prevented from stuffing glue code into the code and causing TSC parsing failed. + * + * case: + * 1.2 File Relative Path Reference 1.1 File + * The 1.2 file is under the glue code path, and the 1.1 file cannot be found in the relative path + * In fact, dependency resolution requires interop decl file + */ +function rootFileNamesCollect(rootFileNames: string[], sharedObj: Object): void { const entryFiles: string[] = projectConfig.widgetCompile ? Object.values(projectConfig.cardEntryObj) : Object.values(projectConfig.entryObj); entryFiles.forEach((fileName: string) => { + if (isBridgeCode(fileName, sharedObj?.projectConfig)) { + return; + } rootFileNames.push(path.resolve(fileName)); }); } \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/common/utils.test.ts b/compiler/test/ark_compiler_ut/common/utils.test.ts index 609e53185..d9dccd562 100644 --- a/compiler/test/ark_compiler_ut/common/utils.test.ts +++ b/compiler/test/ark_compiler_ut/common/utils.test.ts @@ -36,7 +36,8 @@ import { updateSourceMap, hasTsNoCheckOrTsIgnoreFiles, compilingEtsOrTsFiles, - cleanUpFilesList + cleanUpFilesList, + isSubPathOf, } from '../../../lib/fast_build/ark_compiler/utils'; import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock'; import { ModuleInfo } from '../mock/rollup_mock/module_info'; @@ -1382,4 +1383,52 @@ mocha.describe('test utils file api', function () { expect(belongModuleInfo[item] === expectBelongModuleInfo[item]).to.be.true; }); }); + + mocha.it('19-1: test isSubPathOf Api with includePath', function () { + const parentDir = 'a/b/c/d'; + const filePath = 'a/b/c/d/e'; + expect(isSubPathOf(filePath, parentDir)).to.be.true; + }) + + mocha.it('19-2: test isSubPathOf Api with same prefix', function () { + const parentDir = 'a/b/c/d'; + const filePath = 'a/b/c/ddd/e'; + expect(isSubPathOf(filePath, parentDir)).to.be.false; + }) + + mocha.it('19-4: test isSubPathOf with unrelated path', function () { + const parentDir = 'x/y/z'; + const filePath = 'a/b/c'; + expect(isSubPathOf(filePath, parentDir)).to.be.false; + }); + + mocha.it('19-5: test isSubPathOf with exact match', function () { + const parentDir = 'a/b/c'; + const filePath = 'a/b/c'; + expect(isSubPathOf(filePath, parentDir)).to.be.true; + }); + + mocha.it('19-6: test isSubPathOf with dot segments in path', function () { + const parentDir = 'a/b/c'; + const filePath = 'a/b/c/../c/d/e'; + expect(isSubPathOf(filePath, parentDir)).to.be.true; + }); + + mocha.it('19-7: test isSubPathOf with similar prefix but not subdir', function () { + const parentDir = 'a/b/c'; + const filePath = 'a/b/cd/e'; + expect(isSubPathOf(filePath, parentDir)).to.be.false; + }); + + mocha.it('19-8: test isSubPathOf with relative "./" segments', function () { + const parentDir = './src'; + const filePath = './src/utils/helpers.ts'; + expect(isSubPathOf(filePath, parentDir)).to.be.true; + }); + + mocha.it('19-9: test isSubPathOf where filePath is parent of parentDir', function () { + const parentDir = 'a/b/c/d'; + const filePath = 'a/b'; + expect(isSubPathOf(filePath, parentDir)).to.be.false; + }); }); \ No newline at end of file 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 8c3096ecb..179df238b 100644 --- a/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts +++ b/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts @@ -15,7 +15,13 @@ import { expect } from 'chai'; import mocha from 'mocha'; -import { FileManager } from '../../../lib/fast_build/ark_compiler/interop/interop_manager'; +import path from "path"; + +import { + FileManager, + collectSDKInfo, + isBridgeCode + } from '../../../lib/fast_build/ark_compiler/interop/interop_manager'; import { ARKTS_1_1, ARKTS_1_2, HYBRID } from '../../../lib/fast_build/ark_compiler/interop/type'; export interface ArkTSEvolutionModule { @@ -123,12 +129,12 @@ mocha.describe('test interop_manager file api', function () { }); mocha.after(() => { + FileManager.cleanFileManagerObject(); }); mocha.it('1-1: test SDK path', function() { const filePath = '/sdk/default/openharmony/ets/ets1.1/api/TestAPI.ets'; const result = FileManager.getInstance().getLanguageVersionByFilePath(filePath); - console.log('222222',FileManager) expect(result?.languageVersion).to.equal(ARKTS_1_1); expect(result?.pkgName).to.equal('SDK'); }); @@ -182,17 +188,123 @@ mocha.describe('test interop_manager file api', function () { expect(result?.pkgName).to.equal('harv2'); }); - mocha.it('1-8: test source code file from hybrid module', function() { + mocha.it('1-9: test source code file from hybrid module', function() { const filePath = '/MyApplication16/hybrid/fileV1.ets'; const result = FileManager.getInstance().getLanguageVersionByFilePath(filePath); expect(result?.languageVersion).to.equal(ARKTS_1_1); expect(result?.pkgName).to.equal('hybrid'); }); - mocha.it('1-8: test source code file from hybrid module', function() { + mocha.it('1-10: test source code file from hybrid module', function() { const filePath = '/MyApplication16/hybrid/build/default/intermediates/declgen/default/declgenV1/file1'; const result = FileManager.getInstance().getLanguageVersionByFilePath(filePath); expect(result?.languageVersion).to.equal(ARKTS_1_2); expect(result?.pkgName).to.equal('hybrid'); }); + + mocha.it('2-1: test matchModulePath api with 1.1 module', function() { + const filePath = '/MyApplication16/dynamic1/sourceCode.ets'; + const moduleInfo = FileManager.matchModulePath(filePath); + expect(moduleInfo.languageVersion).to.equal(ARKTS_1_1); + expect(moduleInfo.pkgName).to.equal('dynamic1'); + }) + + mocha.it('2-2: test matchModulePath api with 1.2 module', function() { + const filePath = '/MyApplication16/harv2/sourceCode.ets'; + const moduleInfo = FileManager.matchModulePath(filePath); + expect(moduleInfo.languageVersion).to.equal(ARKTS_1_2); + expect(moduleInfo.pkgName).to.equal('harv2'); + }) + + mocha.it('2-3: test matchModulePath api with isHybrid module', function() { + const dymanicFilePath = '/MyApplication16/hybrid/fileV1.ets'; + const staticFilePath = '/MyApplication16/hybrid/fileV2.ets'; + + const moduleInfoV1 = FileManager.matchModulePath(dymanicFilePath); + expect(moduleInfoV1.languageVersion).to.equal(ARKTS_1_1); + expect(moduleInfoV1.pkgName).to.equal('hybrid'); + + const moduleInfoV2 = FileManager.matchModulePath(staticFilePath); + expect(moduleInfoV2.languageVersion).to.equal(ARKTS_1_2); + expect(moduleInfoV2.pkgName).to.equal('hybrid'); + }) + + mocha.it('3-1: test init SDK', function () { + const share = { + projectConfig: { + etsLoaderPath: '/mock/ets-loader', + } + }; + + const result = collectSDKInfo(share); + const expectedDynamicSDKPath = new Set([ + '/mock/ets-loader/declarations', + '/mock/ets-loader/components', + '/component', + '/mock/ets-loader', + '/mnt/data/z00893105/dev/developtools/api', + '/mnt/data/z00893105/dev/developtools/arkts', + '/mnt/data/z00893105/dev/developtools/kits' + ]); + + const expectedStaticInteropDecl = new Set([ + '/ets1.2/build-tools/interop/declarations/kits', + '/ets1.2/build-tools/interop/declarations/api', + '/ets1.2/build-tools/interop/declarations/arkts' + ]); + + const expectedStaticGlueCode = new Set([ + '/ets1.2/build-tools/interop/bridge/kits', + '/ets1.2/build-tools/interop/bridge/api', + '/ets1.2/build-tools/interop/bridge/arkts' + ]); + + expect([...result.dynamicSDKPath]).to.have.deep.members([...expectedDynamicSDKPath]); + expect([...result.staticSDKInteropDecl]).to.have.deep.members([...expectedStaticInteropDecl]); + expect([...result.staticSDKGlueCodePath]).to.have.deep.members([...expectedStaticGlueCode]); + }); +}); + +mocha.describe('isBridgeCode', function () { + const mockConfig = { + mixCompile: true, + dependentModuleMap: new Map([ + ['pkgA', { declgenBridgeCodePath: path.resolve('project/bridge/pkgA') }], + ['pkgB', { declgenBridgeCodePath: path.resolve('project/bridge/pkgB') }], + ]), + }; + + mocha.it('20-1: should return true when filePath is inside a declgenBridgeCodePath', function () { + const filePath = path.resolve('project/bridge/pkgA/utils/helper.ts'); + expect(isBridgeCode(filePath, mockConfig)).to.be.true; + }); + + mocha.it('20-2: should return false when filePath is outside all bridge code paths', function () { + const filePath = path.resolve('project/otherpkg/index.ts'); + expect(isBridgeCode(filePath, mockConfig)).to.be.false; + }); + + mocha.it('20-3: should return false when mixCompile is false', function () { + const config = { ...mockConfig, mixCompile: false }; + const filePath = path.resolve('project/bridge/pkgA/utils/helper.ts'); + expect(isBridgeCode(filePath, config)).to.be.false; + }); + + mocha.it('20-4: should return false when dependentModuleMap is empty', function () { + const config = { mixCompile: true, dependentModuleMap: new Map() }; + const filePath = path.resolve('project/bridge/pkgA/file.ts'); + expect(isBridgeCode(filePath, config)).to.be.false; + }); + + mocha.it('20-5: should return true for multiple matches, stop at first match', function () { + const config = { + mixCompile: true, + dependentModuleMap: new Map([ + ['pkg1', { declgenBridgeCodePath: path.resolve('path/one') }], + ['pkg2', { declgenBridgeCodePath: path.resolve('path/two') }], + ]), + }; + const filePath = path.resolve('path/one/module.ts'); + expect(isBridgeCode(filePath, config)).to.be.true; + }); }); \ No newline at end of file -- Gitee