Skip to content

Commit c171546

Browse files
author
Noam Kfir
committed
Replace workspace file uri implementation with per-language ModulePathToUriConverters
1 parent 6d85f71 commit c171546

File tree

9 files changed

+133
-49
lines changed

9 files changed

+133
-49
lines changed

src/services/EditorHelper.ts

Lines changed: 17 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { Logger } from './logger';
55
import { SourceControl } from './sourceControl';
66
import { DocumentInfoProvider } from './documentInfoProvider';
77
import { Settings } from './../settings';
8+
import { ModulePathInfo } from './languages/modulePathToUriConverters';
89

910
export interface EditorInfo {
1011
workspaceUri?: vscode.Uri;
@@ -155,51 +156,29 @@ export class EditorHelper {
155156
return await this._sourceControl.current?.getFile(uri, commit);
156157
}
157158

158-
159-
public async getWorkspaceFileUri(editorInfo: EditorInfo) : Promise<vscode.Uri | undefined> {
160-
161-
const moduleLogicalPath = editorInfo.moduleLogicalPath;
162-
//Try first using the logical name of the function if we have it
163-
if (moduleLogicalPath){
164-
165-
var symbols = await this.lookupCodeObjectByFullName(moduleLogicalPath);
166-
//We have a match
167-
if (symbols.length===1){
168-
return symbols[0].location.uri;
169-
}
159+
public async getWorkspaceFileUri(
160+
pathInfo: ModulePathInfo,
161+
document?: vscode.TextDocument,
162+
) : Promise<vscode.Uri | undefined> {
163+
if(!document) {
164+
return;
170165
}
171166

172-
const modulePhysicalPath = editorInfo.modulePhysicalPath;
173-
if (modulePhysicalPath){
174-
175-
const moduleRootFolder = modulePhysicalPath.split('/').firstOrDefault();
176-
const moduleWorkspace = vscode.workspace.workspaceFolders?.find(w => w.name === moduleRootFolder);
177-
if (moduleWorkspace){
178-
179-
const workspaceUri = moduleWorkspace
180-
? vscode.Uri.joinPath(moduleWorkspace.uri, '..', modulePhysicalPath)
181-
: undefined;
182-
183-
return workspaceUri;
184-
}
185-
else{
186-
const file = await (await vscode.workspace.findFiles(modulePhysicalPath)).firstOrDefault();
187-
return file;
188-
}
189-
190-
167+
const languageExtractor = await this._documentInfoProvider.symbolProvider.getSupportedLanguageExtractor(document);
168+
if(!languageExtractor) {
169+
return;
191170
}
192171

193-
194-
}
172+
const converters = await languageExtractor.getModulePathToUriConverters();
173+
let path;
174+
for (let index = 0; !path && index < converters.length; index++) {
175+
const converter = converters[index];
176+
path = await converter.convert(pathInfo);
177+
}
195178

196-
private async lookupCodeObjectByFullName(name:string) : Promise<vscode.SymbolInformation[]>{
197-
return await vscode.commands.executeCommand("vscode.executeWorkspaceSymbolProvider", name);
179+
return path;
198180
}
199181

200-
201-
202-
203182
public async getExecutedCodeFromScm(uri: vscode.Uri, commit: string, line: integer) : Promise<string |undefined>{
204183
var doc = await this.getFromSourceControl(uri, commit);
205184
if (doc){

src/services/languages/csharp/languageExtractor.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
import * as vscode from 'vscode';
22
import { CodeInspector } from '../../codeInspector';
33
import { IMethodExtractor, IParametersExtractor, ISpanExtractor } from '../extractors';
4-
import { LanguageExtractor } from "../languageExtractor";
4+
import { LanguageExtractor } from '../languageExtractor';
5+
import { IModulePathToUriConverter, LogicalModulePathToUriConverter, PhysicalModulePathToUriConverter } from '../modulePathToUriConverters';
56
import { CSharpMethodExtractor } from './methodExtractor';
67
import { CSharpParametersExtractor } from './parametersExtractor';
78
import { CSharpSpanExtractor } from './spanExtractor';
@@ -40,4 +41,11 @@ export class CSharpLanguageExtractor extends LanguageExtractor
4041
new CSharpSpanExtractor(codeInspector),
4142
];
4243
}
44+
45+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
46+
return [
47+
new LogicalModulePathToUriConverter(),
48+
new PhysicalModulePathToUriConverter(),
49+
];
50+
}
4351
}

src/services/languages/go/languageExtractor.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { CodeInspector } from '../../codeInspector';
33
import { Logger } from '../../logger';
44
import { IMethodExtractor, ISpanExtractor } from '../extractors';
55
import { LanguageExtractor } from '../languageExtractor';
6+
import { IModulePathToUriConverter, LogicalModulePathToUriConverter, PhysicalModulePathToUriConverter } from '../modulePathToUriConverters';
67
import { GoMethodExtractor } from './methodExtractor';
78
import { GoSpanExtractor } from './spanExtractor';
89

@@ -45,4 +46,11 @@ export class GoLanguageExtractor extends LanguageExtractor
4546
Logger.info(`Finished activating "${extension.id}" extension`);
4647
}
4748
}
49+
50+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
51+
return [
52+
new LogicalModulePathToUriConverter(),
53+
new PhysicalModulePathToUriConverter(),
54+
];
55+
}
4856
}

