diff --git a/ets2panda/bindings/BUILD.gn b/ets2panda/bindings/BUILD.gn index b44cda313ead9b8b008c383b64f441704df69bfd..0e6be72fd93968839af67b16371f60a78528a488 100644 --- a/ets2panda/bindings/BUILD.gn +++ b/ets2panda/bindings/BUILD.gn @@ -337,24 +337,33 @@ action("build_bindings") { ":ts_bindings", ] sources = [ - "./src/Es2pandaNativeModule.ts", - "./src/InteropNativeModule.ts", - "./src/InteropTypes.ts", - "./src/Platform.ts", - "./src/Wrapper.ts", - "./src/arrays.ts", - "./src/generated/Es2pandaEnums.ts", - "./src/generated/Es2pandaNativeModule.ts", - "./src/global.ts", - "./src/index.ts", - "./src/loadLibraries.ts", - "./src/lspNode.ts", - "./src/mainWrapper.ts", - "./src/private.ts", - "./src/strings.ts", - "./src/ts-reflection.ts", - "./src/types.ts", - "./src/utils.ts", + "src/common/Es2pandaNativeModule.ts", + "src/common/InteropNativeModule.ts", + "src/common/InteropTypes.ts", + "src/common/Platform.ts", + "src/common/Wrapper.ts", + "src/common/arrays.ts", + "src/common/driver_helper.ts", + "src/common/global.ts", + "src/common/loadLibraries.ts", + "src/common/mainWrapper.ts", + "src/common/preDefine.ts", + "src/common/private.ts", + "src/common/strings.ts", + "src/common/ts-reflection.ts", + "src/common/types.ts", + "src/common/ui_plugins_driver.ts", + "src/common/utils.ts", + "src/common/arkTSConfigGenerator.ts", + "src/generated/Es2pandaEnums.ts", + "src/generated/Es2pandaNativeModule.ts", + "src/index.ts", + "src/lsp/compile_thread_worker.ts", + "src/lsp/generateArkTSConfig.ts", + "src/lsp/generateBuildConfig.ts", + "src/lsp/index.ts", + "src/lsp/lspNode.ts", + "src/lsp/lsp_helper.ts", ] script = "build_bindings.py" diff --git a/ets2panda/bindings/src/arktsConfigGenerate.ts b/ets2panda/bindings/src/arktsConfigGenerate.ts deleted file mode 100644 index 56f00052edfbf3e3b8fa7090facefb977730077b..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/src/arktsConfigGenerate.ts +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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 { BuildMode } from './build/buildMode'; -import { BuildConfig } from './types'; -import { ModuleDescriptor, generateBuildConfigs } from './buildConfigGenerate'; -import { PANDA_SDK_PATH_FROM_SDK } from './preDefine'; - -import * as fs from 'fs'; -import * as path from 'path'; -import { PluginDriver } from './ui_plugins_driver'; - -function processBuildConfig(projectConfig: BuildConfig): BuildConfig { - let buildConfig: BuildConfig = { ...projectConfig }; - let buildSdkPath: string = buildConfig.buildSdkPath as string; - buildConfig.pandaSdkPath = buildConfig.pandaSdkPath ?? path.resolve(buildSdkPath, PANDA_SDK_PATH_FROM_SDK); - PluginDriver.getInstance().initPlugins(buildConfig); - return buildConfig; -} - -export function generateArkTsConfigByModules( - buildSdkPath: string, - projectRoot: string, - modules?: ModuleDescriptor[] -): void { - const allBuildConfig = generateBuildConfigs(buildSdkPath, projectRoot, modules); - let compileFileInfos: Record = {}; - const cacheDir = path.join(projectRoot, '.idea', '.deveco'); - const compileFileInfosPath = path.join(cacheDir, 'lsp_compileFileInfos.json'); - Object.keys(allBuildConfig).forEach((moduleName) => { - const moduleConfig = allBuildConfig[moduleName] as BuildConfig; - const processedConfig = processBuildConfig(moduleConfig); - - const buildMode = new BuildMode(processedConfig); - buildMode.generateArkTSConfig(compileFileInfos); - }); - try { - const jsonCompileFileInfos = JSON.stringify(compileFileInfos, null, 2); - if (!fs.existsSync(cacheDir)) { - fs.mkdirSync(cacheDir, { recursive: true }); - } - fs.writeFileSync(compileFileInfosPath, jsonCompileFileInfos, 'utf-8'); - } catch (err) { - console.error(`Failed to write compileFileInfos to ${compileFileInfosPath} with error: ${err}`); - } -} diff --git a/ets2panda/bindings/src/build/buildMode.ts b/ets2panda/bindings/src/build/buildMode.ts deleted file mode 100644 index d1be834b99fda47c40eb4787f8670bfa76be6268..0000000000000000000000000000000000000000 --- a/ets2panda/bindings/src/build/buildMode.ts +++ /dev/null @@ -1,188 +0,0 @@ -/* - * 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 * as path from 'path'; - -import { ABC_SUFFIX, ARKTSCONFIG_JSON_FILE, LANGUAGE_VERSION } from '../preDefine'; -import { changeFileExtension } from '../utils'; -import { BuildConfig, DependentModuleConfig, ModuleInfo, CompileFileInfo } from '../types'; -import { ArkTSConfigGenerator } from './generateArkTSConfig'; - -export class BuildMode { - buildConfig: BuildConfig; - entryFiles: Set; - compileFiles: Map; - cacheDir: string; - pandaSdkPath: string; - buildSdkPath: string; - packageName: string; - sourceRoots: string[]; - moduleRootPath: string; - moduleType: string; - dependentModuleList: DependentModuleConfig[]; - moduleInfos: Map; - declgenV1OutPath: string | undefined; - declgenBridgeCodePath: string | undefined; - hasMainModule: boolean; - - constructor(buildConfig: BuildConfig) { - this.buildConfig = buildConfig; - this.entryFiles = new Set(buildConfig.compileFiles as string[]); - this.cacheDir = buildConfig.cachePath as string; - this.pandaSdkPath = buildConfig.pandaSdkPath as string; - this.buildSdkPath = buildConfig.buildSdkPath as string; - this.packageName = buildConfig.packageName as string; - this.sourceRoots = buildConfig.sourceRoots as string[]; - this.moduleRootPath = buildConfig.moduleRootPath as string; - this.moduleType = buildConfig.moduleType as string; - this.dependentModuleList = buildConfig.dependentModuleList; - this.hasMainModule = buildConfig.hasMainModule; - - this.declgenV1OutPath = buildConfig.declgenV1OutPath as string | undefined; - this.declgenBridgeCodePath = buildConfig.declgenBridgeCodePath as string | undefined; - - this.moduleInfos = new Map(); - this.compileFiles = new Map(); - } - - private getDependentModules(moduleInfo: ModuleInfo): Map[] { - let dynamicDepModules: Map = new Map(); - let staticDepModules: Map = new Map(); - - if (moduleInfo.isMainModule) { - this.moduleInfos.forEach((module: ModuleInfo, packageName: string) => { - if (module.isMainModule) { - return; - } - module.language === LANGUAGE_VERSION.ARKTS_1_2 - ? staticDepModules.set(packageName, module) - : dynamicDepModules.set(packageName, module); - }); - return [dynamicDepModules, staticDepModules]; - } - - if (moduleInfo.dependencies) { - moduleInfo.dependencies.forEach((packageName: string) => { - let depModuleInfo: ModuleInfo | undefined = this.moduleInfos.get(packageName); - if (!depModuleInfo) { - console.error(`Module ${packageName} not found in moduleInfos`); - } else { - depModuleInfo.language === LANGUAGE_VERSION.ARKTS_1_2 - ? staticDepModules.set(packageName, depModuleInfo) - : dynamicDepModules.set(packageName, depModuleInfo); - } - }); - } - return [dynamicDepModules, staticDepModules]; - } - - private generateArkTSConfigForModules(compileFileInfos: Record): void { - let generator = ArkTSConfigGenerator.getGenerator(this.buildConfig, this.moduleInfos); - this.moduleInfos.forEach((moduleInfo: ModuleInfo, moduleRootPath: string) => { - for (const fileInfo of moduleInfo.compileFileInfos) { - compileFileInfos[fileInfo.filePath] = fileInfo.arktsConfigFile; - } - generator.writeArkTSConfigFile(moduleInfo); - }); - } - - private collectDepModuleInfos(): void { - this.moduleInfos.forEach((moduleInfo) => { - let [dynamicDepModules, staticDepModules] = this.getDependentModules(moduleInfo); - moduleInfo.dynamicDepModuleInfos = dynamicDepModules; - moduleInfo.staticDepModuleInfos = staticDepModules; - }); - } - - private collectModuleInfos(): void { - if (this.hasMainModule && (!this.packageName || !this.moduleRootPath || !this.sourceRoots)) { - console.error('Main module info from hvigor is not correct.'); - } - let mainModuleInfo: ModuleInfo = { - isMainModule: this.hasMainModule, - packageName: this.packageName, - moduleRootPath: this.moduleRootPath, - moduleType: this.moduleType, - sourceRoots: this.sourceRoots, - entryFile: '', - arktsConfigFile: path.resolve(this.cacheDir, this.packageName, ARKTSCONFIG_JSON_FILE), - dynamicDepModuleInfos: new Map(), - staticDepModuleInfos: new Map(), - compileFileInfos: [], - declgenV1OutPath: this.declgenV1OutPath, - declgenBridgeCodePath: this.declgenBridgeCodePath - }; - this.moduleInfos.set(this.packageName, mainModuleInfo); - this.dependentModuleList.forEach((module: DependentModuleConfig) => { - if (!module.packageName || !module.modulePath || !module.sourceRoots || !module.entryFile) { - console.error('Dependent module info from hvigor is not correct.'); - } - let moduleInfo: ModuleInfo = { - isMainModule: false, - packageName: module.packageName, - moduleRootPath: module.modulePath, - moduleType: module.moduleType, - sourceRoots: module.sourceRoots, - entryFile: module.entryFile, - arktsConfigFile: path.resolve(this.cacheDir, module.packageName, ARKTSCONFIG_JSON_FILE), - compileFileInfos: [], - dynamicDepModuleInfos: new Map(), - staticDepModuleInfos: new Map(), - declgenV1OutPath: undefined, - declgenBridgeCodePath: undefined, - language: module.language, - declFilesPath: module.declFilesPath, - dependencies: module.dependencies - }; - this.moduleInfos.set(module.packageName, moduleInfo); - }); - this.collectDepModuleInfos(); - } - - private collectCompileFiles(): void { - this.entryFiles.forEach((file: string) => { - for (const [packageName, moduleInfo] of this.moduleInfos) { - if (!file.startsWith(moduleInfo.moduleRootPath)) { - continue; - } - let filePathFromModuleRoot: string = path.relative(moduleInfo.moduleRootPath, file); - let filePathInCache: string = path.join(this.cacheDir, moduleInfo.packageName, filePathFromModuleRoot); - let abcFilePath: string = path.resolve(changeFileExtension(filePathInCache, ABC_SUFFIX)); - - let fileInfo: CompileFileInfo = { - filePath: file, - dependentFiles: [], - abcFilePath: abcFilePath, - arktsConfigFile: moduleInfo.arktsConfigFile, - packageName: moduleInfo.packageName - }; - moduleInfo.compileFileInfos.push(fileInfo); - this.compileFiles.set(file, fileInfo); - return; - } - console.error('File does not belong to any module in moduleInfos.'); - }); - } - - public generateModuleInfos(): void { - this.collectModuleInfos(); - this.collectCompileFiles(); - } - - public async generateArkTSConfig(compileFileInfos: Record): Promise { - this.generateModuleInfos(); - this.generateArkTSConfigForModules(compileFileInfos); - } -} diff --git a/ets2panda/bindings/src/Es2pandaNativeModule.ts b/ets2panda/bindings/src/common/Es2pandaNativeModule.ts similarity index 98% rename from ets2panda/bindings/src/Es2pandaNativeModule.ts rename to ets2panda/bindings/src/common/Es2pandaNativeModule.ts index fed3212068ed20047a871a21c53c228b75fd8556..4ab7d8329640d3f261948274c8db4907eb938d32 100644 --- a/ets2panda/bindings/src/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/common/Es2pandaNativeModule.ts @@ -24,7 +24,7 @@ import { KStringPtr, KInt32ArrayPtr } from './InteropTypes'; -import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from './generated/Es2pandaNativeModule'; +import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from '../generated/Es2pandaNativeModule'; import { loadNativeModuleLibrary, registerNativeModuleLibraryName } from './loadLibraries'; import { throwError } from './utils'; @@ -978,7 +978,7 @@ export class Es2pandaNativeModule { export function initEs2panda(): Es2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../ts_bindings.node'); + libPath = path.resolve(__dirname, '../../ts_bindings.node'); } else { libPath = path.join(libPath, 'ts_bindings.node'); } @@ -994,7 +994,7 @@ export function initEs2panda(): Es2pandaNativeModule { export function initGeneratedEs2panda(): GeneratedEs2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../ts_bindings.node'); + libPath = path.resolve(__dirname, '../../ts_bindings.node'); } else { libPath = path.join(libPath, 'ts_bindings.node'); } @@ -1010,7 +1010,7 @@ export function initGeneratedEs2panda(): GeneratedEs2pandaNativeModule { export function initPublicEs2panda(): Es2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../public.node'); + libPath = path.resolve(__dirname, '../../public.node'); } else { libPath = path.join(libPath, 'public.node'); } @@ -1026,7 +1026,7 @@ export function initPublicEs2panda(): Es2pandaNativeModule { export function initPublicGeneratedEs2panda(): GeneratedEs2pandaNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../public.node'); + libPath = path.resolve(__dirname, '../../public.node'); } else { libPath = path.join(libPath, 'public.node'); } diff --git a/ets2panda/bindings/src/InteropNativeModule.ts b/ets2panda/bindings/src/common/InteropNativeModule.ts similarity index 95% rename from ets2panda/bindings/src/InteropNativeModule.ts rename to ets2panda/bindings/src/common/InteropNativeModule.ts index 35eac9b80641b233c9e1c5e4add9fb2f7d995224..fcc82a57ebd647d95e660ab6b75c63fa29074b72 100644 --- a/ets2panda/bindings/src/InteropNativeModule.ts +++ b/ets2panda/bindings/src/common/InteropNativeModule.ts @@ -60,7 +60,7 @@ export class InteropNativeModule { export function initInterop(): InteropNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../ts_bindings.node'); + libPath = path.resolve(__dirname, '../../ts_bindings.node'); } else { libPath = path.join(libPath, 'ts_bindings.node'); } @@ -76,7 +76,7 @@ export function initInterop(): InteropNativeModule { export function initPublicInterop(): InteropNativeModule { let libPath = process.env.BINDINGS_PATH; if (libPath === undefined) { - libPath = path.resolve(__dirname, '../public.node'); + libPath = path.resolve(__dirname, '../../public.node'); } else { libPath = path.join(libPath, 'public.node'); } diff --git a/ets2panda/bindings/src/InteropTypes.ts b/ets2panda/bindings/src/common/InteropTypes.ts similarity index 100% rename from ets2panda/bindings/src/InteropTypes.ts rename to ets2panda/bindings/src/common/InteropTypes.ts diff --git a/ets2panda/bindings/src/Platform.ts b/ets2panda/bindings/src/common/Platform.ts similarity index 100% rename from ets2panda/bindings/src/Platform.ts rename to ets2panda/bindings/src/common/Platform.ts diff --git a/ets2panda/bindings/src/Wrapper.ts b/ets2panda/bindings/src/common/Wrapper.ts similarity index 100% rename from ets2panda/bindings/src/Wrapper.ts rename to ets2panda/bindings/src/common/Wrapper.ts diff --git a/ets2panda/bindings/src/build/generateArkTSConfig.ts b/ets2panda/bindings/src/common/arkTSConfigGenerator.ts similarity index 71% rename from ets2panda/bindings/src/build/generateArkTSConfig.ts rename to ets2panda/bindings/src/common/arkTSConfigGenerator.ts index 2197374fdff417064431a5cd0718f51761d929e2..5b2a1ee5f9b999b9ebe4a6ba658caaf301ddb078 100644 --- a/ets2panda/bindings/src/build/generateArkTSConfig.ts +++ b/ets2panda/bindings/src/common/arkTSConfigGenerator.ts @@ -16,9 +16,9 @@ import * as path from 'path'; import * as fs from 'fs'; -import { changeFileExtension, ensurePathExists } from '../utils'; -import { BuildConfig, ModuleInfo } from '../types'; -import { LANGUAGE_VERSION, SYSTEM_SDK_PATH_FROM_SDK } from '../preDefine'; +import { changeFileExtension, ensurePathExists } from './utils'; +import { BuildConfig, ModuleInfo } from './types'; +import { LANGUAGE_VERSION, PANDA_SDK_PATH_FROM_SDK, SYSTEM_SDK_PATH_FROM_SDK } from './preDefine'; interface DependencyItem { language: string; @@ -41,22 +41,24 @@ export class ArkTSConfigGenerator { private stdlibStdPath: string; private stdlibEscompatPath: string; private systemSdkPath: string; + private externalApiPath: string; - private moduleInfos: Map; + private moduleInfos: Record; private pathSection: Record; - private constructor(buildConfig: BuildConfig, moduleInfos: Map) { - let pandaStdlibPath: string = - buildConfig.pandaStdlibPath ?? path.resolve(buildConfig.pandaSdkPath!!, 'lib', 'stdlib'); + private constructor(buildConfig: BuildConfig, moduleInfos: Record) { + let pandaSdkPath = path.resolve(buildConfig.buildSdkPath, PANDA_SDK_PATH_FROM_SDK); + let pandaStdlibPath: string = path.resolve(pandaSdkPath, 'lib', 'stdlib'); this.stdlibStdPath = path.resolve(pandaStdlibPath, 'std'); this.stdlibEscompatPath = path.resolve(pandaStdlibPath, 'escompat'); this.systemSdkPath = path.resolve(buildConfig.buildSdkPath, SYSTEM_SDK_PATH_FROM_SDK); + this.externalApiPath = buildConfig.externalApiPath !== undefined ? buildConfig.externalApiPath : ''; this.moduleInfos = moduleInfos; this.pathSection = {}; } - public static getInstance(buildConfig?: BuildConfig, moduleInfos?: Map): ArkTSConfigGenerator { + public static getInstance(buildConfig?: BuildConfig, moduleInfos?: Record): ArkTSConfigGenerator { if (!ArkTSConfigGenerator.instance) { if (!buildConfig || !moduleInfos) { throw new Error('buildConfig and moduleInfos is required for the first instantiation of ArkTSConfigGenerator.'); @@ -66,7 +68,7 @@ export class ArkTSConfigGenerator { return ArkTSConfigGenerator.instance; } - public static getGenerator(buildConfig: BuildConfig, moduleInfos: Map): ArkTSConfigGenerator { + public static getGenerator(buildConfig: BuildConfig, moduleInfos: Record): ArkTSConfigGenerator { return new ArkTSConfigGenerator(buildConfig, moduleInfos); } @@ -75,11 +77,20 @@ export class ArkTSConfigGenerator { } private generateSystemSdkPathSection(pathSection: Record): void { - function traverse(currentDir: string, relativePath: string = '', isExcludedDir: boolean = false): void { + function traverse( + currentDir: string, + relativePath: string = '', + isExcludedDir: boolean = false, + allowedExtensions: string[] = ['.d.ets'] + ): void { const items = fs.readdirSync(currentDir); for (const item of items) { const itemPath = path.join(currentDir, item); const stat = fs.statSync(itemPath); + const isAllowedFile = allowedExtensions.some((ext) => item.endsWith(ext)); + if (stat.isFile() && !isAllowedFile) { + continue; + } if (stat.isFile()) { const basename = path.basename(item, '.d.ets'); @@ -87,9 +98,9 @@ export class ArkTSConfigGenerator { pathSection[key] = [changeFileExtension(itemPath, '', '.d.ets')]; } if (stat.isDirectory()) { - // For non-arkui files under api dir, + // For files under api dir excluding arkui/runtime-api dir, // fill path section with `"pathFromApi.subdir.fileName" = [${absolute_path_to_file}]`; - // For arkui files under api dir, + // For @koalaui files under arkui/runtime-api dir, // fill path section with `"fileName" = [${absolute_path_to_file}]`. const isCurrentDirExcluded = path.basename(currentDir) === 'arkui' && item === 'runtime-api'; const newRelativePath = isCurrentDirExcluded ? '' : relativePath ? `${relativePath}.${item}` : item; @@ -98,17 +109,18 @@ export class ArkTSConfigGenerator { } } - let apiPath: string = path.resolve(this.systemSdkPath, 'api'); - fs.existsSync(apiPath) ? traverse(apiPath) : console.error(`sdk path ${apiPath} not exist.`); - - let arktsPath: string = path.resolve(this.systemSdkPath, 'arkts'); - fs.existsSync(arktsPath) ? traverse(arktsPath) : console.error(`sdk path ${arktsPath} not exist.`); - - let kitsPath: string = path.resolve(this.systemSdkPath, 'kits'); - fs.existsSync(kitsPath) ? traverse(kitsPath) : console.error(`sdk path ${kitsPath} not exist.`); + let directoryNames: string[] = ['api', 'arkts', 'kits']; + directoryNames.forEach((dir) => { + let systemSdkPath = path.resolve(this.systemSdkPath, dir); + let externalApiPath = path.resolve(this.externalApiPath, dir); + fs.existsSync(systemSdkPath) ? traverse(systemSdkPath) : console.warn(`sdk path ${systemSdkPath} not exist.`); + fs.existsSync(externalApiPath) + ? traverse(externalApiPath) + : console.warn(`sdk path ${externalApiPath} not exist.`); + }); } - private getPathSection(): Record { + private getPathSection(moduleInfo: ModuleInfo): Record { if (Object.keys(this.pathSection).length !== 0) { return this.pathSection; } @@ -118,10 +130,9 @@ export class ArkTSConfigGenerator { this.generateSystemSdkPathSection(this.pathSection); - this.moduleInfos.forEach((moduleInfo: ModuleInfo, packageName: string) => { - if (moduleInfo.language === LANGUAGE_VERSION.ARKTS_1_2) { - this.pathSection[moduleInfo.packageName] = [path.resolve(moduleInfo.moduleRootPath, moduleInfo.sourceRoots[0])]; - } + Object.values(moduleInfo.staticDepModuleInfos).forEach((depModuleName: string) => { + let depModuleInfo = this.moduleInfos[depModuleName]; + this.pathSection[depModuleInfo.packageName] = [path.resolve(depModuleInfo.moduleRootPath)]; }); return this.pathSection; @@ -134,9 +145,9 @@ export class ArkTSConfigGenerator { } private getDependenciesSection(moduleInfo: ModuleInfo, dependencySection: Record): void { - let depModules: Map = moduleInfo.dynamicDepModuleInfos; - - depModules.forEach((depModuleInfo: ModuleInfo) => { + let depModules: string[] = moduleInfo.dynamicDepModuleInfos; + depModules.forEach((depModuleName: string) => { + let depModuleInfo = this.moduleInfos[depModuleName]; if (!depModuleInfo.declFilesPath || !fs.existsSync(depModuleInfo.declFilesPath)) { console.error(`Module ${moduleInfo.packageName} depends on dynamic module ${depModuleInfo.packageName}, but decl file not found on path ${depModuleInfo.declFilesPath}`); @@ -161,14 +172,11 @@ export class ArkTSConfigGenerator { } public writeArkTSConfigFile(moduleInfo: ModuleInfo): void { - if (!moduleInfo.sourceRoots || moduleInfo.sourceRoots.length === 0) { - console.error('SourceRoots not set from hvigor.'); - } - let pathSection = this.getPathSection(); + let pathSection = this.getPathSection(moduleInfo); let dependencySection: Record = {}; this.getDependenciesSection(moduleInfo, dependencySection); - let baseUrl: string = path.resolve(moduleInfo.moduleRootPath, moduleInfo.sourceRoots[0]); + let baseUrl: string = path.resolve(moduleInfo.moduleRootPath); let arktsConfig: ArkTSConfigObject = { compilerOptions: { package: moduleInfo.packageName, diff --git a/ets2panda/bindings/src/arrays.ts b/ets2panda/bindings/src/common/arrays.ts similarity index 100% rename from ets2panda/bindings/src/arrays.ts rename to ets2panda/bindings/src/common/arrays.ts diff --git a/ets2panda/bindings/src/driver_helper.ts b/ets2panda/bindings/src/common/driver_helper.ts similarity index 98% rename from ets2panda/bindings/src/driver_helper.ts rename to ets2panda/bindings/src/common/driver_helper.ts index ad435334f1b732a3e5cfac1fe315d4355957e2ea..4bd68da844cfb88951afb8fa9b857efc8856deeb 100644 --- a/ets2panda/bindings/src/driver_helper.ts +++ b/ets2panda/bindings/src/common/driver_helper.ts @@ -16,7 +16,7 @@ import { Context, Config } from './types'; import { global } from './global'; import { throwError } from './utils'; -import { Es2pandaContextState } from './generated/Es2pandaEnums'; +import { Es2pandaContextState } from '../generated/Es2pandaEnums'; import { withStringResult } from './Platform'; import { KBoolean, KInt, KNativePointer, KPointer } from './InteropTypes'; import { passStringArray } from './private'; diff --git a/ets2panda/bindings/src/global.ts b/ets2panda/bindings/src/common/global.ts similarity index 98% rename from ets2panda/bindings/src/global.ts rename to ets2panda/bindings/src/common/global.ts index fcb066888cc390f65795662315931f95b9aafb40..b6841d5e5fb6dd6ecd41df67f522238b72bdc3ce 100644 --- a/ets2panda/bindings/src/global.ts +++ b/ets2panda/bindings/src/common/global.ts @@ -22,7 +22,7 @@ import { initPublicEs2panda, initPublicGeneratedEs2panda } from './Es2pandaNativeModule'; -import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from './generated/Es2pandaNativeModule'; +import { Es2pandaNativeModule as GeneratedEs2pandaNativeModule } from '../generated/Es2pandaNativeModule'; import { initInterop, InteropNativeModule, initPublicInterop } from './InteropNativeModule'; // CC-OFFNXT(G.NAM.01) project code style diff --git a/ets2panda/bindings/src/loadLibraries.ts b/ets2panda/bindings/src/common/loadLibraries.ts similarity index 100% rename from ets2panda/bindings/src/loadLibraries.ts rename to ets2panda/bindings/src/common/loadLibraries.ts diff --git a/ets2panda/bindings/src/mainWrapper.ts b/ets2panda/bindings/src/common/mainWrapper.ts similarity index 100% rename from ets2panda/bindings/src/mainWrapper.ts rename to ets2panda/bindings/src/common/mainWrapper.ts diff --git a/ets2panda/bindings/src/preDefine.ts b/ets2panda/bindings/src/common/preDefine.ts similarity index 87% rename from ets2panda/bindings/src/preDefine.ts rename to ets2panda/bindings/src/common/preDefine.ts index 392cee9a94bbbb1f5a477952e66869afac92204f..0de1510a8f34aa704a76e10152b60582694c7459 100644 --- a/ets2panda/bindings/src/preDefine.ts +++ b/ets2panda/bindings/src/common/preDefine.ts @@ -15,8 +15,6 @@ export const ARKTSCONFIG_JSON_FILE: string = 'arktsconfig.json'; -export const ABC_SUFFIX: string = '.abc'; - export enum LANGUAGE_VERSION { ARKTS_1_2 = '1.2', ARKTS_1_1 = '1.1', @@ -26,3 +24,5 @@ export enum LANGUAGE_VERSION { export const DECL_ETS_SUFFIX: string = '.d.ets'; export const PANDA_SDK_PATH_FROM_SDK: string = './build-tools/ets2panda'; export const SYSTEM_SDK_PATH_FROM_SDK: string = './'; +export const EXTERNAL_API_PATH_FROM_SDK: string = '../../../hms/ets/ets1.2'; +export const DEFAULT_CACHE_DIR: string = './.idea/.deveco'; diff --git a/ets2panda/bindings/src/private.ts b/ets2panda/bindings/src/common/private.ts similarity index 97% rename from ets2panda/bindings/src/private.ts rename to ets2panda/bindings/src/common/private.ts index df50a1f914699f92dccfeaa31ba1256a7041425f..3ad06d3be69edede57a0f02e5bcbaafbca66c6b8 100644 --- a/ets2panda/bindings/src/private.ts +++ b/ets2panda/bindings/src/common/private.ts @@ -17,7 +17,7 @@ import { throwError } from './utils'; import { KNativePointer, nullptr } from './InteropTypes'; import { withString, withStringArray, withBigingArray } from './arrays'; import { NativePtrDecoder, withStringResult } from './Platform'; -import { LspDiagsNode, LspNode } from './lspNode'; +import { LspDiagsNode, LspNode } from '../lsp/lspNode'; export function lspData(peer: KNativePointer): LspNode { return new LspDiagsNode(peer); diff --git a/ets2panda/bindings/src/strings.ts b/ets2panda/bindings/src/common/strings.ts similarity index 100% rename from ets2panda/bindings/src/strings.ts rename to ets2panda/bindings/src/common/strings.ts diff --git a/ets2panda/bindings/src/ts-reflection.ts b/ets2panda/bindings/src/common/ts-reflection.ts similarity index 100% rename from ets2panda/bindings/src/ts-reflection.ts rename to ets2panda/bindings/src/common/ts-reflection.ts diff --git a/ets2panda/bindings/src/types.ts b/ets2panda/bindings/src/common/types.ts similarity index 80% rename from ets2panda/bindings/src/types.ts rename to ets2panda/bindings/src/common/types.ts index ef956f40bf59c6ff70f8c7e172ac6a6574d098b1..c8bc63bb52f1c5d0818dce52e2f8b8cc90d89b64 100644 --- a/ets2panda/bindings/src/types.ts +++ b/ets2panda/bindings/src/common/types.ts @@ -136,30 +136,21 @@ export interface PluginsConfig { [pluginName: string]: string; } -export interface BuildBaseConfig { - buildType: 'build' | 'preview' | 'hotreload' | 'coldreload'; - buildMode: 'Debug' | 'Release'; - hasMainModule: boolean; - arkts: object; - arktsGlobal: object; -} - export interface ModuleConfig { packageName: string; moduleType: string; moduleRootPath: string; - sourceRoots: string[]; + language: string; + declFilesPath?: string; + dependencies?: string[]; } export interface PathConfig { - loaderOutPath: string; - declgenDtsOutPath: string; - declgenTsOutPath: string; - cachePath: string; buildSdkPath: string; - pandaSdkPath?: string; // path to panda sdk lib/bin, for local test - pandaStdlibPath?: string; // path to panda sdk stdlib, for local test - abcLinkerPath?: string; + projectPath: string; + declgenOutDir: string; + cacheDir?: string; + externalApiPath?: string; } export interface DeclgenConfig { @@ -168,52 +159,25 @@ export interface DeclgenConfig { declgenBridgeCodePath?: string; } -export interface LoggerConfig { - getHvigorConsoleLogger?: Function; -} - -export interface DependentModuleConfig { - packageName: string; - moduleName: string; - moduleType: string; - modulePath: string; - sourceRoots: string[]; - entryFile: string; - language: string; - declFilesPath?: string; - dependencies?: string[]; -} - -export interface BuildConfig extends BuildBaseConfig, DeclgenConfig, LoggerConfig, ModuleConfig, PathConfig { +export interface BuildConfig extends DeclgenConfig, ModuleConfig, PathConfig { plugins: PluginsConfig; compileFiles: string[]; - dependentModuleList: DependentModuleConfig[]; } // ProjectConfig ends -export interface CompileFileInfo { - filePath: string; - dependentFiles: string[]; - abcFilePath: string; - arktsConfigFile: string; - packageName: string; -} - export interface ModuleInfo { - isMainModule: boolean; packageName: string; moduleRootPath: string; moduleType: string; - sourceRoots: string[]; entryFile: string; arktsConfigFile: string; - compileFileInfos: CompileFileInfo[]; + compileFiles: string[]; declgenV1OutPath: string | undefined; declgenBridgeCodePath: string | undefined; + staticDepModuleInfos: string[]; + dynamicDepModuleInfos: string[]; + language: string; dependencies?: string[]; - staticDepModuleInfos: Map; - dynamicDepModuleInfos: Map; - language?: string; declFilesPath?: string; } @@ -245,3 +209,9 @@ export interface WorkerInfo { worker: ThreadWorker; isIdle: boolean; } +export interface TextDocumentChangeInfo { + newDoc: string; + rangeStart?: number; + rangeEnd?: number; + updateText?: string; +} diff --git a/ets2panda/bindings/src/ui_plugins_driver.ts b/ets2panda/bindings/src/common/ui_plugins_driver.ts similarity index 100% rename from ets2panda/bindings/src/ui_plugins_driver.ts rename to ets2panda/bindings/src/common/ui_plugins_driver.ts diff --git a/ets2panda/bindings/src/utils.ts b/ets2panda/bindings/src/common/utils.ts similarity index 100% rename from ets2panda/bindings/src/utils.ts rename to ets2panda/bindings/src/common/utils.ts diff --git a/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts b/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts index 8bd49b74b2f0d7c05b5b93ba613015467b5282c1..bb53f1d512a49c81af2aaf9a797748ea9f96f4d7 100644 --- a/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts +++ b/ets2panda/bindings/src/generated/Es2pandaNativeModule.ts @@ -13,7 +13,7 @@ * limitations under the License. */ -import { KBoolean, KInt, KNativePointer } from '../InteropTypes'; +import { KBoolean, KInt, KNativePointer } from '../common/InteropTypes'; export class Es2pandaNativeModule { _CreateMemberExpression( diff --git a/ets2panda/bindings/src/index.ts b/ets2panda/bindings/src/index.ts index 7f572287111d7951aa275ad6f477cfece9b7cc24..d508b948c88a327860440a69dc67f46dfc34172e 100644 --- a/ets2panda/bindings/src/index.ts +++ b/ets2panda/bindings/src/index.ts @@ -13,19 +13,4 @@ * limitations under the License. */ -export { Lsp } from './lsp_helper'; -export { DriverHelper } from './driver_helper'; -export { Es2pandaContextState } from './generated/Es2pandaEnums'; -export { - LspCompletionInfo, - LspCompletionEntryKind, - LspDefinitionData, - LspDiagsNode, - LspDiagnosticNode, - LspDiagSeverity, - LspQuickInfo, - LspSymbolDisplayPart -} from './lspNode'; -export { generateArkTsConfigByModules } from './arktsConfigGenerate'; -export type { ModuleDescriptor } from './buildConfigGenerate'; -export type { TextDocumentChangeInfo } from './lsp_helper'; +export * from './lsp/index'; diff --git a/ets2panda/bindings/src/compile_thread_worker.ts b/ets2panda/bindings/src/lsp/compile_thread_worker.ts similarity index 86% rename from ets2panda/bindings/src/compile_thread_worker.ts rename to ets2panda/bindings/src/lsp/compile_thread_worker.ts index 9c2878deb0583d15b6b704c7642207c02dcb016b..14cdbd600444e40a33e91fe7a298586216cdaa7f 100644 --- a/ets2panda/bindings/src/compile_thread_worker.ts +++ b/ets2panda/bindings/src/lsp/compile_thread_worker.ts @@ -15,10 +15,10 @@ import { parentPort, workerData } from 'worker_threads'; import * as fs from 'fs'; -import { PluginDriver, PluginHook } from './ui_plugins_driver'; -import { LspDriverHelper } from './driver_helper'; -import { Es2pandaContextState } from './generated/Es2pandaEnums'; -import { JobInfo } from './types'; +import { PluginDriver, PluginHook } from '../common/ui_plugins_driver'; +import { LspDriverHelper } from '../common/driver_helper'; +import { Es2pandaContextState } from '../generated/Es2pandaEnums'; +import { JobInfo } from '../common/types'; const { workerId } = workerData; @@ -27,6 +27,9 @@ function compileExternalProgram(jobInfo: JobInfo): void { let ets2pandaCmd = ['-', '--extension', 'ets', '--arktsconfig', jobInfo.arktsConfigFile]; let lspDriverHelper = new LspDriverHelper(); let config = lspDriverHelper.createCfg(ets2pandaCmd, jobInfo.filePath); + if (!fs.existsSync(jobInfo.filePath)) { + return; + } const source = fs.readFileSync(jobInfo.filePath, 'utf8').replace(/\r\n/g, '\n'); let context = lspDriverHelper.createCtx(source, jobInfo.filePath, config, jobInfo.globalContextPtr, true); PluginDriver.getInstance().getPluginContext().setContextPtr(context); diff --git a/ets2panda/bindings/src/lsp/generateArkTSConfig.ts b/ets2panda/bindings/src/lsp/generateArkTSConfig.ts new file mode 100644 index 0000000000000000000000000000000000000000..fae5a16029d155265c52a0df422300ce6b748559 --- /dev/null +++ b/ets2panda/bindings/src/lsp/generateArkTSConfig.ts @@ -0,0 +1,84 @@ +/* + * 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 * as path from 'path'; + +import { ARKTSCONFIG_JSON_FILE, LANGUAGE_VERSION } from '../common/preDefine'; +import { BuildConfig, ModuleInfo } from '../common/types'; +import { ArkTSConfigGenerator } from '../common/arkTSConfigGenerator'; + +function collectDepModuleInfos(moduleInfo: ModuleInfo, allBuildConfig: Record): void { + let dynamicDepModules: string[] = []; + let staticDepModules: string[] = []; + + if (moduleInfo.dependencies) { + moduleInfo.dependencies.forEach((moduleName: string) => { + let depModule = allBuildConfig[moduleName]; + depModule.language === LANGUAGE_VERSION.ARKTS_1_2 + ? staticDepModules.push(depModule.packageName) + : dynamicDepModules.push(depModule.packageName); + }); + } + moduleInfo.dynamicDepModuleInfos = dynamicDepModules; + moduleInfo.staticDepModuleInfos = staticDepModules; +} + +function collectModuleInfos(allBuildConfig: Record): Record { + let moduleInfos: Record = {}; + Object.values(allBuildConfig).forEach((buildConfig) => { + let moduleInfo = generateModuleInfo(allBuildConfig, buildConfig); + moduleInfos[moduleInfo.packageName] = moduleInfo; + }); + return moduleInfos; +} + +export function generateModuleInfo(allBuildConfig: Record, buildConfig: BuildConfig): ModuleInfo { + if (!buildConfig.packageName || !buildConfig.moduleRootPath) { + console.error('Main buildConfig info from hvigor is not correct.'); + } + let moduleInfo: ModuleInfo = { + packageName: buildConfig.packageName, + moduleRootPath: buildConfig.moduleRootPath, + moduleType: buildConfig.moduleType, + entryFile: buildConfig.packageName !== 'entry' ? path.join(buildConfig.moduleRootPath, 'Index.ets') : '', + arktsConfigFile: path.resolve(buildConfig.cacheDir!, buildConfig.packageName, ARKTSCONFIG_JSON_FILE), + compileFiles: buildConfig.compileFiles, + declgenV1OutPath: buildConfig.declgenV1OutPath, + declgenBridgeCodePath: buildConfig.declgenBridgeCodePath, + staticDepModuleInfos: [], + dynamicDepModuleInfos: [], + language: buildConfig.language, + dependencies: buildConfig.dependencies, + declFilesPath: buildConfig.declFilesPath + }; + collectDepModuleInfos(moduleInfo, allBuildConfig); + return moduleInfo; +} + +export function generateArkTsConfigs(allBuildConfig: Record): Record { + let moduleInfos: Record = collectModuleInfos(allBuildConfig); + Object.keys(moduleInfos).forEach((filePath: string) => { + let packageName = moduleInfos[filePath].packageName; + let generator = ArkTSConfigGenerator.getGenerator(allBuildConfig[packageName], moduleInfos); + generator.writeArkTSConfigFile(moduleInfos[filePath]); + }); + let fileToModuleInfo: Record = {}; + Object.values(moduleInfos).forEach((moduleInfo: ModuleInfo) => { + moduleInfo.compileFiles.forEach((file: string) => { + fileToModuleInfo[file] = moduleInfo; + }); + }); + return fileToModuleInfo; +} diff --git a/ets2panda/bindings/src/buildConfigGenerate.ts b/ets2panda/bindings/src/lsp/generateBuildConfig.ts similarity index 71% rename from ets2panda/bindings/src/buildConfigGenerate.ts rename to ets2panda/bindings/src/lsp/generateBuildConfig.ts index 478196c6aaaa569ab9b798c8eca2cc9879a506f8..88206a3e5ffb1b254894443e9fcb7495bac34fe7 100644 --- a/ets2panda/bindings/src/buildConfigGenerate.ts +++ b/ets2panda/bindings/src/lsp/generateBuildConfig.ts @@ -16,7 +16,8 @@ import * as fs from 'fs'; import * as path from 'path'; import * as JSON5 from 'json5'; -import { BuildConfig } from './types'; +import { BuildConfig, PathConfig } from '../common/types'; +import { DEFAULT_CACHE_DIR, EXTERNAL_API_PATH_FROM_SDK } from '../common/preDefine'; export interface ModuleDescriptor { arktsversion: string; @@ -92,9 +93,8 @@ function getEtsFiles(modulePath: string): string[] { const files: string[] = []; const shouldSkipDirectory = (relativePath: string): boolean => { - const testDir1 = `src${path.sep}test`; - const testDir2 = `src${path.sep}ohosTest`; - return relativePath.startsWith(testDir1) || relativePath.startsWith(testDir2); + const filterList = [`src${path.sep}test`, `src${path.sep}ohosTest`, `build${path.sep}`, `oh_modules${path.sep}`]; + return filterList.some((directoryPrefix: string) => relativePath.startsWith(directoryPrefix)); }; const processEntry = (dir: string, entry: fs.Dirent): void => { @@ -150,15 +150,8 @@ function getModuleDependencies(modulePath: string, visited = new Set()): } }; - const resolveNestedDependencies = (deps: string[]): string[] => { - return deps.flatMap((depPath) => - visited.has(depPath) ? [] : [depPath, ...getModuleDependencies(depPath, visited)] - ); - }; - const dependencies = extractDependencies(); - const nestedDependencies = resolveNestedDependencies(dependencies); - return Array.from(new Set([...dependencies, ...nestedDependencies])); + return Array.from(new Set([...dependencies])); } function createMapEntryForPlugin(buildSdkPath: string, pluginName: string): string { @@ -175,67 +168,73 @@ function createPluginMap(buildSdkPath: string): Record { } export function generateBuildConfigs( - buildSdkPath: string, - projectRoot: string, + pathConfig: PathConfig, modules?: ModuleDescriptor[] ): Record { const allBuildConfigs: Record = {}; if (!modules) { - const buildProfilePath = path.join(projectRoot, 'build-profile.json5'); + const buildProfilePath = path.join(pathConfig.projectPath, 'build-profile.json5'); modules = getModulesFromBuildProfile(buildProfilePath); } const definedModules = modules; - const cacheDir = path.join(projectRoot, '.idea', '.deveco'); + + const enableDeclgen: Map = new Map(modules.map((module) => [module.name, false])); for (const module of definedModules) { const modulePath = module.srcPath; const compileFiles = new Set(getEtsFiles(modulePath)); - const pluginMap = createPluginMap(buildSdkPath); + const pluginMap = createPluginMap(pathConfig.buildSdkPath); // Get recursive dependencies const dependencies = getModuleDependencies(modulePath); for (const depPath of dependencies) { getEtsFiles(depPath).forEach((file) => compileFiles.add(file)); + const depModule = definedModules.find((m) => m.srcPath === depPath); + if (module.arktsversion === '1.1' && depModule?.arktsversion === '1.2') { + enableDeclgen.set(depModule.name, true); + } } allBuildConfigs[module.name] = { plugins: pluginMap, - arkts: {}, - arktsGlobal: {}, compileFiles: Array.from(compileFiles), packageName: module.name, moduleType: module.moduleType, - buildType: 'build', - buildMode: 'Debug', moduleRootPath: modulePath, - sourceRoots: ['./'], - hasMainModule: true, - loaderOutPath: path.join(modulePath, 'build', 'default', 'cache'), - cachePath: cacheDir, - buildSdkPath: buildSdkPath, + language: module.arktsversion, + buildSdkPath: pathConfig.buildSdkPath, + projectPath: pathConfig.projectPath, + declgenOutDir: pathConfig.declgenOutDir, + externalApiPath: pathConfig.externalApiPath + ? pathConfig.externalApiPath + : path.resolve(pathConfig.buildSdkPath, EXTERNAL_API_PATH_FROM_SDK), + cacheDir: + pathConfig.cacheDir !== undefined ? pathConfig.cacheDir : path.join(pathConfig.projectPath, DEFAULT_CACHE_DIR), enableDeclgenEts2Ts: false, - declgenDtsOutPath: path.join(modulePath, 'build', 'default', 'cache'), - declgenTsOutPath: path.join(modulePath, 'build', 'default', 'cache'), - dependentModuleList: dependencies.map((dep) => { + declFilesPath: + module.arktsversion === '1.1' + ? path.join(pathConfig.declgenOutDir, 'static', module.name, 'decl-fileInfo.json') + : undefined, + dependencies: dependencies.map((dep) => { const depModule = definedModules.find((m) => m.srcPath === dep); - return { - packageName: path.basename(dep), - moduleName: path.basename(dep), - moduleType: depModule ? depModule.moduleType : 'har', - modulePath: dep, - sourceRoots: ['./'], - entryFile: 'index.ets', - language: depModule ? depModule.arktsversion : '1.1' - }; + return depModule!.name; }) }; } - const outputPath = path.join(cacheDir, 'lsp_build_config.json'); - if (!fs.existsSync(cacheDir)) { - fs.mkdirSync(cacheDir, { recursive: true }); - } - fs.writeFileSync(outputPath, JSON.stringify(allBuildConfigs, null, 4)); + Object.entries(allBuildConfigs).forEach(([key, config]) => { + if (enableDeclgen.get(key) === true) { + config.enableDeclgenEts2Ts = true; + config.declgenV1OutPath = path.join(pathConfig.declgenOutDir, 'dynamic', key, 'declgenV1'); + config.declgenBridgeCodePath = path.join(pathConfig.declgenOutDir, 'dynamic', key, 'declgenBridgeCode'); + if (!fs.existsSync(config.declgenV1OutPath)) { + fs.mkdirSync(config.declgenV1OutPath, { recursive: true }); + } + if (!fs.existsSync(config.declgenBridgeCodePath)) { + fs.mkdirSync(config.declgenBridgeCodePath, { recursive: true }); + } + } + }); return allBuildConfigs; } diff --git a/ets2panda/bindings/src/lsp/index.ts b/ets2panda/bindings/src/lsp/index.ts new file mode 100644 index 0000000000000000000000000000000000000000..effe67f08670ee67f0bfb3e486fd3060c32c7470 --- /dev/null +++ b/ets2panda/bindings/src/lsp/index.ts @@ -0,0 +1,29 @@ +/* + * 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. + */ + +export { Lsp } from './lsp_helper'; +export { Es2pandaContextState } from '../generated/Es2pandaEnums'; +export { + LspCompletionInfo, + LspCompletionEntryKind, + LspDefinitionData, + LspDiagsNode, + LspDiagnosticNode, + LspDiagSeverity, + LspQuickInfo, + LspSymbolDisplayPart +} from './lspNode'; +export type { ModuleDescriptor } from './generateBuildConfig'; +export type { PathConfig, TextDocumentChangeInfo } from '../common/types'; diff --git a/ets2panda/bindings/src/lspNode.ts b/ets2panda/bindings/src/lsp/lspNode.ts similarity index 99% rename from ets2panda/bindings/src/lspNode.ts rename to ets2panda/bindings/src/lsp/lspNode.ts index f4cdf5092ef05164c721ef039acb34ea393f8778..492350d708ede2822d13b30c4aa46f007edb110b 100644 --- a/ets2panda/bindings/src/lspNode.ts +++ b/ets2panda/bindings/src/lsp/lspNode.ts @@ -13,12 +13,12 @@ * limitations under the License. */ -import { KBoolean, KInt, KNativePointer, KUInt } from './InteropTypes'; -import { unpackString, VariantTypes } from './private'; -import { throwError } from './utils'; -import { isNullPtr } from './Wrapper'; -import { global } from './global'; -import { NativePtrDecoder } from './Platform'; +import { KBoolean, KInt, KNativePointer, KUInt } from '../common/InteropTypes'; +import { unpackString, VariantTypes } from '../common/private'; +import { throwError } from '../common/utils'; +import { isNullPtr } from '../common/Wrapper'; +import { global } from '../common/global'; +import { NativePtrDecoder } from '../common/Platform'; enum HierarchyType { OTHERS, diff --git a/ets2panda/bindings/src/lsp_helper.ts b/ets2panda/bindings/src/lsp/lsp_helper.ts similarity index 89% rename from ets2panda/bindings/src/lsp_helper.ts rename to ets2panda/bindings/src/lsp/lsp_helper.ts index aba1bcdaaf3fde21bd5da01f07ca3f0dad5104be..8500c1a2012e78608b849c1827e77a182a02de88 100644 --- a/ets2panda/bindings/src/lsp_helper.ts +++ b/ets2panda/bindings/src/lsp/lsp_helper.ts @@ -13,8 +13,8 @@ * limitations under the License. */ -import { LspDriverHelper } from './driver_helper'; -import { global } from './global'; +import { LspDriverHelper } from '../common/driver_helper'; +import { global } from '../common/global'; import { LspDefinitionData, LspDiagsNode, @@ -49,22 +49,32 @@ import { LspRenameInfoSuccess, LspRenameInfoFailure } from './lspNode'; -import { passStringArray, unpackString } from './private'; -import { Es2pandaContextState } from './generated/Es2pandaEnums'; -import { BuildConfig, Config, FileDepsInfo, Job, JobInfo, WorkerInfo } from './types'; -import { PluginDriver, PluginHook } from './ui_plugins_driver'; -import { ModuleDescriptor } from './buildConfigGenerate'; -import { generateArkTsConfigByModules } from './arktsConfigGenerate'; +import { passStringArray, unpackString } from '../common/private'; +import { Es2pandaContextState } from '../generated/Es2pandaEnums'; +import { + BuildConfig, + Config, + FileDepsInfo, + Job, + JobInfo, + WorkerInfo, + ModuleInfo, + PathConfig, + TextDocumentChangeInfo +} from '../common/types'; +import { PluginDriver, PluginHook } from '../common/ui_plugins_driver'; +import { ModuleDescriptor, generateBuildConfigs } from './generateBuildConfig'; +import { generateArkTsConfigs, generateModuleInfo } from './generateArkTSConfig'; import * as fs from 'fs'; import * as path from 'path'; -import { KNativePointer, KPointer } from './InteropTypes'; -import { passPointerArray } from './private'; -import { NativePtrDecoder } from './Platform'; +import { KNativePointer, KPointer } from '../common/InteropTypes'; +import { passPointerArray } from '../common/private'; +import { NativePtrDecoder } from '../common/Platform'; import { Worker as ThreadWorker } from 'worker_threads'; -import { ensurePathExists, isMac } from './utils'; +import { ensurePathExists } from '../common/utils'; import * as child_process from 'child_process'; -import { DECL_ETS_SUFFIX } from './preDefine'; +import { DECL_ETS_SUFFIX, DEFAULT_CACHE_DIR } from '../common/preDefine'; import * as crypto from 'crypto'; import * as os from 'os'; @@ -74,50 +84,57 @@ function initBuildEnv(): void { const currentPath: string | undefined = process.env.PATH; let pandaLibPath: string = process.env.PANDA_LIB_PATH ? process.env.PANDA_LIB_PATH - : path.resolve(__dirname, '../../ets2panda/lib'); + : path.resolve(__dirname, '../../../ets2panda/lib'); process.env.PATH = `${currentPath}${path.delimiter}${pandaLibPath}`; } -export interface TextDocumentChangeInfo { - newDoc: string; - rangeStart?: number; - rangeEnd?: number; - updateText?: string; -} - export class Lsp { private pandaLibPath: string; private pandaBinPath: string; - private fileNameToArktsconfig: Record; // Map - private moduleToBuildConfig: Record; // Map private getFileContent: (filePath: string) => string; private filesMap: Map; // Map - private projectPath: string; private cacheDir: string; private globalContextPtr?: KNativePointer; private globalConfig?: Config; private globalLspDriverHelper?: LspDriverHelper; private entryArkTsConfig: string; private fileDependencies: string; + private buildConfigs: Record; // Map + private moduleInfos: Record; // Map + private pathConfig: PathConfig; - constructor(projectPath: string, getContentCallback?: (filePath: string) => string) { + constructor(pathConfig: PathConfig, getContentCallback?: (filePath: string) => string, modules?: ModuleDescriptor[]) { initBuildEnv(); - this.cacheDir = path.join(projectPath, '.idea', '.deveco'); - let compileFileInfoPath = path.join(this.cacheDir, 'lsp_compileFileInfos.json'); + this.cacheDir = + pathConfig.cacheDir !== undefined ? pathConfig.cacheDir : path.join(pathConfig.projectPath, DEFAULT_CACHE_DIR); this.fileDependencies = path.join(this.cacheDir, 'file_dependencies.json'); this.entryArkTsConfig = path.join(this.cacheDir, 'entry', 'arktsconfig.json'); - this.projectPath = projectPath; this.pandaLibPath = process.env.PANDA_LIB_PATH ? process.env.PANDA_LIB_PATH - : path.resolve(__dirname, '../../ets2panda/lib'); + : path.resolve(__dirname, '../../../ets2panda/lib'); this.pandaBinPath = process.env.PANDA_BIN_PATH ? process.env.PANDA_BIN_PATH - : path.resolve(__dirname, '../../ets2panda/bin'); - this.fileNameToArktsconfig = JSON.parse(fs.readFileSync(compileFileInfoPath, 'utf-8')); - let buildConfigPath = path.join(projectPath, '.idea', '.deveco', 'lsp_build_config.json'); - this.moduleToBuildConfig = JSON.parse(fs.readFileSync(buildConfigPath, 'utf-8')); + : path.resolve(__dirname, '../../../ets2panda/bin'); this.filesMap = new Map(); this.getFileContent = getContentCallback || ((path: string): string => fs.readFileSync(path, 'utf8')); + this.buildConfigs = generateBuildConfigs(pathConfig, modules); + this.moduleInfos = generateArkTsConfigs(this.buildConfigs); + this.pathConfig = pathConfig; + PluginDriver.getInstance().initPlugins(Object.values(this.buildConfigs)[0]); + } + + // Partially update for new file + updateModuleInfos(module: ModuleDescriptor, newFilePath: String): void { + let buildConfig = this.buildConfigs[module.name]; + buildConfig.compileFiles.push(newFilePath.valueOf()); + let moduleInfo = generateModuleInfo(this.buildConfigs, buildConfig); + this.moduleInfos[newFilePath.valueOf()] = moduleInfo; + } + + // Full update for `Sync Now` + update(modules: ModuleDescriptor[]): void { + this.buildConfigs = generateBuildConfigs(this.pathConfig, modules); + this.moduleInfos = generateArkTsConfigs(this.buildConfigs); } modifyFilesMap(fileName: string, fileContent: TextDocumentChangeInfo): void { @@ -128,14 +145,6 @@ export class Lsp { this.filesMap.delete(fileName); } - updateConfig(buildSdkPath: string, modules?: ModuleDescriptor[]): void { - generateArkTsConfigByModules(buildSdkPath, this.projectPath, modules); - let compileFileInfoPath = path.join(this.projectPath, '.idea', '.deveco', 'lsp_compileFileInfos.json'); - this.fileNameToArktsconfig = JSON.parse(fs.readFileSync(compileFileInfoPath, 'utf-8')); - let buildConfigPath = path.join(this.projectPath, '.idea', '.deveco', 'lsp_build_config.json'); - this.moduleToBuildConfig = JSON.parse(fs.readFileSync(buildConfigPath, 'utf-8')); - } - private getFileSource(filePath: string): string { const getSource = this.filesMap.get(filePath) || this.getFileContent(filePath); if (!getSource) { @@ -144,20 +153,10 @@ export class Lsp { return getSource.replace(/\r\n/g, '\n'); } - private getModuleNameFromFilename(filePath: string): string { - const projectRoot = this.projectPath; - if (!filePath.startsWith(projectRoot)) { - return ''; - } - const relativePath = path.relative(projectRoot, filePath); - const parts = relativePath.split(path.sep); - return parts[0] || ''; - } - getDefinitionAtPosition(filename: String, offset: number): LspDefinitionData { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -176,7 +175,7 @@ export class Lsp { getSemanticDiagnostics(filename: String): LspDiagsNode { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -195,7 +194,7 @@ export class Lsp { getCurrentTokenValue(filename: String, offset: number): string { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -214,7 +213,7 @@ export class Lsp { getImplementationAtPosition(filename: String, offset: number): LspDefinitionData { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -233,7 +232,7 @@ export class Lsp { getFileReferences(filename: String): LspReferenceData[] { let lspDriverHelper = new LspDriverHelper(); let searchFilePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[searchFilePath]; + let arktsconfig = this.moduleInfos[searchFilePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, searchFilePath, this.pandaLibPath); const source = this.getFileSource(searchFilePath); @@ -247,11 +246,10 @@ export class Lsp { lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); let result: LspReferenceData[] = []; - let moduleName = path.basename(path.dirname(arktsconfig)); - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; - for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let compileFiles = this.moduleInfos[searchFilePath].compileFiles; + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -277,7 +275,7 @@ export class Lsp { getReferencesAtPosition(filename: String, offset: number): LspReferenceData[] { let lspDriverHelper = new LspDriverHelper(); let searchFilePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[searchFilePath]; + let arktsconfig = this.moduleInfos[searchFilePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, searchFilePath, this.pandaLibPath); const source = this.getFileSource(searchFilePath); @@ -291,11 +289,10 @@ export class Lsp { lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); let result: LspReferenceData[] = []; - let moduleName = path.basename(path.dirname(arktsconfig)); - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; - for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let compileFiles = this.moduleInfos[searchFilePath].compileFiles; + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -317,7 +314,7 @@ export class Lsp { getTypeHierarchies(filename: String, offset: number): LspTypeHierarchiesInfo | null { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -335,11 +332,10 @@ export class Lsp { return null; } let result: LspTypeHierarchiesInfo[] = []; - let moduleName = path.basename(path.dirname(arktsconfig)); - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; - for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let compileFiles = this.moduleInfos[filePath].compileFiles; + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let searchCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -381,7 +377,7 @@ export class Lsp { getClassHierarchyInfo(filename: String, offset: number): LspClassHierarchy { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -400,7 +396,7 @@ export class Lsp { getAliasScriptElementKind(filename: String, offset: number): LspCompletionEntryKind { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -420,7 +416,7 @@ export class Lsp { let contextList = []; let lspDriverHelper = new LspDriverHelper(); let localFilePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[localFilePath]; + let arktsconfig = this.moduleInfos[localFilePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, localFilePath, this.pandaLibPath); const source = this.getFileSource(localFilePath); @@ -431,14 +427,13 @@ export class Lsp { lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); contextList.push({ ctx: localCtx, cfg: localCfg }); let nativeContextList = global.es2panda._pushBackToNativeContextVector(localCtx, localCtx, 1); - let moduleName = path.basename(path.dirname(arktsconfig)); - let buildConfig = this.moduleToBuildConfig[moduleName]; - for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]); + let compileFiles = this.moduleInfos[localFilePath].compileFiles; + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); if (localFilePath === filePath) { continue; } - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let searchCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -466,7 +461,7 @@ export class Lsp { ): LspClassPropertyInfo { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -485,7 +480,7 @@ export class Lsp { getOrganizeImports(filename: String): LspFileTextChanges { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -504,7 +499,7 @@ export class Lsp { findSafeDeleteLocation(filename: String, offset: number): LspSafeDeleteLocationInfo[] { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -518,11 +513,10 @@ export class Lsp { lspDriverHelper.destroyContext(localCtx); lspDriverHelper.destroyConfig(localCfg); let result: LspSafeDeleteLocationInfo[] = []; - let moduleName = path.basename(path.dirname(arktsconfig)); - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; - for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let compileFiles = this.moduleInfos[filePath].compileFiles; + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -544,7 +538,7 @@ export class Lsp { getCompletionEntryDetails(filename: String, offset: number, entryName: String): CompletionEntryDetails { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -563,7 +557,7 @@ export class Lsp { getApplicableRefactors(filename: String, kind: String, offset: number): ApplicableRefactorItemInfo[] { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -585,7 +579,7 @@ export class Lsp { getClassConstructorInfo(filename: String, offset: number, properties: string[]): LspClassConstructorInfo { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -604,13 +598,13 @@ export class Lsp { getSyntacticDiagnostics(filename: String): LspDiagsNode { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); let localCtx = lspDriverHelper.createCtx(source, filePath, localCfg, this.globalContextPtr); - const moduleName = this.getModuleNameFromFilename(filePath); - const buildConfig = this.moduleToBuildConfig[moduleName]; + const packageName = this.moduleInfos[filePath].packageName; + const buildConfig = this.buildConfigs[packageName]; PluginDriver.getInstance().getPluginContext().setProjectConfig(buildConfig); PluginDriver.getInstance().getPluginContext().setContextPtr(localCtx); lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); @@ -626,7 +620,7 @@ export class Lsp { getSuggestionDiagnostics(filename: String): LspDiagsNode { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -645,7 +639,7 @@ export class Lsp { getQuickInfoAtPosition(filename: String, offset: number): LspQuickInfo { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -664,7 +658,7 @@ export class Lsp { getDocumentHighlights(filename: String, offset: number): LspDocumentHighlightsReferences { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -683,7 +677,7 @@ export class Lsp { getCompletionAtPosition(filename: String, offset: number): LspCompletionInfo { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); let source = this.getFileSource(filePath); @@ -712,7 +706,7 @@ export class Lsp { toLineColumnOffset(filename: String, offset: number): LspLineAndCharacter { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -731,7 +725,7 @@ export class Lsp { getSafeDeleteInfo(filename: String, position: number): boolean { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -750,7 +744,7 @@ export class Lsp { findRenameLocations(filename: String, offset: number): LspRenameLocation[] { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -759,13 +753,12 @@ export class Lsp { lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_PARSED); PluginDriver.getInstance().runPluginHook(PluginHook.PARSED); lspDriverHelper.proceedToState(localCtx, Es2pandaContextState.ES2PANDA_STATE_CHECKED); - let moduleName = path.basename(path.dirname(arktsconfig)); - let buildConfig: BuildConfig = this.moduleToBuildConfig[moduleName]; + let compileFiles = this.moduleInfos[filePath].compileFiles; const fileContexts: KPointer[] = []; const fileConfigs: Config[] = [localCfg]; - for (let i = 0; i < buildConfig.compileFiles.length; i++) { - let filePath = path.resolve(buildConfig.compileFiles[i]); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + for (let i = 0; i < compileFiles.length; i++) { + let filePath = path.resolve(compileFiles[i]); + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let compileFileCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -800,7 +793,7 @@ export class Lsp { getRenameInfo(filename: String, offset: number): LspRenameInfoType { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -826,7 +819,7 @@ export class Lsp { getSpanOfEnclosingComment(filename: String, offset: number, onlyMultiLine: boolean): LspTextSpan { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -845,7 +838,7 @@ export class Lsp { getCodeFixesAtPosition(filename: String, start: number, end: number, errorCodes: number[]): CodeFixActionInfo[] { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -873,7 +866,7 @@ export class Lsp { provideInlayHints(filename: String, span: TextSpan): LspInlayHint[] { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -896,7 +889,7 @@ export class Lsp { getSignatureHelpItems(filename: String, offset: number): LspSignatureHelpItems { let lspDriverHelper = new LspDriverHelper(); let filePath = path.resolve(filename.valueOf()); - let arktsconfig = this.fileNameToArktsconfig[filePath]; + let arktsconfig = this.moduleInfos[filePath].arktsConfigFile; let ets2pandaCmd = ets2pandaCmdPrefix.concat(arktsconfig); let localCfg = lspDriverHelper.createCfg(ets2pandaCmd, filePath, this.pandaLibPath); const source = this.getFileSource(filePath); @@ -916,7 +909,6 @@ export class Lsp { private getFileDependencies(inputs: string[], output: string): void { let depInputContent = ''; let outputFile: string = output; - let libPath = process.env.PANDA_SDK_PATH; let depAnalyzerPath: string = path.join(this.pandaBinPath, 'dependency_analyzer'); let depInputFile = path.join(this.cacheDir, 'depInput.txt'); inputs.forEach((file) => { @@ -1039,7 +1031,7 @@ export class Lsp { } private collectCompileJobs(jobs: Record, isValid: boolean = false): void { - let entryFileList: string[] = Object.keys(this.fileNameToArktsconfig); + let entryFileList: string[] = Object.keys(this.moduleInfos); this.getFileDependencies(entryFileList, this.fileDependencies); const data = fs.readFileSync(this.fileDependencies, 'utf-8'); let fileDepsInfo: FileDepsInfo = JSON.parse(data) as FileDepsInfo; @@ -1165,7 +1157,7 @@ export class Lsp { 'ets', '--arktsconfig', this.entryArkTsConfig, - Object.keys(this.fileNameToArktsconfig)[0] + Object.keys(this.moduleInfos)[0] ]; this.globalLspDriverHelper = new LspDriverHelper(); @@ -1306,7 +1298,7 @@ export class Lsp { filePath: job.fileList[0], arktsConfigFile: this.entryArkTsConfig, globalContextPtr: this.globalContextPtr!, - buildConfig: Object.values(this.moduleToBuildConfig)[0], + buildConfig: Object.values(this.buildConfigs)[0], isValid: job.isValid }; } @@ -1352,7 +1344,7 @@ export class Lsp { filePath: filename.valueOf(), arktsConfigFile: this.entryArkTsConfig, globalContextPtr: this.globalContextPtr!, - buildConfig: Object.values(this.moduleToBuildConfig)[0], + buildConfig: Object.values(this.buildConfigs)[0], isValid: true }; this.compileExternalProgram(jobInfo); diff --git a/ets2panda/bindings/test/cases.ts b/ets2panda/bindings/test/cases.ts index f64151085afce54abe6f7900149c14300577f8d8..f353848c71171c8daa1a077116a00d32cde1724e 100644 --- a/ets2panda/bindings/test/cases.ts +++ b/ets2panda/bindings/test/cases.ts @@ -14,7 +14,7 @@ */ import path from 'path'; -import { TextSpan } from '../src/lspNode'; +import { TextSpan } from '../src/lsp/lspNode'; export interface TestConfig { expectedFilePath: string; diff --git a/ets2panda/bindings/test/run_tests.ts b/ets2panda/bindings/test/run_tests.ts index 7d6edb92a1faabc95eaec38081f2301c8df40378..9220c53c917f33f75723dd47b730ec8a668ce23d 100644 --- a/ets2panda/bindings/test/run_tests.ts +++ b/ets2panda/bindings/test/run_tests.ts @@ -15,16 +15,9 @@ import path from 'path'; import fs from 'fs'; -import { - Lsp, - LspDefinitionData, - LspCompletionInfo, - LspDiagsNode, - ModuleDescriptor, - generateArkTsConfigByModules -} from '../src/index'; +import { Lsp, LspDefinitionData, LspCompletionInfo, LspDiagsNode, ModuleDescriptor, PathConfig } from '../src/index'; import { testCases } from './cases'; -import { LspCompletionEntry } from '../src/lspNode'; +import { LspCompletionEntry } from '../src/lsp/lspNode'; interface ComparisonOptions { subMatch?: boolean; @@ -364,13 +357,16 @@ if (require.main === module) { updateMode = true; } const testDir = path.resolve(process.argv[2]); - const buildSdkPath = path.join(testDir, 'ets', 'ets1.2'); - const projectRoot = path.join(testDir, 'testcases'); - const modules = getModules(projectRoot); + const pathConfig: PathConfig = { + buildSdkPath: path.join(testDir, 'ets', 'ets1.2'), + projectPath: path.join(testDir, 'testcases'), + declgenOutDir: '' + }; + + const modules = getModules(pathConfig.projectPath); - generateArkTsConfigByModules(buildSdkPath, projectRoot, modules); - const lsp = new Lsp(projectRoot); + const lsp = new Lsp(pathConfig, undefined, modules); - process.env.BINDINGS_PATH = path.join(buildSdkPath, 'build-tools', 'bindings'); + process.env.BINDINGS_PATH = path.join(pathConfig.buildSdkPath, 'build-tools', 'bindings'); runTests(testDir, lsp); }