"fix(viper): vpjEditor 与命令注册加容错,避免调试双加载时重复注册导致扩展激活失败
Validation / Typecheck (push) Has been cancelled
Validation / Style (push) Has been cancelled
Validation / Test macos-latest (push) Has been cancelled
Validation / Test ubuntu-latest (push) Has been cancelled
Validation / Test windows-latest (push) Has been cancelled
Validation / Build (push) Has been cancelled
Validation / Required (push) Has been cancelled
Validation / Typecheck (push) Has been cancelled
Validation / Style (push) Has been cancelled
Validation / Test macos-latest (push) Has been cancelled
Validation / Test ubuntu-latest (push) Has been cancelled
Validation / Test windows-latest (push) Has been cancelled
Validation / Build (push) Has been cancelled
Validation / Required (push) Has been cancelled
fix(lsp): 源文件位于执行根之外时仍从同目录解析绝对导入,修复 import lib 无法解析及白色高亮"
This commit is contained in:
1 parent
11e83eb2be
commit
417bc8a2be
4 files changed
+60
-14
No files matched your search
Vendored
+2
-2
@@ -51,7 +51,7 @@
|
||||
"preLaunchTask": "npm: build:extension:dev",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/vscode-Vipeye",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/viper",
|
||||
//"--extensionDevelopmentPath=${workspaceFolder}/packages/viper",
|
||||
// The published extension is named "ms-Vipeye.Vipeye", but in debug mode it's "ms-Vipeye.vscode-Vipeye"
|
||||
// to allow the extension code to participate in the lerna monorepo. Make sure that the published extension
|
||||
// isn't enabled, otherwise both are loaded and conflict.
|
||||
@@ -71,7 +71,7 @@
|
||||
"preLaunchTask": "Watch extension",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/vscode-Vipeye",
|
||||
"--extensionDevelopmentPath=${workspaceFolder}/packages/viper",
|
||||
// "--extensionDevelopmentPath=${workspaceFolder}/packages/viper",
|
||||
// The published extension is named "ms-Vipeye.Vipeye", but in debug mode it's "ms-Vipeye.vscode-Vipeye"
|
||||
// to allow the extension code to participate in the lerna monorepo. Make sure that the published extension
|
||||
// isn't enabled, otherwise both are loaded and conflict.
|
||||
|
||||
@@ -52,28 +52,28 @@ export async function activate(context: ExtensionContext): Promise<ViperApiImpl>
|
||||
|
||||
// 命令。
|
||||
context.subscriptions.push(
|
||||
commands.registerCommand('viper.createProject', async () => {
|
||||
RegisterCommandSafe(context, 'viper.createProject', async () => {
|
||||
await CreateProjectCommand();
|
||||
await projects.DiscoverProjects();
|
||||
projectView.Refresh();
|
||||
}),
|
||||
commands.registerCommand('viper.selectToolchain', async () => {
|
||||
RegisterCommandSafe(context, 'viper.selectToolchain', async () => {
|
||||
await toolchain.SelectToolchain();
|
||||
}),
|
||||
commands.registerCommand('viper.showProjectInfo', () => {
|
||||
RegisterCommandSafe(context, 'viper.showProjectInfo', () => {
|
||||
ShowProjectInfoCommand(projects);
|
||||
}),
|
||||
commands.registerCommand('viper.openSettings', () => {
|
||||
RegisterCommandSafe(context, 'viper.openSettings', () => {
|
||||
commands.executeCommand('workbench.action.openSettings', '@ext:TermiNexus.vipeye');
|
||||
}),
|
||||
commands.registerCommand('viper.refreshView', async () => {
|
||||
RegisterCommandSafe(context, 'viper.refreshView', async () => {
|
||||
await projects.DiscoverProjects();
|
||||
toolchain.Refresh();
|
||||
projectView.Refresh();
|
||||
toolchainView.Refresh();
|
||||
settingsView.Refresh();
|
||||
}),
|
||||
commands.registerCommand('viper.openVpjAsJson', async (uri?: import('vscode').Uri) => {
|
||||
RegisterCommandSafe(context, 'viper.openVpjAsJson', async (uri?: import('vscode').Uri) => {
|
||||
const target = uri ?? window.activeTextEditor?.document.uri;
|
||||
if (!target) {
|
||||
window.showWarningMessage('No .vpj file selected.');
|
||||
@@ -102,6 +102,22 @@ export function deactivate(): void {
|
||||
// 清理由 context.subscriptions 自动处理。
|
||||
}
|
||||
|
||||
/** 安全注册命令:vscode-vipeye 单一合并了核心代码,若与独立的 viper 核心扩展
|
||||
* 同时激活,命令可能已被先注册的扩展注册(command 'xxx' already exists)。
|
||||
* 此处捕获重复注册错误并跳过,避免整个扩展激活失败;命令由先注册方提供。 */
|
||||
function RegisterCommandSafe(
|
||||
context: ExtensionContext,
|
||||
commandId: string,
|
||||
handler: (...args: any[]) => any
|
||||
): import('vscode').Disposable {
|
||||
try {
|
||||
return commands.registerCommand(commandId, handler);
|
||||
} catch (e) {
|
||||
console.warn(`[viper] command '${commandId}' already registered by another extension, skipping.`);
|
||||
return { dispose() {} };
|
||||
}
|
||||
}
|
||||
|
||||
/** 创建项目命令:在当前 workspace 根目录生成 .vpj 模板。 */
|
||||
async function CreateProjectCommand(): Promise<void> {
|
||||
if (!workspace.workspaceFolders || workspace.workspaceFolders.length === 0) {
|
||||
|
||||
@@ -18,10 +18,18 @@ export class VpjEditorProvider implements vscode.CustomTextEditorProvider {
|
||||
|
||||
public static Register(context: vscode.ExtensionContext): vscode.Disposable {
|
||||
const provider = new VpjEditorProvider(context);
|
||||
return vscode.window.registerCustomEditorProvider(VpjEditorProvider.ViewType, provider, {
|
||||
webviewOptions: { retainContextWhenHidden: true },
|
||||
supportsMultipleEditorsPerDocument: false,
|
||||
});
|
||||
try {
|
||||
return vscode.window.registerCustomEditorProvider(VpjEditorProvider.ViewType, provider, {
|
||||
webviewOptions: { retainContextWhenHidden: true },
|
||||
supportsMultipleEditorsPerDocument: false,
|
||||
});
|
||||
} catch (e) {
|
||||
// viper 核心扩展与合并了核心代码的 vscode-vipeye 同时激活时,
|
||||
// 后激活者会因 viewType 已注册而抛错,导致整个扩展激活失败。
|
||||
// 此处跳过重复注册,编辑器由先注册的扩展提供,功能等价。
|
||||
console.warn(`[viper] ${VpjEditorProvider.ViewType} already registered by another extension, skipping.`);
|
||||
return { dispose() {} };
|
||||
}
|
||||
}
|
||||
|
||||
constructor(private readonly context: vscode.ExtensionContext) {}
|
||||
|
||||
@@ -559,6 +559,8 @@ export class ImportResolver {
|
||||
// and so on, until the import root is reached.
|
||||
const origin = sourceFileUri.getDirectory();
|
||||
|
||||
const importLogger = this._configOptions.verboseOutput ? new ImportLogger() : undefined;
|
||||
|
||||
const result = this.cachedParentImportResults.getImportResult(origin, importName, importResult);
|
||||
if (result) {
|
||||
// Already ran the parent directory resolution for this import name on this location.
|
||||
@@ -568,11 +570,31 @@ export class ImportResolver {
|
||||
// Check whether the given file is in the parent directory import resolution cache.
|
||||
const root = getParentImportResolutionRoot(sourceFileUri, execEnv.root);
|
||||
if (!this.cachedParentImportResults.checkValidPath(this.fileSystem, sourceFileUri, root)) {
|
||||
// Viper 扩展:源文件不在执行根下(例如 LSP 工作区根被 .vpj 子项目收窄,
|
||||
// main.py 位于子项目目录之外)时,Pyright 原逻辑直接放弃父目录回退。
|
||||
// 这里仍从源文件自身目录解析一次绝对导入(Python 语义:脚本所在目录
|
||||
// 在 sys.path 上),支持 main.py + 同目录包(如 App/lib)的导入。
|
||||
// 不做向上遍历,避免误解析到执行根外的父目录包。
|
||||
if (IsViperDialect(this._configOptions.dialect)) {
|
||||
const originResult = this.resolveAbsoluteImport(
|
||||
sourceFileUri,
|
||||
origin,
|
||||
execEnv,
|
||||
moduleDescriptor,
|
||||
importName,
|
||||
importLogger,
|
||||
/* allowPartial */ undefined,
|
||||
/* allowNativeLib */ undefined,
|
||||
/* useStubPackage */ false,
|
||||
/* allowPyi */ true
|
||||
);
|
||||
if (originResult?.isImportFound) {
|
||||
return this.filterImplicitImports(originResult, moduleDescriptor.importedSymbols);
|
||||
}
|
||||
}
|
||||
return importResult;
|
||||
}
|
||||
|
||||
const importLogger = this._configOptions.verboseOutput ? new ImportLogger() : undefined;
|
||||
|
||||
const importPath: ImportPath = { importPath: undefined };
|
||||
|
||||
// Going up the given folder one by one until we can resolve the import.
|
||||
|
||||
Reference in new issue
Block a user