src/services/languages/javascript/languageExtractor.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { IMethodExtractor, ISpanExtractor } from '../extractors';
44
import { LanguageExtractor } from '../languageExtractor';
55
import { IMethodPositionSelector } from '../methodPositionSelector';
66
import { JSMethodPositionSelector } from './methodPositionSelector';
7+
import { IModulePathToUriConverter, LogicalModulePathToUriConverter, PhysicalModulePathToUriConverter } from '../modulePathToUriConverters';
78
import { JSMethodExtractor } from './methodExtractor';
89
import { JSSpanExtractor } from './spanExtractor';
910

@@ -34,4 +35,11 @@ export class JSLanguageExtractor extends LanguageExtractor
3435
new JSSpanExtractor(codeInspector)
3536
];
3637
}
38+
39+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
40+
return [
41+
new LogicalModulePathToUriConverter(),
42+
new PhysicalModulePathToUriConverter(),
43+
];
44+
}
3745
}

src/services/languages/languageExtractor.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { CodeInspector } from '../codeInspector';
33
import { IMethodPositionSelector, DefaultMethodPositionSelector } from './methodPositionSelector';
44
import { IMethodExtractor, IParametersExtractor, IEndpointExtractor, ISpanExtractor } from './extractors';
55
import { BasicParametersExtractor } from './defaultImpls';
6+
import { IModulePathToUriConverter } from './modulePathToUriConverters';
67

78
export interface ILanguageExtractor {
89
requiredExtensionLoaded: boolean;
@@ -14,6 +15,7 @@ export interface ILanguageExtractor {
1415
getEndpointExtractors(codeInspector: CodeInspector): IEndpointExtractor[];
1516
getSpanExtractors(codeInspector: CodeInspector): ISpanExtractor[];
1617
validateConfiguration(): Promise<void>;
18+
getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]>;
1719
}
1820

1921
export abstract class LanguageExtractor implements ILanguageExtractor {
@@ -41,4 +43,6 @@ export abstract class LanguageExtractor implements ILanguageExtractor {
4143

4244
public async validateConfiguration(): Promise<void> {
4345
}
46+
47+
public abstract getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]>;
4448
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import * as vscode from 'vscode';
2+
3+
export interface ModulePathInfo {
4+
modulePhysicalPath?: string;
5+
moduleLogicalPath?: string;
6+
codeObjectId?: string;
7+
}
8+
9+
export interface IModulePathToUriConverter {
10+
convert(pathInfo: ModulePathInfo): Promise<vscode.Uri | undefined>;
11+
}
12+
13+
export class LogicalModulePathToUriConverter implements IModulePathToUriConverter {
14+
async convert(pathInfo: ModulePathInfo): Promise<vscode.Uri | undefined> {
15+
const { moduleLogicalPath } = pathInfo;
16+
if (moduleLogicalPath){
17+
const symbols = await this.lookupCodeObjectByFullName(moduleLogicalPath);
18+
//We have a match
19+
if (symbols.length === 1) {
20+
return symbols[0].location.uri;
21+
}
22+
}
23+
}
24+
25+
private async lookupCodeObjectByFullName(name:string): Promise<vscode.SymbolInformation[]> {
26+
return await vscode.commands.executeCommand('vscode.executeWorkspaceSymbolProvider', name);
27+
}
28+
}
29+
30+
export class PhysicalModulePathToUriConverter implements IModulePathToUriConverter {
31+
async convert(pathInfo: ModulePathInfo): Promise<vscode.Uri | undefined> {
32+
const { modulePhysicalPath } = pathInfo;
33+
if (modulePhysicalPath) {
34+
const moduleRootFolder = modulePhysicalPath.split('/').firstOrDefault();
35+
const moduleWorkspace = vscode.workspace.workspaceFolders?.find(w => w.name === moduleRootFolder);
36+
if (moduleWorkspace) {
37+
const workspaceUri = moduleWorkspace
38+
? vscode.Uri.joinPath(moduleWorkspace.uri, '..', modulePhysicalPath)
39+
: undefined;
40+
return workspaceUri;
41+
}
42+
else {
43+
const file = await (await vscode.workspace.findFiles(modulePhysicalPath)).firstOrDefault();
44+
return file;
45+
}
46+
}
47+
}
48+
}

src/services/languages/python/languageExtractor.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import * as vscode from 'vscode';
22
import { CodeInspector } from '../../codeInspector';
33
import { IMethodExtractor, ISpanExtractor } from '../extractors';
44
import { LanguageExtractor } from '../languageExtractor';
5+
import { IModulePathToUriConverter, PhysicalModulePathToUriConverter } from '../modulePathToUriConverters';
56
import { PythonMethodExtractor } from './methodExtractor';
67
import { PythonSpanExtractor } from './spanExtractor';
78

@@ -29,4 +30,10 @@ export class PythonLanguageExtractor extends LanguageExtractor
2930
new PythonSpanExtractor(codeInspector)
3031
];
3132
}
33+
34+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
35+
return [
36+
new PhysicalModulePathToUriConverter(),
37+
];
38+
}
3239
}

