From dbcfa0d6f1d0f7ecdfec908711ed7babd16a7ba6 Mon Sep 17 00:00:00 2001 From: wuhailong Date: Sat, 7 Jun 2025 20:04:12 +0800 Subject: [PATCH] Fix symbols info loss in AST Issue: #ICDDSY Signed-off-by: wuhailong Change-Id: Idfa825b1530d2aae2f45e2c931167651f04209f8 --- .../src/fast_build/ark_compiler/logger.ts | 28 ++++--- .../ark_compiler/module/module_mode.ts | 2 +- .../ark_compiler/module/module_source_file.ts | 4 +- compiler/src/process_lazy_import.ts | 11 +-- .../common/process_lazy_import.test.ts | 77 ++++++++++++++++++- 5 files changed, 98 insertions(+), 24 deletions(-) diff --git a/compiler/src/fast_build/ark_compiler/logger.ts b/compiler/src/fast_build/ark_compiler/logger.ts index abdf135c1..1d5ce0f60 100644 --- a/compiler/src/fast_build/ark_compiler/logger.ts +++ b/compiler/src/fast_build/ark_compiler/logger.ts @@ -20,6 +20,15 @@ import { ES2ABC_ERROR_MAPPING } from './error_code'; +interface ErrorInfo { + code: ErrorCode; + description: string; + cause: string; + position: string; + solutions: string[]; + details: string; +} + export class CommonLogger { private static instance: CommonLogger; private logger: Object; @@ -142,29 +151,18 @@ export class LogDataFactory { if (!trimmedOutput) { return LogDataFactory.newInstance( ErrorCode.BYTECODE_OBFUSCATION_COMMON_ERROR, - 'Bytecode program terminated abnormally', - `Status code: ${statusCode}` - ); + 'Bytecode program terminated abnormally', `Status code: ${statusCode}`); } const parseErrorLines = (output: string): Record => - output - .split('\n') - .reduce((acc: Record, line) => { + output.split('\n').reduce((acc: Record, line) => { const [key, ...values] = line.split(':').map(part => part.trim()); return key && values.length ? { ...acc, [key]: values.join(':').trim() } : acc; }, {}); const parsedErrors = parseErrorLines(trimmedOutput); - const getErrorInfo = (): { - code: ErrorCode; - description: string; - cause: string; - position: string; - solutions: string[]; - details: string; - } => { + const getErrorInfo = (): ErrorInfo => { if (Object.keys(parsedErrors).length === 0) { return { code: ErrorCode.BYTECODE_OBFUSCATION_COMMON_ERROR, @@ -186,7 +184,7 @@ export class LogDataFactory { }; }; - const { code, description, cause, position, solutions, details } = getErrorInfo(); + const { code, description, cause, position, solutions, details }: ErrorInfo = getErrorInfo(); return LogDataFactory.newInstance( code, description, 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 a619cb2ef..d0c7dfe15 100644 --- a/compiler/src/fast_build/ark_compiler/module/module_mode.ts +++ b/compiler/src/fast_build/ark_compiler/module/module_mode.ts @@ -667,7 +667,7 @@ export class ModuleMode extends CommonMode { this.generateNpmEntriesInfo(); } this.generateAbcCacheFilesInfo(); - stopEvent(eventEenDescriptionsForMergedEs2abc) + stopEvent(eventEenDescriptionsForMergedEs2abc); } generateMergedAbcOfEs2Abc(parentEvent: CompileEvent): void { 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 2152ebdfe..3694f43a7 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 @@ -229,7 +229,7 @@ export class ModuleSourceFile { pkgName: rollupObject.share.projectConfig.entryPackageName, pkgPath: rollupObject.share.projectConfig.modulePath } - } + }; } static isMockFile(file: string, rollupObject: Object): boolean { @@ -328,7 +328,7 @@ export class ModuleSourceFile { return ModuleSourceFile.sourceFiles; } - static async processSingleModuleSourceFile(rollupObject: Object, moduleId: string, parentEvent: CompileEvent| undefined): Promise { + static async processSingleModuleSourceFile(rollupObject: Object, moduleId: string, parentEvent: CompileEvent | undefined): Promise { if (!ModuleSourceFile.isEnvInitialized) { this.initPluginEnv(rollupObject); ModuleSourceFile.setProcessMock(rollupObject); diff --git a/compiler/src/process_lazy_import.ts b/compiler/src/process_lazy_import.ts index 5e87a2e4f..a7004df8a 100644 --- a/compiler/src/process_lazy_import.ts +++ b/compiler/src/process_lazy_import.ts @@ -90,8 +90,8 @@ function updateImportDecl(node: ts.ImportDeclaration, resolver: Object): ts.Impo // eliminate the type symbol // eg: import { type t, x } from '...' --> import { x } from '...' const newNameBindings: ts.ImportSpecifier[] = eliminateTypeSymbol(namedBindings, resolver); - newImportClause = ts.factory.createImportClause(false, importClause.name, - ts.factory.createNamedImports(newNameBindings)); + newImportClause = ts.factory.updateImportClause(importClause, false, importClause.name, + ts.factory.updateNamedImports(namedBindings, newNameBindings)); } else { newImportClause = importClause; } @@ -113,10 +113,11 @@ function eliminateTypeSymbol(namedBindings: ts.NamedImportBindings, resolver: Ob // import { x } from './y' --> propertyName is undefined // import { x as a } from './y' --> propertyName is x newNameBindings.push( - ts.factory.createImportSpecifier( + ts.factory.updateImportSpecifier( + element, false, - element.propertyName ? ts.factory.createIdentifier(element.propertyName.text) : undefined, - ts.factory.createIdentifier(element.name.text) + element.propertyName, + element.name ) ); } diff --git a/compiler/test/ark_compiler_ut/common/process_lazy_import.test.ts b/compiler/test/ark_compiler_ut/common/process_lazy_import.test.ts index ca4b2e72a..2fc025d0b 100644 --- a/compiler/test/ark_compiler_ut/common/process_lazy_import.test.ts +++ b/compiler/test/ark_compiler_ut/common/process_lazy_import.test.ts @@ -25,7 +25,8 @@ import { processJsCodeLazyImport, reExportNoCheckMode, reExportCheckLog, - resetReExportCheckLog + resetReExportCheckLog, + transformLazyImport } from '../../../lib/process_lazy_import'; import { RELEASE } from '../../../lib/fast_build/ark_compiler/common/ark_define'; import { ModuleSourceFile } from '../../../lib/fast_build/ark_compiler/module/module_source_file'; @@ -389,4 +390,78 @@ mocha.describe('process Lazy Imports tests', function () { const result: string = processJsCodeLazyImport('index.js', code, true, 'strict'); expect(result === expectCode).to.be.true; }); + + mocha.it('3-1: test transformLazyImport: the symbol exist after conversion', function () { + const files: Record = { + 'main.ts': ` + import { foo } from './lib'; + console.log(foo); + `, + 'lib.ts': ` + export const foo = 42; + ` + }; + + const fileNames = Object.keys(files); + + const compilerHost = ts.createCompilerHost({}, true); + const getFileKey = (filePath: string) => path.basename(filePath); + + compilerHost.getSourceFile = (filePath, languageVersion) => { + const key = getFileKey(filePath); + const sourceText = files[key]; + return sourceText !== undefined + ? ts.createSourceFile(filePath, sourceText, languageVersion, true) + : undefined; + }; + + compilerHost.readFile = (filePath) => { + const key = getFileKey(filePath); + return files[key]; + }; + + compilerHost.fileExists = (filePath) => { + const key = getFileKey(filePath); + return key in files; + }; + + compilerHost.getCanonicalFileName = fileName => + ts.sys.useCaseSensitiveFileNames ? fileName : fileName.toLowerCase(); + + const program = ts.createProgram(['main.ts'], { + target: ts.ScriptTarget.ESNext, + module: ts.ModuleKind.ESNext + }, compilerHost); + + const checker = program.getTypeChecker(); + + const originalSource = program.getSourceFile('main.ts')!; + const libSource = program.getSourceFile('lib.ts')!; + + const libFooSymbol = (() => { + for (const stmt of libSource.statements) { + if (ts.isVariableStatement(stmt)) { + const decl = stmt.declarationList.declarations[0]; + if (ts.isIdentifier(decl.name) && decl.name.text === 'foo') { + return checker.getSymbolAtLocation(decl.name)!; + } + } + } + })(); + const mockResolver = { + isReferencedAliasDeclaration() { + return true; + } + }; + + const transformed = transformLazyImport(originalSource, mockResolver); + + const importDecl = transformed.statements.find(ts.isImportDeclaration)!; + const specifiers = (importDecl.importClause!.namedBindings as ts.NamedImports).elements; + + for (const spec of specifiers) { + const transformedSymbol = checker.getSymbolAtLocation(spec.name); + expect(transformedSymbol).to.exist; + } + }); }); \ No newline at end of file -- Gitee