Fix codecheck for printer optimization

Issue: https://gitee.com/openharmony/developtools_ace_ets2bundle/issues/IB1MSS

Test: ut & arkTest

Signed-off-by: dengxinyu <dengxinyu4@huawei.com>
Change-Id: I2a1b0de85104ddffafddaa1f3a8dc4e97f6abc47
This commit is contained in:
dengxinyu 2024-11-02 21:21:57 +08:00
parent b6f03f2081
commit c27441013f
3 changed files with 253 additions and 40 deletions

View File

@ -71,14 +71,20 @@ import {
projectConfig,
sdkConfigPrefix
} from '../main';
import { getRelativeSourcePath, mangleFilePath } from './fast_build/ark_compiler/common/ob_config_resolver';
import {
getRelativeSourcePath,
mangleFilePath,
setNewNameCache,
getNameCacheByPath,
setUnobfuscationNames,
writeObfuscatedFile
} from './fast_build/ark_compiler/common/ob_config_resolver';
import { moduleRequestCallback } from './fast_build/system_api/api_check_utils';
import { SourceMapGenerator } from './fast_build/ark_compiler/generate_sourcemap';
import { sourceFileBelongProject } from './fast_build/ark_compiler/module/module_source_file';
const red: string = '\u001b[31m';
const reset: string = '\u001b[39m';
const IDENTIFIER_CACHE: string = 'IdentifierCache';
export const SRC_MAIN: string = 'src/main';
@ -484,7 +490,10 @@ function replaceRelativeDependency(item: string, moduleRequest: string, sourcePa
return item;
}
interface ModuleInfo {
/**
* Informantion of build files
*/
export interface ModuleInfo {
content: string,
/**
* the path in build cache dir
@ -555,16 +564,7 @@ export async function writeArkguardObfuscatedSourceCode(moduleInfo: ModuleInfo,
previousStageSourceMap = sourceMapGeneratorInstance.getSpecifySourceMap(rollupNewSourceMaps, selectedFilePath) as sourceMap.RawSourceMap;
}
let historyNameCache = new Map<string, string>();
let namecachePath = moduleInfo.relativeSourceFilePath;
if (isDeclaration) {
namecachePath = getRelativeSourcePath(moduleInfo.originSourceFilePath, projectRootPath,
sourceFileBelongProject.get(toUnixPath(moduleInfo.originSourceFilePath)));
}
if (nameCacheMap) {
let identifierCache = nameCacheMap.get(namecachePath)?.[IDENTIFIER_CACHE];
deleteLineInfoForNameString(historyNameCache, identifierCache);
}
const historyNameCache: Map<string, string> = getNameCacheByPath(moduleInfo, isDeclaration, projectRootPath);
let mixedInfo: { content: string, sourceMap?: Object, nameCache?: Object, unobfuscationNameMap?: Map<string, Set<string>>};
let projectInfo: {
@ -591,35 +591,16 @@ export async function writeArkguardObfuscatedSourceCode(moduleInfo: ModuleInfo,
sourceMapGeneratorInstance.updateSpecifySourceMap(rollupNewSourceMaps, selectedFilePath, mixedInfo.sourceMap);
}
if (mixedInfo.nameCache && !isDeclaration) {
let obfName: string = moduleInfo.relativeSourceFilePath;
let isOhModule = isPackageModulesFile(moduleInfo.originSourceFilePath, projectConfig);
if (projectConfig.obfuscationMergedObConfig?.options.enableFileNameObfuscation && !isOhModule) {
obfName = mangleFilePath(moduleInfo.relativeSourceFilePath);
}
mixedInfo.nameCache.obfName = obfName;
nameCacheMap.set(moduleInfo.relativeSourceFilePath, mixedInfo.nameCache);
}
setNewNameCache(mixedInfo.nameCache, isDeclaration, moduleInfo, projectConfig);
if (mixedInfo.unobfuscationNameMap && !isDeclaration) {
let arrayObject: Record<string, string[]> = {};
// The type of unobfuscationNameMap's value is Set, convert Set to Array.
mixedInfo.unobfuscationNameMap.forEach((value: Set<string>, key: string) => {
let array: string[] = Array.from(value);
arrayObject[key] = array;
});
unobfuscationNamesObj[moduleInfo.relativeSourceFilePath] = arrayObject;
}
setUnobfuscationNames(mixedInfo.unobfuscationNameMap, moduleInfo.relativeSourceFilePath, isDeclaration);
const newFilePath: string = tryMangleFileName(moduleInfo.buildFilePath, projectConfig, moduleInfo.originSourceFilePath);
if (newFilePath !== moduleInfo.buildFilePath && !isDeclaration) {
sourceMapGeneratorInstance.saveKeyMappingForObfFileName(moduleInfo.rollupModuleId!);
}
performancePrinter?.singleFilePrinter?.startEvent(EventList.WRITE_FILE, performancePrinter.timeSumPrinter);
mkdirsSync(path.dirname(newFilePath));
fs.writeFileSync(newFilePath, mixedInfo.content ?? '');
performancePrinter?.singleFilePrinter?.endEvent(EventList.WRITE_FILE, performancePrinter.timeSumPrinter, false, true);
writeObfuscatedFile(newFilePath, mixedInfo.content ?? '');
}
export function tryMangleFileName(filePath: string, projectConfig: Object, originalFilePath: string): string {

View File

@ -19,16 +19,23 @@ import type * as ts from 'typescript';
import {
ApiExtractor,
clearGlobalCaches,
performancePrinter
performancePrinter,
getRelativeSourcePath,
nameCacheMap,
deleteLineInfoForNameString,
mangleFilePath,
unobfuscationNamesObj,
EventList
} from 'arkguard';
import type {
ArkObfuscator,
} from 'arkguard';
import { toUnixPath } from '../../../utils';
import { isPackageModulesFile, mkdirsSync, toUnixPath } from '../../../utils';
import { allSourceFilePaths, localPackageSet } from '../../../ets_checker';
import { isCurrentProjectFiles } from '../utils';
import { sourceFileBelongProject } from '../module/module_source_file';
import { ModuleInfo } from '../../../ark_utils';
export {
collectResevedFileNameInIDEConfig, // For running unit test.
@ -60,6 +67,11 @@ export function resetObfuscation(): void {
*/
export const sourceFileDependencies: Map<string, ts.ModeAwareCache<ts.ResolvedModuleFull | undefined>> = new Map();
/**
* Identifier cache name
*/
export const IDENTIFIER_CACHE: string = 'IdentifierCache';
// Collect all keep files. If the path configured by the developer is a folder, all files in the compilation will be used to match this folder.
function collectAllKeepFiles(startPaths: string[], excludePathSet: Set<string>): Set<string> {
const allKeepFiles: Set<string> = new Set();
@ -144,6 +156,82 @@ export function disablePerformancePrinter(): void {
if (performancePrinter !== undefined) {
performancePrinter.filesPrinter = undefined;
performancePrinter.singleFilePrinter = undefined;
performancePrinter.timeSumPrinter = undefined
performancePrinter.timeSumPrinter = undefined;
}
}
/**
* Get namecache by path
*
* If it is a declaration file, retrieves the corresponding source file's obfuscation results
* Or retrieves obfuscation results from full compilation run
*/
export function getNameCacheByPath(
moduleInfo: ModuleInfo,
isDeclaration: boolean,
projectRootPath: string | undefined
): Map<string, string> {
let historyNameCache = new Map<string, string>();
let nameCachePath = moduleInfo.relativeSourceFilePath;
if (isDeclaration) {
nameCachePath = getRelativeSourcePath(
moduleInfo.originSourceFilePath,
projectRootPath,
sourceFileBelongProject.get(toUnixPath(moduleInfo.originSourceFilePath))
);
}
if (nameCacheMap) {
let identifierCache = nameCacheMap.get(nameCachePath)?.[IDENTIFIER_CACHE];
deleteLineInfoForNameString(historyNameCache, identifierCache);
}
return historyNameCache;
}
/**
* Set newly updated namecache for project source files
*/
export function setNewNameCache(
newNameCache: Object,
isDeclaration: boolean,
moduleInfo: ModuleInfo,
projectConfig: Object
): void {
if (newNameCache && !isDeclaration) {
let obfName: string = moduleInfo.relativeSourceFilePath;
let isOhModule: boolean = isPackageModulesFile(moduleInfo.originSourceFilePath, projectConfig);
if (projectConfig.obfuscationMergedObConfig?.options.enableFileNameObfuscation && !isOhModule) {
obfName = mangleFilePath(moduleInfo.relativeSourceFilePath);
}
newNameCache.obfName = obfName;
nameCacheMap.set(moduleInfo.relativeSourceFilePath, newNameCache);
}
}
/**
* Set unobfuscation list after obfuscation
*/
export function setUnobfuscationNames(
unobfuscationNameMap: Map<string, Set<string>> | undefined,
relativeSourceFilePath: string,
isDeclaration: boolean
): void {
if (unobfuscationNameMap && !isDeclaration) {
let arrayObject: Record<string, string[]> = {};
// The type of unobfuscationNameMap's value is Set, convert Set to Array.
unobfuscationNameMap.forEach((value: Set<string>, key: string) => {
let array: string[] = Array.from(value);
arrayObject[key] = array;
});
unobfuscationNamesObj[relativeSourceFilePath] = arrayObject;
}
}
/**
* Write out obfuscated files
*/
export function writeObfuscatedFile(newFilePath: string, content: string): void {
performancePrinter?.singleFilePrinter?.startEvent(EventList.WRITE_FILE, performancePrinter.timeSumPrinter);
mkdirsSync(path.dirname(newFilePath));
fs.writeFileSync(newFilePath, content);
performancePrinter?.singleFilePrinter?.endEvent(EventList.WRITE_FILE, performancePrinter.timeSumPrinter, false, true);
}

View File

@ -24,9 +24,14 @@ import {
MergedConfig,
ObConfigResolver,
collectResevedFileNameInIDEConfig,
getNameCacheByPath,
getRelativeSourcePath,
handleKeepFilesAndGetDependencies,
sourceFileDependencies
setNewNameCache,
setUnobfuscationNames,
sourceFileDependencies,
writeObfuscatedFile,
IDENTIFIER_CACHE
} from '../../../lib/fast_build/ark_compiler/common/ob_config_resolver';
import {
OBFUSCATION_RULE_PATH,
@ -35,7 +40,7 @@ import {
import { OBFUSCATION_TOOL } from '../../../lib/fast_build/ark_compiler/common/ark_define';
import { RELEASE } from '../../../lib/fast_build/ark_compiler/common/ark_define';
import RollUpPluginMock from '../mock/rollup_mock/rollup_plugin_mock';
import { ArkObfuscator } from 'arkguard';
import { ArkObfuscator, nameCacheMap, unobfuscationNamesObj } from 'arkguard';
const OBFUSCATE_TESTDATA_DIR = path.resolve(__dirname, '../../../test/ark_compiler_ut/testdata/obfuscation');
@ -726,4 +731,143 @@ mocha.describe('test obfuscate config resolver api', function () {
expect(keepFilesAndDependencies.has(testFile4)).to.be.true;
expect(keepFilesAndDependencies.has(testFile5)).to.be.false;
});
mocha.it('6-1: test getHistoryNameCache: isDeclaration false', function () {
const moduleInfo = {
content: 'module content',
buildFilePath: 'build/path/to/file.ts',
relativeSourceFilePath: 'src/file.ts',
originSourceFilePath: 'C:/projects/my-project/src/file.ts'
};
nameCacheMap.set('src/file.ts', {
[IDENTIFIER_CACHE]: {
'identifier1:1': 'obfuscated1',
identifier2: 'obfuscated2'
}
});
const isDeclaration: boolean = false;
const projectRootPath: string = 'C:/projects/my-project';
const result: Map<string, string> = getNameCacheByPath(moduleInfo, isDeclaration, projectRootPath);
nameCacheMap.clear();
expect(result.size).to.equal(2);
expect(result.get('identifier1')).to.equal('obfuscated1');
expect(result.get('identifier2')).to.equal('obfuscated2');
});
mocha.it('6-2: test getHistoryNameCache: isDeclaration true', function () {
const moduleInfo = {
content: 'module content',
buildFilePath: 'build/path/to/file.d.ts',
relativeSourceFilePath: 'src/file.ts',
originSourceFilePath: 'C:/projects/my-project/src/file.ts'
};
nameCacheMap.set('src/file.ts', {
[IDENTIFIER_CACHE]: {
'identifier1:1': 'obfuscated1',
identifier2: 'obfuscated2'
}
});
const isDeclaration: boolean = true;
const projectRootPath: string = 'C:/projects/my-project';
const result: Map<string, string> = getNameCacheByPath(moduleInfo, isDeclaration, projectRootPath);
nameCacheMap.clear();
expect(result.size).to.equal(2);
expect(result.get('identifier1')).to.equal('obfuscated1');
expect(result.get('identifier2')).to.equal('obfuscated2');
});
mocha.it('7-1: test setNewNameCache: isOhModule is false', function () {
const moduleInfo = {
content: 'module content',
buildFilePath: 'build/path/to/file.ts',
relativeSourceFilePath: 'src/file.ts',
originSourceFilePath: 'C:/projects/my-project/src/file.ts'
};
nameCacheMap.set('src/file.ts', {
[IDENTIFIER_CACHE]: {
'identifier1:1': 'obfuscated1',
identifier2: 'obfuscated2'
}
});
const newNameCache = {
[IDENTIFIER_CACHE]: {
'identifier3:3': 'obfuscated3'
}
};
const isDeclaration: boolean = false;
const projectConfig: Object = {
obfuscationMergedObConfig: { options: { enableFileNameObfuscation: true } },
projectRootPath: '/projectRoot',
packageDir: 'oh_modules',
modulePathMap: {
module1: '/externalModule'
},
};
setNewNameCache(newNameCache, isDeclaration, moduleInfo, projectConfig);
const result: string | {} = nameCacheMap.get(moduleInfo.relativeSourceFilePath);
nameCacheMap.clear();
expect(result[IDENTIFIER_CACHE]['identifier3:3'] === 'obfuscated3').to.be.true;
expect(result.obfName === 'src/file.ts').to.be.false;
});
mocha.it('7-2: test setNewNameCache: isOhModule is true', function () {
const moduleInfo = {
content: 'module content',
buildFilePath: 'build/path/to/file.ts',
relativeSourceFilePath: 'src/file.ts',
originSourceFilePath: '/projectRoot/oh_modules/src/file.ts'
};
nameCacheMap.set('src/file.ts', {
[IDENTIFIER_CACHE]: {
'identifier1:1': 'obfuscated1',
identifier2: 'obfuscated2'
}
});
const newNameCache = {
[IDENTIFIER_CACHE]: {
'identifier3:3': 'obfuscated3'
}
};
const isDeclaration: boolean = false;
const projectConfig: Object = {
obfuscationMergedObConfig: { options: { enableFileNameObfuscation: true } },
projectRootPath: '/projectRoot',
packageDir: 'oh_modules'
};
setNewNameCache(newNameCache, isDeclaration, moduleInfo, projectConfig);
const result: string | {} = nameCacheMap.get(moduleInfo.relativeSourceFilePath);
nameCacheMap.clear();
expect(result[IDENTIFIER_CACHE]['identifier3:3'] === 'obfuscated3').to.be.true;
expect(result.obfName === 'src/file.ts').to.be.true;
});
mocha.it('8-1: test setUnobfuscationNames', function () {
const relativeSourceFilePath: string = 'src/file.ts';
const unobfuscationNameMap: Map<string, Set<string>> = new Map([
['key1', new Set(['value1', 'value2'])],
['key2', new Set(['value3'])]
]);
const isDeclaration: boolean = false;
setUnobfuscationNames(unobfuscationNameMap, relativeSourceFilePath, isDeclaration);
expect(unobfuscationNamesObj[relativeSourceFilePath]).to.deep.equal({
key1: ['value1', 'value2'],
key2: ['value3']
});
});
mocha.it('9-1: test writeFile', function () {
const newFilePath: string = '../../test/ark_compiler_ut/testdata/writeFile.ts';
const content: string = 'obfuscated code';
writeObfuscatedFile(newFilePath, content);
expect(fs.existsSync(newFilePath)).to.be.true;
const fileContent: string = fs.readFileSync(newFilePath, 'utf-8');
expect(fileContent).to.equal(content);
fs.unlinkSync(newFilePath);
});
});