src/services/languages/symbolProvider.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ export class SymbolProvider
240240
return supportedLanguage?.methodPositionSelector ?? new DefaultMethodPositionSelector();
241241
}
242242

243-
private async getSupportedLanguageExtractor(document: vscode.TextDocument): Promise<ILanguageExtractor | undefined> {
243+
public async getSupportedLanguageExtractor(document: vscode.TextDocument): Promise<ILanguageExtractor | undefined> {
244244
const supportedLanguage = this.languageExtractors.find(x => vscode.languages.match(x.documentFilter, document) > 0);
245245
if (!supportedLanguage ||
246246
!(supportedLanguage.requiredExtensionLoaded || await this.loadRequiredExtension(supportedLanguage)))

src/views/codeAnalytics/errorsViewTab.ts

Lines changed: 31 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,9 @@ export class ErrorsViewTab implements ICodeAnalyticsViewTab
204204
this._overlay.show(HtmlHelper.getLoadingMessage('Loading error view...'), this.errorOverlayId);
205205
const errorDetails = await this._analyticsProvider.getCodeObjectError(e.errorSourceUID);
206206
const codeObject = await this.getCurrentCodeObject() || emptyCodeObject;
207+
const { document } = await this.getCurrentDocumentContext();
207208

208-
const viewModels = await this.createViewModels(errorDetails);
209+
const viewModels = await this.createViewModels(errorDetails, document);
209210
const stackViewModel = viewModels.firstOrDefault();
210211
this._stackViewModel = stackViewModel;
211212
this._stackViewModels = viewModels;
@@ -261,7 +262,10 @@ export class ErrorsViewTab implements ICodeAnalyticsViewTab
261262
return result;
262263
}
263264

264-
private async createViewModels(errorDetails: CodeObjectErrorDetails): Promise<ErrorFlowStackViewModel[]> {
265+
private async createViewModels(
266+
errorDetails: CodeObjectErrorDetails,
267+
document?: vscode.TextDocument,
268+
): Promise<ErrorFlowStackViewModel[]> {
265269
const sourceFlows = errorDetails.errors;
266270
const viewModels: ErrorFlowStackViewModel[] = [];
267271
let id = 0;
@@ -286,10 +290,14 @@ export class ErrorsViewTab implements ICodeAnalyticsViewTab
286290
repeat,
287291
} = sourceFrame;
288292

289-
const workspaceUri = await this._editorHelper.getWorkspaceFileUri({
290-
moduleLogicalPath,
291-
modulePhysicalPath,
292-
});
293+
const workspaceUri = await this._editorHelper.getWorkspaceFileUri(
294+
{
295+
codeObjectId,
296+
moduleLogicalPath,
297+
modulePhysicalPath,
298+
},
299+
document,
300+
);
293301

294302
const frame: FrameViewModel = {
295303
id: id++,
@@ -333,13 +341,22 @@ export class ErrorsViewTab implements ICodeAnalyticsViewTab
333341
return viewModels;
334342
}
335343

336-
private async getCurrentCodeObject(): Promise<CodeObjectInfo | undefined> {
344+
private async getCurrentDocumentContext(): Promise<DocumentContext> {
337345
const editor = vscode.window.activeTextEditor;
338-
if(!editor) {
346+
const document = editor?.document;
347+
348+
return {
349+
editor,
350+
document,
351+
};
352+
}
353+
354+
private async getCurrentCodeObject(): Promise<CodeObjectInfo | undefined> {
355+
const { editor, document } = await this.getCurrentDocumentContext();
356+
if(!editor || !document) {
339357
return;
340358
}
341359

342-
const document = editor.document;
343360
const position = editor.selection.anchor;
344361

345362
const docInfo = this._documentInfoProvider.symbolProvider.supportsDocument(document)
@@ -403,3 +420,8 @@ export class ErrorsViewTab implements ICodeAnalyticsViewTab
403420
this._errorFlowParamDecorator.errorFlow = errorFlow;
404421
}
405422
}
423+
424+
type DocumentContext = {
425+
editor?: vscode.TextEditor
426+
document?: vscode.TextDocument
427+
};

0 commit comments

Comments
 (0)