diff --git a/compiler/src/ets_checker.ts b/compiler/src/ets_checker.ts index 3e3ed92b29e113a3f5d6b0219b527c17d6b5b59b..cb870e2dadea966cf01826f0f3dfd45d675dc938 100644 --- a/compiler/src/ets_checker.ts +++ b/compiler/src/ets_checker.ts @@ -34,6 +34,7 @@ import { preprocessNewExtend } from './validate_ui_syntax'; import { + ARKTS_1_1, INNER_COMPONENT_MEMBER_DECORATORS, COMPONENT_DECORATORS_PARAMS, COMPONENT_BUILD_FUNCTION, @@ -1073,6 +1074,7 @@ export function resolveTypeReferenceDirectives(typeDirectiveNames: string[] | ts export const resolvedModulesCache: Map = new Map(); export function resolveModuleNames(moduleNames: string[], containingFile: string): ts.ResolvedModuleFull[] { + const languageVersion = FileManager.mixCompile ? FileManager.getInstance().getLanguageVersionByFilePath(containingFile).languageVersion : ARKTS_1_1; startTimeStatisticsLocation(resolveModuleNamesTime); const resolvedModules: ts.ResolvedModuleFull[] = []; const cacheFileContent: ts.ResolvedModuleFull[] = resolvedModulesCache.get(path.resolve(containingFile)); @@ -1095,7 +1097,7 @@ export function resolveModuleNames(moduleNames: string[], containingFile: string // When result has a value and the path parsed is the source code file path of module 1.2, // the parsing result needs to be modified to the glue code path of module 1.2 let arktsEvoDeclFilePathExist: boolean = false; - const resolvedFileName: string = toUnixPath(result.resolvedModule.resolvedFileName); + const resolvedFileName: string = toUnixPath(result.resolvedModule.resolvedFileName); const resultDETSPath: string = getArkTSEvoDeclFilePath({ moduleRequest: '', resolvedFileName }); if (ts.sys.fileExists(resultDETSPath)) { resolvedModules.push(getResolveModule(resultDETSPath, EXTNAME_D_ETS)); @@ -1108,19 +1110,19 @@ export function resolveModuleNames(moduleNames: string[], containingFile: string resolvedModules.push(result.resolvedModule); } } else if (new RegExp(`^@(${sdkConfigPrefix})\\.`, 'i').test(moduleName.trim())) { - let apiFileExist: boolean = false; - for (let i = 0; i < sdkConfigs.length; i++) { - const sdkConfig = sdkConfigs[i]; - const resolveModuleInfo: ResolveModuleInfo = getRealModulePath(sdkConfig.apiPath, moduleName, ['.d.ts', '.d.ets']); - const modulePath: string = resolveModuleInfo.modulePath; - const isDETS: boolean = resolveModuleInfo.isEts; - if (systemModules.includes(moduleName + (isDETS ? '.d.ets' : '.d.ts')) && ts.sys.fileExists(modulePath)) { - resolvedModules.push(getResolveModule(modulePath, isDETS ? '.d.ets' : '.d.ts')); - apiFileExist = true; - break; - } - } - if (!apiFileExist) { + const searchPaths = languageVersion && languageVersion === ARKTS_1_2 + ? Array.from(FileManager.staticSDKDeclPath) + : [...new Set(sdkConfigs.flatMap(config => config.apiPath))]; + const resolveModuleInfo = getRealModulePath(searchPaths, moduleName, ['.d.ts', '.d.ets']); + const modulePath = resolveModuleInfo.modulePath; + const extension = resolveModuleInfo.isEts ? '.d.ets' : '.d.ts'; + const fullModuleName = moduleName + extension; + + if (systemModules.includes(fullModuleName) && ts.sys.fileExists(modulePath)) { + resolvedModules.push(getResolveModule(modulePath, extension)); + } else if (languageVersion === ARKTS_1_2) { + resolvedModules.push(getResolveModule(modulePath, extension)); + } else { resolvedModules.push(null); } } else if (/\.ets$/.test(moduleName) && !/\.d\.ets$/.test(moduleName)) { @@ -1138,46 +1140,57 @@ export function resolveModuleNames(moduleNames: string[], containingFile: string resolvedModules.push(null); } } else { - const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts'); - const systemDETSModulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ets'); - const kitModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ts'); - const kitSystemDETSModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ets'); - const suffix: string = /\.js$/.test(moduleName) ? '' : '.js'; - const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix); - const fileModulePath: string = - path.resolve(__dirname, '../node_modules', moduleName + '/index.js'); - const DETSModulePath: string = path.resolve(path.dirname(containingFile), - /\.d\.ets$/.test(moduleName) ? moduleName : moduleName + EXTNAME_D_ETS); - const arktsEvoDeclFilePath: string = getArkTSEvoDeclFilePath({ moduleRequest: moduleName, resolvedFileName: '' }); - if (ts.sys.fileExists(modulePath)) { - resolvedModules.push(getResolveModule(modulePath, '.d.ts')); - } else if (ts.sys.fileExists(systemDETSModulePath)) { - resolvedModules.push(getResolveModule(systemDETSModulePath, '.d.ets')); - } else if (ts.sys.fileExists(kitModulePath)) { - resolvedModules.push(getResolveModule(kitModulePath, '.d.ts')); - } else if (ts.sys.fileExists(kitSystemDETSModulePath)) { - resolvedModules.push(getResolveModule(kitSystemDETSModulePath, '.d.ets')); - } else if (ts.sys.fileExists(jsModulePath)) { - resolvedModules.push(getResolveModule(jsModulePath, '.js')); - } else if (ts.sys.fileExists(fileModulePath)) { - resolvedModules.push(getResolveModule(fileModulePath, '.js')); - } else if (ts.sys.fileExists(DETSModulePath)) { - resolvedModules.push(getResolveModule(DETSModulePath, '.d.ets')); - } else if (ts.sys.fileExists(arktsEvoDeclFilePath)) { - resolvedModules.push(getResolveModule(arktsEvoDeclFilePath, '.d.ets')); + const aliasConfig = FileManager.getInstance().queryOriginApiName(moduleName, containingFile); + if (aliasConfig) { + const searchPaths = aliasConfig.isStatic + ? Array.from(FileManager.staticSDKDeclPath) + : [...new Set(sdkConfigs.flatMap(config => config.apiPath))]; + const resolveModuleInfo = getRealModulePath(searchPaths, aliasConfig.originalAPIName, ['.d.ts', '.d.ets']); + const modulePath = resolveModuleInfo.modulePath; + const extension = resolveModuleInfo.isEts ? '.d.ets' : '.d.ts'; + resolvedModules.push(getResolveModule(modulePath, extension)); } else { - const srcIndex: number = projectConfig.projectPath.indexOf('src' + path.sep + 'main'); - let DETSModulePathFromModule: string; - if (srcIndex > 0) { - DETSModulePathFromModule = path.resolve( - projectConfig.projectPath.substring(0, srcIndex), moduleName + path.sep + 'index' + EXTNAME_D_ETS); - if (DETSModulePathFromModule && ts.sys.fileExists(DETSModulePathFromModule)) { - resolvedModules.push(getResolveModule(DETSModulePathFromModule, '.d.ets')); + const modulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ts'); + const systemDETSModulePath: string = path.resolve(__dirname, '../../../api', moduleName + '.d.ets'); + const kitModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ts'); + const kitSystemDETSModulePath: string = path.resolve(__dirname, '../../../kits', moduleName + '.d.ets'); + const suffix: string = /\.js$/.test(moduleName) ? '' : '.js'; + const jsModulePath: string = path.resolve(__dirname, '../node_modules', moduleName + suffix); + const fileModulePath: string = + path.resolve(__dirname, '../node_modules', moduleName + '/index.js'); + const DETSModulePath: string = path.resolve(path.dirname(containingFile), + /\.d\.ets$/.test(moduleName) ? moduleName : moduleName + EXTNAME_D_ETS); + const arktsEvoDeclFilePath: string = getArkTSEvoDeclFilePath({ moduleRequest: moduleName, resolvedFileName: '' }); + if (ts.sys.fileExists(modulePath)) { + resolvedModules.push(getResolveModule(modulePath, '.d.ts')); + } else if (ts.sys.fileExists(systemDETSModulePath)) { + resolvedModules.push(getResolveModule(systemDETSModulePath, '.d.ets')); + } else if (ts.sys.fileExists(kitModulePath)) { + resolvedModules.push(getResolveModule(kitModulePath, '.d.ts')); + } else if (ts.sys.fileExists(kitSystemDETSModulePath)) { + resolvedModules.push(getResolveModule(kitSystemDETSModulePath, '.d.ets')); + } else if (ts.sys.fileExists(jsModulePath)) { + resolvedModules.push(getResolveModule(jsModulePath, '.js')); + } else if (ts.sys.fileExists(fileModulePath)) { + resolvedModules.push(getResolveModule(fileModulePath, '.js')); + } else if (ts.sys.fileExists(DETSModulePath)) { + resolvedModules.push(getResolveModule(DETSModulePath, '.d.ets')); + } else if (ts.sys.fileExists(arktsEvoDeclFilePath)) { + resolvedModules.push(getResolveModule(arktsEvoDeclFilePath, '.d.ets')); + } else { + const srcIndex: number = projectConfig.projectPath.indexOf('src' + path.sep + 'main'); + let DETSModulePathFromModule: string; + if (srcIndex > 0) { + DETSModulePathFromModule = path.resolve( + projectConfig.projectPath.substring(0, srcIndex), moduleName + path.sep + 'index' + EXTNAME_D_ETS); + if (DETSModulePathFromModule && ts.sys.fileExists(DETSModulePathFromModule)) { + resolvedModules.push(getResolveModule(DETSModulePathFromModule, '.d.ets')); + } else { + resolvedModules.push(null); + } } else { resolvedModules.push(null); } - } else { - resolvedModules.push(null); } } } @@ -1195,6 +1208,7 @@ export function resolveModuleNames(moduleNames: string[], containingFile: string resolvedModulesCache.set(path.resolve(containingFile), resolvedModules); stopTimeStatisticsLocation(resolveModuleNamesTime); return resolvedModules; + } stopTimeStatisticsLocation(resolveModuleNamesTime); return resolvedModulesCache.get(path.resolve(containingFile)); diff --git a/compiler/src/fast_build/ark_compiler/error_code.ts b/compiler/src/fast_build/ark_compiler/error_code.ts index 80352dbed8ddfbee740425048d5e6ffc238f649a..29dd70e204e9b8815676898c102a0936a11f6a5c 100644 --- a/compiler/src/fast_build/ark_compiler/error_code.ts +++ b/compiler/src/fast_build/ark_compiler/error_code.ts @@ -45,6 +45,7 @@ export enum ErrorCode { ETS2BUNDLE_INTERNAL_SOURCE_CODE_OBFUSCATION_FAILED = '10310020', ETS2BUNDLE_INTERNAL_ES2ABC_SUBPROCESS_START_FAILED = '10310021', ETS2BUNDLE_INTERNAL_EXECUTE_ES2ABC_WITH_ASYNC_HANDLER_FAILED = '10310022', + ETS2BUNDLE_INTERNAL_FAILED_TO_FIND_GLUD_CODE = '10310023', // EXTERNAL ERRORS ETS2BUNDLE_EXTERNAL_FORBIDDEN_IMPORT_ARKTS_FILE = '10311001', @@ -61,7 +62,7 @@ export enum ErrorCode { // INTEROPTRANSFORMER ERROR CODE ETS2BUNDLE_EXTERNAL_CLASS_HAS_NO_CONSTRUCTOR_WITHOUT_ARGS = '10311012', ETS2BUNDLE_EXTERNAL_UNION_TYPE_AMBIGUITY = '10311013', - + ETS2BUNDLE_EXTERNAL_ALIAS_CONFIG_FORMAT_INVALID = '10311014', // 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 3ea51946e4eb6c587bd8eb5755dd2de587b29727..ca0a6042aa50195e82fc7c57f3a6935a9213cba0 100644 --- a/compiler/src/fast_build/ark_compiler/interop/interop_manager.ts +++ b/compiler/src/fast_build/ark_compiler/interop/interop_manager.ts @@ -15,7 +15,6 @@ import fs from 'fs'; import path from 'path'; -import * as ts from 'typescript'; import { sdkConfigs } from '../../../../main'; import { toUnixPath } from '../../../utils'; @@ -24,23 +23,38 @@ import { ArkTSEvolutionModule, ARKTS_1_2, HYBRID, - FileInfo + FileInfo, + AliasConfig } from './type'; +import { hasExistingPaths } from '../utils'; +import { + CommonLogger, + LogData, + LogDataFactory +} from '../logger'; +import { + ArkTSErrorDescription, + ErrorCode +} from '../error_code'; export class FileManager { private static instance: FileManager | undefined = undefined; static arkTSModuleMap: Map = new Map(); + static aliasConfig: Map> = new Map(); static dynamicLibPath: Set = new Set(); static staticSDKDeclPath: Set = new Set(); static staticSDKGlueCodePath: Set = new Set(); static mixCompile: boolean = false; static glueCodeFileInfos: Map = new Map(); + static isInteropSDKEnabled: boolean = false; + static sharedObj: Object | undefined = undefined; private constructor() { } public static init( dependentModuleMap: Map, + aliasPaths?: Map, dynamicSDKPath?: Set, staticSDKDeclPath?: Set, staticSDKGlueCodePath?: Set @@ -48,10 +62,26 @@ export class FileManager { if (FileManager.instance === undefined) { FileManager.instance = new FileManager(); FileManager.initLanguageVersionFromDependentModuleMap(dependentModuleMap); + FileManager.initAliasConfig(aliasPaths); FileManager.initSDK(dynamicSDKPath, staticSDKDeclPath, staticSDKGlueCodePath); } } + public static initForTest( + dependentModuleMap: Map, + aliasPaths: Map, + dynamicSDKPath?: Set, + staticSDKDeclPath?: Set, + staticSDKGlueCodePath?: Set + ): void { + if (FileManager.instance === undefined) { + FileManager.instance = new FileManager(); + FileManager.initLanguageVersionFromDependentModuleMap(dependentModuleMap); + FileManager.initAliasConfig(aliasPaths); + FileManager.initSDK(dynamicSDKPath, staticSDKDeclPath, staticSDKGlueCodePath, false); + } + } + public static getInstance(): FileManager { if (!FileManager.instance) { FileManager.instance = new FileManager(); @@ -59,6 +89,14 @@ export class FileManager { return FileManager.instance; } + public static setRollUpObj(shared: Object): void { + FileManager.sharedObj = shared; + } + + public static setMixCompile(mixCompile: boolean): void { + FileManager.mixCompile = mixCompile; + } + private static initLanguageVersionFromDependentModuleMap( dependentModuleMap: Map ): void { @@ -79,11 +117,65 @@ export class FileManager { this.arkTSModuleMap = convertedMap; } + private static initAliasConfig(aliasPaths: Map): void { + if (!aliasPaths) { + return; + } + + for (const [pkgName, filePath] of aliasPaths) { + const rawContent = fs.readFileSync(filePath, 'utf-8'); + const jsonData = JSON.parse(rawContent); + const pkgAliasMap = this.parseAliasJson(pkgName, jsonData); + this.aliasConfig.set(pkgName, pkgAliasMap); + } + } + + private static parseAliasJson(pkgName: string, jsonData: any): Map { + const map = new Map(); + + for (const [aliasKey, config] of Object.entries(jsonData)) { + if (!this.isValidAliasConfig(config)) { + const errInfo: LogData = LogDataFactory.newInstance( + ErrorCode.ETS2BUNDLE_EXTERNAL_ALIAS_CONFIG_FORMAT_INVALID, + ArkTSErrorDescription, + 'Invalid alias config format detected.', + `Package: ${pkgName}`, + ['Please ensure each alias entry contains "originalAPIName" and "isStatic" fields.'] + ); + + FileManager.logError(errInfo); + } + + map.set(aliasKey, { + originalAPIName: config.originalAPIName, + isStatic: config.isStatic + }); + } + + return map; + } + + private static isValidAliasConfig(config: any): config is AliasConfig { + return typeof config === 'object' && + config !== null && + 'originalAPIName' in config && + 'isStatic' in config; + } + private static initSDK( dynamicSDKPath?: Set, staticSDKBaseUrl?: Set, - staticSDKGlueCodePaths?: Set + 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)); @@ -179,6 +271,14 @@ export class FileManager { return undefined; } + private static logError(error: LogData): void { + if (FileManager.sharedObj) { + CommonLogger.getInstance(FileManager.sharedObj).printErrorAndExit(error); + } else { + console.error(error.toString()); + } + } + private static matchSDKPath(path: string): { languageVersion: string, pkgName: string @@ -199,6 +299,39 @@ export class FileManager { } return undefined; } + + queryOriginApiName(moduleName: string, containingFile: string): AliasConfig { + const result = this.getLanguageVersionByFilePath(containingFile); + if (!result) { + return undefined; + } + + const alias = FileManager.aliasConfig.get(result.pkgName); + if (!alias) { + return undefined; + } + + return alias.get(moduleName); + } + + getGlueCodePathByModuleRequest(moduleRequest: string): { fullPath: string, basePath: string } | undefined { + const extensions = ['.ts', '.ets']; + for (const basePath of FileManager.staticSDKGlueCodePath) { + const fullPath = extensions + .map(ext => path.resolve(basePath, moduleRequest + ext)) + .find(fs.existsSync); + + if (fullPath) { + return { + fullPath: toUnixPath(fullPath), + basePath: toUnixPath(basePath) + }; + } + } + + return undefined; + } + } export function initFileManagerInRollup(share: Object): void { @@ -211,10 +344,12 @@ export function initFileManagerInRollup(share: Object): void { FileManager.init( share.projectConfig.dependentModuleMap, + share.projectConfig.aliasPaths, sdkInfo.dynamicSDKPath, sdkInfo.staticSDKInteropDecl, sdkInfo.staticSDKGlueCodePath ); + FileManager.setRollUpObj(share); } function collectSDKInfo(share: Object): { @@ -223,17 +358,18 @@ function collectSDKInfo(share: Object): { staticSDKGlueCodePath: Set } { const dynamicSDKPath: Set = new Set(); - + const staticInteroSDKBasePath = process.env.staticInteroSDKBasePath || + path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2/build-tools/interop'); const staticSDKInteropDecl: Set = new Set([ - path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2interop/declarations/kit'), - path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2interop/declarations/api'), - path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2interop/declarations/arkts'), + path.resolve(staticInteroSDKBasePath, './declarations/kits'), + path.resolve(staticInteroSDKBasePath, './declarations/api'), + path.resolve(staticInteroSDKBasePath, './declarations/arkts'), ].map(toUnixPath)); const staticSDKGlueCodePath: Set = new Set([ - path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2interop/bridge/kit'), - path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2interop/bridge/api'), - path.resolve(share.projectConfig.etsLoaderPath, '../../../ets1.2interop/bridge/arkts'), + path.resolve(staticInteroSDKBasePath, './bridge/kits'), + path.resolve(staticInteroSDKBasePath, './bridge/api'), + path.resolve(staticInteroSDKBasePath, './bridge/arkts'), ].map(toUnixPath)); const declarationsPath: string = path.resolve(share.projectConfig.etsLoaderPath, './declarations').replace(/\\/g, '/'); @@ -242,8 +378,8 @@ function collectSDKInfo(share: Object): { if (process.env.externalApiPaths) { const externalApiPaths = path.resolve(process.env.externalApiPaths, '../'); - staticSDKGlueCodePath.add(path.resolve(externalApiPaths, 'ets1.2interop/bridge')); - staticSDKInteropDecl.add(path.resolve(externalApiPaths, 'ets1.2interop/declarations')); + staticSDKGlueCodePath.add(path.resolve(externalApiPaths, './ets1.2/interop/bridge')); + staticSDKInteropDecl.add(path.resolve(externalApiPaths, './ets1.2/interop/declarations')); } dynamicSDKPath.add(declarationsPath); 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 cf724c889e00ad255cba56c78cc2c4466004bf39..ee322322314caf8a5873f1f124c20aa39280a5b1 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,6 +41,9 @@ 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) { + return; + } if (task.buildTask === BuildType.DECLGEN) { DeclfileProductor.getInstance().runDeclgen(moduleInfo); } else if (task.buildTask === BuildType.INTEROP_CONTEXT) { diff --git a/compiler/src/fast_build/ark_compiler/interop/type.ts b/compiler/src/fast_build/ark_compiler/interop/type.ts index 132f76602b588bc41b9835f177bcdcffadc5d986..61e90bfde6bf50ac43736e01d5d2dd101cfcca34 100644 --- a/compiler/src/fast_build/ark_compiler/interop/type.ts +++ b/compiler/src/fast_build/ark_compiler/interop/type.ts @@ -31,11 +31,6 @@ export interface ArkTSEvolutionModule { packageVersion: string; } -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 HYBRID: string = 'hybrid'; - export interface Params { dependentModuleMap: Map; projectConfig: ProjectConfig; @@ -93,4 +88,46 @@ export interface DeclFilesConfig { 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'; +export const ARKTS_1_0: string = '1.0'; +export const HYBRID: string = 'hybrid'; + +export interface Params { + dependentModuleMap: Map; + projectConfig: ProjectConfig; + tasks: taskInfo[]; +} + +interface taskInfo { + packageName: string; + buildTask: BuildType +} + +export interface AliasConfig { + originalAPIName: string; + isStatic: boolean; +} + +export interface FileInfo { + recordName: string; + baseUrl: string; + abstractPath: string; } \ No newline at end of file diff --git a/compiler/src/fast_build/ark_compiler/module/module_mode.ts b/compiler/src/fast_build/ark_compiler/module/module_mode.ts index 562661f77d5c9b6688f935e9a383b65893a74843..65dfc168b37d20f5b454905c15f38ef5a79bc1f6 100644 --- a/compiler/src/fast_build/ark_compiler/module/module_mode.ts +++ b/compiler/src/fast_build/ark_compiler/module/module_mode.ts @@ -126,6 +126,7 @@ import { arkTSModuleMap, isArkTSEvolutionFile } from '../../../process_arkts_evolution'; +import { FileManager } from '../interop/interop_manager'; export class ModuleInfo { filePath: string; @@ -641,6 +642,10 @@ export class ModuleMode extends CommonMode { }); } + for (const [pkgName, fileInfo] of FileManager.glueCodeFileInfos) { + filesInfo += `${fileInfo.abstractPath};${fileInfo.recordName};${ESM};${fileInfo.abstractPath};${this.projectConfig.entryPackageName};` + + `${false};ts\n`; + } fs.writeFileSync(this.filesInfoPath, filesInfo, 'utf-8'); } diff --git a/compiler/src/fast_build/ark_compiler/module/module_source_file.ts b/compiler/src/fast_build/ark_compiler/module/module_source_file.ts index 8d9771f04ff5069876d8ea145b2af173c48d5da4..a0ff56a11cc0321b80be033e9050b144e9314af1 100644 --- a/compiler/src/fast_build/ark_compiler/module/module_source_file.ts +++ b/compiler/src/fast_build/ark_compiler/module/module_source_file.ts @@ -85,6 +85,8 @@ import { writeBridgeCodeFileSyncByNode, isArkTSEvolutionFile } from '../../../process_arkts_evolution'; +import { FileManager } from '../interop/interop_manager'; +import { FileInfo } from '../interop/type'; const ROLLUP_IMPORT_NODE: string = 'ImportDeclaration'; const ROLLUP_EXPORTNAME_NODE: string = 'ExportNamedDeclaration'; @@ -442,7 +444,18 @@ export class ModuleSourceFile { if (!!rollupObject.share.projectConfig.useNormalizedOHMUrl) { useNormalizedOHMUrl = rollupObject.share.projectConfig.useNormalizedOHMUrl; } - let systemOrLibOhmUrl = getOhmUrlBySystemApiOrLibRequest(moduleRequest, ModuleSourceFile.projectConfig, + let queryResult = undefined; + let staticOhmUrl: string | undefined = undefined; + + if (rollupObject.share.projectConfig.mixCompile) { + queryResult = FileManager.getInstance().queryOriginApiName(moduleRequest, this.moduleId); + staticOhmUrl = this.tryBuildStaticOhmUrl(queryResult, moduleRequest); + } + if (staticOhmUrl) { + return staticOhmUrl; + } + const api = (queryResult && !queryResult.isStatic) ? queryResult.originalAPIName : moduleRequest; + let systemOrLibOhmUrl = getOhmUrlBySystemApiOrLibRequest(api, ModuleSourceFile.projectConfig, ModuleSourceFile.logger, importerFile, useNormalizedOHMUrl); if (systemOrLibOhmUrl !== undefined) { if (ModuleSourceFile.needProcessMock) { @@ -500,8 +513,8 @@ export class ModuleSourceFile { ModuleSourceFile.generateNewMockInfo(moduleRequest, res, rollupObject, importerFile); // processing cases of user-defined mock targets let mockedTarget: string = toUnixPath(filePath). - replace(toUnixPath(rollupObject.share.projectConfig.modulePath), ''). - replace(`/${rollupObject.share.projectConfig.mockParams.etsSourceRootPath}/`, ''); + replace(toUnixPath(rollupObject.share.projectConfig.modulePath), ''). + replace(`/${rollupObject.share.projectConfig.mockParams.etsSourceRootPath}/`, ''); ModuleSourceFile.generateNewMockInfo(mockedTarget, res, rollupObject, importerFile); } return res; @@ -509,6 +522,13 @@ export class ModuleSourceFile { return undefined; } + private static generateNormalizedOhmulrForSDkInterop(project: Object, projectFilePath: string): string { + const packageName = project.entryPackageName; + const bundleName = project.pkgContextInfo[packageName].bundleName; + const version = project.pkgContextInfo[packageName].version; + return `${bundleName}&${packageName}/${projectFilePath}&${version}`; + } + private static spliceNormalizedOhmurl(moduleInfo: Object, filePath: string, importerFile?: string): string { const isArkTSEvolution: boolean = isArkTSEvolutionFile(filePath, moduleInfo.meta); const pkgPath: string = isArkTSEvolution ? @@ -704,6 +724,40 @@ export class ModuleSourceFile { ModuleSourceFile.sourceFiles.sort((a, b) => a.moduleId.localeCompare(b.moduleId)); } + private tryBuildStaticOhmUrl(queryResult: any, moduleRequest: string): string | undefined { + if (!queryResult || !queryResult.isStatic) { + return undefined; + } + + const { originalAPIName } = queryResult; + const recordName = ModuleSourceFile.generateNormalizedOhmulrForSDkInterop( + ModuleSourceFile.projectConfig, + originalAPIName + ); + const moduleName = ModuleSourceFile.projectConfig. + pkgContextInfo[ModuleSourceFile.projectConfig.entryPackageName].moduleName; + const ohmUrl = `N&${moduleName}&${recordName}`; + const glueCodeInfo = FileManager.getInstance().getGlueCodePathByModuleRequest(originalAPIName); + + if (!glueCodeInfo) { + const errInfo: LogData = LogDataFactory.newInstance( + ErrorCode.ETS2BUNDLE_INTERNAL_FAILED_TO_FIND_GLUD_CODE, + ArkTSInternalErrorDescription, + `Failed to find glue code for: ${moduleRequest}` + ); + ModuleSourceFile.logger.printErrorAndExit(errInfo); + } + + FileManager.glueCodeFileInfos.set(originalAPIName, { + recordName: recordName, + baseUrl: glueCodeInfo.basePath, + abstractPath: glueCodeInfo.fullPath + } as FileInfo); + + return `@normalized:${ohmUrl}`; + } + + public static cleanUpObjects(): void { ModuleSourceFile.sourceFiles = []; ModuleSourceFile.projectConfig = undefined; diff --git a/compiler/src/fast_build/ark_compiler/rollup-plugin-gen-abc.ts b/compiler/src/fast_build/ark_compiler/rollup-plugin-gen-abc.ts index 08415ffeb961bc017441bc58a930cd88c461bf2b..9d21a248547745477be96ff9242ba133a8b9a133 100644 --- a/compiler/src/fast_build/ark_compiler/rollup-plugin-gen-abc.ts +++ b/compiler/src/fast_build/ark_compiler/rollup-plugin-gen-abc.ts @@ -28,6 +28,7 @@ import { cleanUpKitImportObjects } from '../../process_kit_import'; import { cleanUpFilesList } from './utils'; import { CommonLogger } from './logger'; import { cleanUpProcessArkTSEvolutionObj } from '../../process_arkts_evolution'; +import { FileManager } from './interop/interop_manager'; export function genAbc() { return { @@ -75,6 +76,7 @@ export function genAbc() { cleanSharedModuleSet(); CommonLogger.destroyInstance(); cleanUpProcessArkTSEvolutionObj(); + FileManager.cleanFileManagerObject(); } }; } diff --git a/compiler/src/fast_build/ark_compiler/utils.ts b/compiler/src/fast_build/ark_compiler/utils.ts index c4c94a77dd5c682088b0543fbf31982862de5b4f..5d60da55854e2854297c97e7d44be418a46845d7 100644 --- a/compiler/src/fast_build/ark_compiler/utils.ts +++ b/compiler/src/fast_build/ark_compiler/utils.ts @@ -308,4 +308,13 @@ export function hasArkDecorator(node: ts.MethodDeclaration | ts.FunctionDeclarat export const utUtils = { writeFileContent -}; \ No newline at end of file +}; + +export function hasExistingPaths(paths: Set): boolean { + for (const p of paths) { + if (fs.existsSync(toUnixPath(p))) { + return true; + } + } + return false; +} \ 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 89cd4cd542df4732b5fcc28e933aeb5ae5dc18b4..3b71ae831642d517a2d1f29a85df08ccbaa0523d 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 @@ -150,9 +150,6 @@ export function etsChecker() { // The generated js file might be different in some cases when we change the targetESVersion, // so we need to regenerate them all when targetESVersion is changed. return targetESVersionChanged; - }, - cleanUp(): void { - FileManager.cleanFileManagerObject(); } }; } diff --git a/compiler/test/ark_compiler_ut/ets_checker.test.ts b/compiler/test/ark_compiler_ut/ets_checker.test.ts index 6d5786792c1725ff1e1ba710c4a15281eb040be0..522fd3f106247bb6c88e763f964fb1fd5dfd3176 100644 --- a/compiler/test/ark_compiler_ut/ets_checker.test.ts +++ b/compiler/test/ark_compiler_ut/ets_checker.test.ts @@ -39,7 +39,7 @@ import { MAX_FLOW_DEPTH_DEFAULT_VALUE, resolveModuleNames as resolveModuleNamesMain } from '../../lib/ets_checker'; -import { TS_BUILD_INFO_SUFFIX } from '../../lib/pre_define'; +import { ARKTS_1_1, TS_BUILD_INFO_SUFFIX } from '../../lib/pre_define'; import { globalProgram, projectConfig @@ -49,6 +49,8 @@ import { arkTSEvolutionModuleMap, cleanUpProcessArkTSEvolutionObj } from '../../lib/process_arkts_evolution'; +import { ArkTSEvolutionModule } from './interop/interop_manager.test'; +import { FileManager } from '../../lib/fast_build/ark_compiler/interop/interop_manager'; mocha.describe('test ets_checker file api', function () { mocha.before(function () { @@ -527,4 +529,82 @@ mocha.describe('deleteProgramSourceFiles', () => { const newFileSize: number = program.getSourceFiles().length; expect(origrinFileSize === newFileSize).to.be.true; }); +}); + +mocha.describe('test interop sdk', function () { + let baseUrl; + mocha.before(function () { + this.rollup = new RollUpPluginMock(); + this.rollup.build(); + baseUrl = path.join(this.rollup.share.projectConfig.projectRootPath, './interop_sdk'); + const dependentModuleMap: Map = new Map(); + const aliasConfig: Map = new Map(); + const staticSDKDeclPath: Set = new Set([ + path.join(baseUrl, 'ets1.2interop/declarations/api'), + ]); + aliasConfig.set('application', path.join(baseUrl, './configs/alias.json')); + + dependentModuleMap.set('application', { + language: ARKTS_1_1, + packageName: 'application', + moduleName: 'application', + modulePath: '/MyApplication16/application', + declgenV1OutPath: '/MyApplication16/application/build/default/intermediates/declgen/default/declgenV1', + declgenV2OutPath: '/MyApplication16/application/build/default/intermediates/declgen/default/declgenV2', + declgenBridgeCodePath: '/MyApplication16/application/build/default/intermediates/declgen/default/declgenBridgeCode', + declFilesPath: '/MyApplication16/application/build/default/intermediates/declgen/default/decl-fileInfo.json', + dynamicFiles: [], + staticFiles: [], + cachePath: '/MyApplication16/application/build/cache', + byteCodeHarInfo: {} + }); + FileManager.cleanFileManagerObject(); + FileManager.initForTest( + dependentModuleMap, + aliasConfig, + undefined, + staticSDKDeclPath, + undefined); + }); + + mocha.after(() => { + delete this.rollup; + }); + + mocha.it('1-1: test use statis alias', function () { + this.rollup.build(); + const dependentModuleMap: Map = new Map(); + const aliasConfig: Map = new Map(); + const staticSDKDeclPath: Set = new Set([ + path.join(baseUrl, 'ets1.2interop/declarations/api'), + ]); + aliasConfig.set('application', path.join(baseUrl, './configs/alias.json')); + + dependentModuleMap.set('application', { + language: ARKTS_1_1, + packageName: 'application', + moduleName: 'application', + modulePath: baseUrl, + declgenV1OutPath: '/MyApplication16/application/build/default/intermediates/declgen/default/declgenV1', + declgenV2OutPath: '/MyApplication16/application/build/default/intermediates/declgen/default/declgenV2', + declgenBridgeCodePath: '/MyApplication16/application/build/default/intermediates/declgen/default/declgenBridgeCode', + declFilesPath: '/MyApplication16/application/build/default/intermediates/declgen/default/decl-fileInfo.json', + dynamicFiles: [], + staticFiles: [], + cachePath: '/MyApplication16/application/build/cache', + byteCodeHarInfo: {} + }); + FileManager.cleanFileManagerObject(); + FileManager.initForTest( + dependentModuleMap, + aliasConfig, + undefined, + staticSDKDeclPath, + undefined); + FileManager.setMixCompile(true); + const filePath = path.join(baseUrl, './source_code/file1.ts'); + const expectPath = path.join(baseUrl, './ets1.2interop/declarations/api/@ohos.errorCode.d.ets'); + const resolvedModules = resolveModuleNamesMain(['alias.errcode'], path.join(baseUrl, './source_code/file1.ts')); + expect(resolvedModules[0].resolvedFileName === expectPath).to.be.true; + }); }); \ 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 dd961e254809835270ff1f19b302e20d0c9ca9a3..8c3096ecb0cd1ac7bc53fa8d6c247512f251d07a 100644 --- a/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts +++ b/compiler/test/ark_compiler_ut/interop/interop_manager.test.ts @@ -114,8 +114,9 @@ mocha.describe('test interop_manager file api', function () { byteCodeHarInfo: {} }); FileManager.cleanFileManagerObject(); - FileManager.init( + FileManager.initForTest( dependentModuleMap, + undefined, dynamicSDKPath, staticSDKDeclPath, staticSDKGlueCodePath); @@ -127,6 +128,7 @@ mocha.describe('test interop_manager file api', function () { 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'); }); diff --git a/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/configs/alias.json b/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/configs/alias.json new file mode 100644 index 0000000000000000000000000000000000000000..7b12c22cc492cd284db73b515554031a4b0e1812 --- /dev/null +++ b/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/configs/alias.json @@ -0,0 +1,6 @@ +{ + "alias.errcode": { + "originalAPIName": "@ohos.errorCode", + "isStatic": "true" + } +} \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/ets1.2interop/declarations/api/@ohos.errorCode.d.ets b/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/ets1.2interop/declarations/api/@ohos.errorCode.d.ets new file mode 100644 index 0000000000000000000000000000000000000000..948ae04c71bcb69decca9fd87ed4179ccaab51d8 --- /dev/null +++ b/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/ets1.2interop/declarations/api/@ohos.errorCode.d.ets @@ -0,0 +1 @@ +export function foo(); \ No newline at end of file diff --git a/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/source_code/file1.ts b/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/source_code/file1.ts new file mode 100644 index 0000000000000000000000000000000000000000..e40ad6867d32c3b18815220d375b77dfd1a56cac --- /dev/null +++ b/compiler/test/ark_compiler_ut/testdata/testcase_def/interop_sdk/source_code/file1.ts @@ -0,0 +1,18 @@ +/* + * 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 { foo } from 'alias.errcode'; + +foo(); \ No newline at end of file