diff --git a/compiler/main.js b/compiler/main.js index b8b98b1cfd745b762524a6cb2f6dd9a7cca47969..55772bde59d22cb2961481903dc53c90dbea123b 100644 --- a/compiler/main.js +++ b/compiler/main.js @@ -73,7 +73,8 @@ let ohosSystemModulePaths = []; let ohosSystemModuleSubDirPaths = []; let allModulesPaths = []; let externalApiCheckPlugin = new Map(); - +let externalApiMethodPlugin = new Map(); +let fileDeviceCheckPlugin = new Map(); function initProjectConfig(projectConfig) { initProjectPathConfig(projectConfig); @@ -799,8 +800,11 @@ function collectExternalApiCheckPlugin(sdkConfig, sdkPath) { pluginConfigs.forEach(config => { const pluginPrefix = sdkConfig.osName + '/' + config.tag; config.path = path.resolve(sdkPath, config.path); + let externalApiCheckPlugins; if (externalApiCheckPlugin.get(pluginPrefix)) { - externalApiCheckPlugin.set(pluginPrefix, externalApiCheckPlugin.get(pluginPrefix).push(...pluginConfigs)); + externalApiCheckPlugins = externalApiCheckPlugin.get(pluginPrefix); + externalApiCheckPlugins.push(...pluginConfigs); + externalApiCheckPlugin.set(pluginPrefix, externalApiCheckPlugins); } else { externalApiCheckPlugin.set(pluginPrefix, [...pluginConfigs]); } @@ -1148,6 +1152,8 @@ function resetMain() { ohosSystemModuleSubDirPaths = []; allModulesPaths = []; externalApiCheckPlugin = new Map(); + externalApiMethodPlugin = new Map(); + fileDeviceCheckPlugin = new Map(); } function resetAbilityConfig() { @@ -1239,4 +1245,6 @@ exports.setEntryArrayForObf = setEntryArrayForObf; exports.getPackageJsonEntryPath = getPackageJsonEntryPath; exports.setIntentEntryPages = setIntentEntryPages; exports.externalApiCheckPlugin = externalApiCheckPlugin; +exports.externalApiMethodPlugin = externalApiMethodPlugin; +exports.fileDeviceCheckPlugin = fileDeviceCheckPlugin; exports.setStartupPagesForObf = setStartupPagesForObf; diff --git a/compiler/src/fast_build/system_api/api_check_define.ts b/compiler/src/fast_build/system_api/api_check_define.ts index d4a8a9794246f264812b6f997bc0ddcbb4e709dc..843b7247ec5eb89e433b8a60e2febd3162bf8d7d 100644 --- a/compiler/src/fast_build/system_api/api_check_define.ts +++ b/compiler/src/fast_build/system_api/api_check_define.ts @@ -53,3 +53,9 @@ export const CONSTANT_STEP_3: number = 3; export const GLOBAL_DECLARE_WHITE_LIST: Set = new Set(['Context', 'PointerStyle', 'PixelMap', 'UnifiedData', 'Summary', 'UniformDataType', 'IntentionCode', 'NavDestinationInfo', 'UIContext', 'Resource', 'WebviewController']); + +export enum ComparisonResult { + Less = -1, + Equal = 0, + Greater = 1 +} \ No newline at end of file diff --git a/compiler/src/fast_build/system_api/api_check_utils.ts b/compiler/src/fast_build/system_api/api_check_utils.ts index 8eff0797fc03166a3942394b08478986100d0cc7..19f4cfbc39d032216dfbf7869ad19d77eac47818 100644 --- a/compiler/src/fast_build/system_api/api_check_utils.ts +++ b/compiler/src/fast_build/system_api/api_check_utils.ts @@ -25,7 +25,8 @@ import { systemModules, allModulesPaths, ohosSystemModuleSubDirPaths, - externalApiCheckPlugin + externalApiCheckPlugin, + externalApiMethodPlugin } from '../../../main'; import { LogType, @@ -71,7 +72,8 @@ import { GLOBAL_DECLARE_WHITE_LIST, SINCE_TAG_NAME, SINCE_TAG_CHECK_ERROER, - VERSION_CHECK_FUNCTION_NAME + VERSION_CHECK_FUNCTION_NAME, + ComparisonResult } from './api_check_define'; import { JsDocCheckService } from './api_check_permission'; import { SdkVersionValidator } from './sdk_version_validator'; @@ -580,6 +582,7 @@ function checkSinceValue( // Perform version validation check const versionChecker = getVersionValidationFunction(); + let projectTargetVersion: string; if (versionChecker === compareVersionsWithPointSystem) { projectTargetVersion = projectConfig.compatibleSdkVersion.toString(); @@ -613,18 +616,31 @@ function checkSinceValue( * @returns Version validation function (external or default) */ export function getVersionValidationFunction(): VersionValidationFunction { + const pluginKey = getPluginKey(projectConfig.runtimeOS, SINCE_TAG_NAME); + + // First check if we already have a cached method + if (externalApiMethodPlugin.has(pluginKey)) { + return externalApiMethodPlugin.get(pluginKey)!; + } + + // Fallback to default if no compatible SDK version if (projectConfig.originCompatibleSdkVersion?.toString() === undefined) { + externalApiMethodPlugin.set(pluginKey, compareVersionsWithPointSystem); return compareVersionsWithPointSystem; } - const pluginKey = getPluginKey(projectConfig.runtimeOS, SINCE_TAG_NAME); + const plugins = externalApiCheckPlugin.get(pluginKey); - + // Check if external plugins exist and try to load them if (plugins && plugins.length > 0) { try { for (const plugin of plugins) { + // Load the external method const externalMethod = require(plugin.path)[plugin.functionName]; + if (typeof externalMethod === 'function') { + // Cache with pluginKey for future calls + externalApiMethodPlugin.set(pluginKey, externalMethod); return externalMethod; } } @@ -632,7 +648,9 @@ export function getVersionValidationFunction(): VersionValidationFunction { console.warn(`Failed to load external version validator: ${error}`); } } - + + // Cache and return default method + externalApiMethodPlugin.set(pluginKey, compareVersionsWithPointSystem); return compareVersionsWithPointSystem; } @@ -925,13 +943,14 @@ function getMinVersion(jsDocs: ts.JSDoc[]): string { return minVersion; } + /** * compare point version * @param { string } firstVersion * @param { string } secondVersion * @returns { number } */ -function comparePointVersion(firstVersion: string, secondVersion: string): -1 | 0 | 1 { +function comparePointVersion(firstVersion: string, secondVersion: string): ComparisonResult { const firstParts = firstVersion.split('.'); const secondParts = secondVersion.split('.'); @@ -940,9 +959,9 @@ function comparePointVersion(firstVersion: string, secondVersion: string): -1 | const part2 = parseInt(secondParts[i] || '0', 10); if (part1 !== part2) { - return part1 > part2 ? 1 : -1; + return part1 > part2 ? ComparisonResult.Greater : ComparisonResult.Less; } } - return 0; + return ComparisonResult.Equal; } \ No newline at end of file diff --git a/compiler/src/fast_build/system_api/sdk_version_validator.ts b/compiler/src/fast_build/system_api/sdk_version_validator.ts index 74b9901c864024902a1848408c52d0491960c67c..fd1206e40ac6ab5bfafc6ba623621f40f90ae137 100644 --- a/compiler/src/fast_build/system_api/sdk_version_validator.ts +++ b/compiler/src/fast_build/system_api/sdk_version_validator.ts @@ -15,11 +15,13 @@ import ts from 'typescript'; import { - projectConfig + projectConfig, + fileDeviceCheckPlugin } from '../../../main'; import { getVersionValidationFunction } from './api_check_utils'; +import fs from 'fs'; /** * The node is considered **valid** if it satisfies **at least one** of the following: @@ -37,6 +39,7 @@ export class SdkVersionValidator { [this.otherSourceDeviceInfo, ['@ohos.deviceInfo.d.ts']], [this.openSourceDeviceInfo, ['@ohos.deviceInfo.d.ts']] ]); + private readonly fileDeviceCheckCache: Map = new Map(); private readonly typeChecker?: ts.TypeChecker; @@ -117,6 +120,31 @@ export class SdkVersionValidator { } private isNodeWrappedInSdkComparison(node: ts.Node): boolean { + const nodeSourceFile = node.getSourceFile()?.fileName; + if (!nodeSourceFile) { + return false; + } + + // First check cache + if (fileDeviceCheckPlugin.has(nodeSourceFile)) { + const hasDeviceInfo = fileDeviceCheckPlugin.get(nodeSourceFile)!; + if (!hasDeviceInfo) { + return false; + } + } else { + // File not in cache, read and cache the result + try { + const fileContent: string = fs.readFileSync(nodeSourceFile, { encoding: 'utf-8' }); + const deviceInfoContentChecker = /\bdeviceInfo\b/.test(fileContent); + fileDeviceCheckPlugin.set(nodeSourceFile, deviceInfoContentChecker); + if (!deviceInfoContentChecker) { + return false; + } + } catch (error) { + console.warn('Error reading device info: ' + nodeSourceFile); + } + } + if (this.compatibleSdkVersion === '' || !this.typeChecker) { return false; }