Skip to content

Commit 2c1cdb8

Browse files
authored
Merge pull request #194 from digma-ai/feature/fix-js-error-parsing
Feature/fix js error parsing
2 parents c603e58 + e4326b5 commit 2c1cdb8

16 files changed

+372
-163
lines changed

src/analyticsCodeLens.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import { CodeObjectLocationInfo } from './services/languages/extractors';
88
import { CodeObjectUsageStatus, UsageStatusResults } from './services/analyticsProvider';
99

1010

11-
export class AnaliticsCodeLens implements vscode.Disposable
11+
export class AnalyticsCodeLens implements vscode.Disposable
1212
{
1313

1414
private _provider: CodelensProvider;

src/extension.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as vscode from 'vscode';
2-
import { AnaliticsCodeLens } from './analyticsCodeLens';
2+
import { AnalyticsCodeLens } from './analyticsCodeLens';
33
import { AnalyticsProvider} from './services/analyticsProvider';
44
import { SymbolProvider } from './services/languages/symbolProvider';
55
import { PythonLanguageExtractor } from "./services/languages/python/languageExtractor";
@@ -36,9 +36,9 @@ export async function activate(context: vscode.ExtensionContext)
3636
const codeInspector = new CodeInspector();
3737
const symbolProvider = new SymbolProvider(supportedLanguages, codeInspector);
3838
const analyticsProvider = new AnalyticsProvider(workspaceState);
39-
const documentInfoProvider = new DocumentInfoProvider(analyticsProvider, symbolProvider,workspaceState);
39+
const documentInfoProvider = new DocumentInfoProvider(analyticsProvider, symbolProvider, workspaceState);
4040
const editorHelper = new EditorHelper(sourceControl, documentInfoProvider);
41-
const codeLensProvider = new AnaliticsCodeLens(documentInfoProvider,workspaceState)
41+
const codeLensProvider = new AnalyticsCodeLens(documentInfoProvider, workspaceState);
4242

4343
if(!workspaceState.environment){
4444
const firstEnv = (await analyticsProvider.getEnvironments()).firstOrDefault();

src/services/EditorHelper.ts

Lines changed: 40 additions & 75 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;
@@ -29,80 +30,68 @@ export class EditorHelper {
2930
private _documentInfoProvider: DocumentInfoProvider,
3031
) {}
3132

32-
public async goToFileAndLine(editorInfo?: EditorInfo)
33-
{
33+
public async goToFileAndLine(editorInfo?: EditorInfo) {
3434
if(!editorInfo?.workspaceUri) {
3535
return;
3636
}
3737

3838
const workspaceUri = editorInfo.workspaceUri;
3939
const lineNumber = editorInfo.lineNumber ?? 0;
4040

41-
try
42-
{
41+
try {
4342
let doc: vscode.TextDocument | undefined = undefined;
4443

45-
if(!await utils.fileExists(workspaceUri))
46-
{
44+
if(!await utils.fileExists(workspaceUri)) {
4745
doc = await this.askAndOpenFromSourceControl(editorInfo);
4846
}
49-
else
50-
{
47+
else {
5148
doc = await vscode.workspace.openTextDocument(workspaceUri);
5249

5350
const txtLine = doc.lineAt(lineNumber-1);
54-
var fileChanged:boolean = false;
55-
if (editorInfo.executedCode){
51+
let fileChanged:boolean = false;
52+
if (editorInfo.executedCode) {
5653
fileChanged = (txtLine.text.trim() !== editorInfo.executedCode);
5754
}
5855
else {
5956
try {
60-
var sourceDoc = await this.getFromSourceControl(workspaceUri, editorInfo.lastInstanceCommitId!);
61-
if (sourceDoc){
57+
const sourceDoc = await this.getFromSourceControl(workspaceUri, editorInfo.lastInstanceCommitId!);
58+
if (sourceDoc) {
6259
fileChanged = (txtLine.text.trim() !== sourceDoc.lineAt(lineNumber-1).text.trim());
6360
}
64-
else{
61+
else {
6562
return;
6663
}
6764
}
68-
catch (exeption){
65+
catch(exeption) {
6966
await vscode.window.showWarningMessage(
7067
'Cannot locate file in source control. Please make sure its checked in');
7168
}
72-
73-
7469
}
75-
if(fileChanged)
76-
{
70+
if(fileChanged) {
7771
doc = await this.askAndOpenFromSourceControl(editorInfo);;
7872
}
79-
else
80-
{
73+
else {
8174
const docInfo = await this._documentInfoProvider.getDocumentInfo(doc);
8275
const methodInfos = docInfo?.methods || [];
83-
if(methodInfos.all(m => m.symbol.name != editorInfo.functionName))
84-
{
76+
if(methodInfos.all(m => m.symbol.name != editorInfo.functionName)) {
8577
doc = await this.askAndOpenFromSourceControl(editorInfo);
8678
}
8779
}
8880
}
8981

90-
if(doc)
91-
{
82+
if(doc) {
9283
await this.openFileAndLine(doc, lineNumber);
9384
}
9485
}
95-
catch(error)
96-
{
86+
catch(error) {
9787
Logger.error(`Failed to open file: ${editorInfo.modulePhysicalPath}`, error);
9888
vscode.window.showErrorMessage(`Failed to open file: ${editorInfo.modulePhysicalPath}`)
9989
}
10090
}
10191

102-
public async openTextDocumentFromUri(uri: vscode.Uri) : Promise<vscode.TextDocument>{
92+
public async openTextDocumentFromUri(uri: vscode.Uri) : Promise<vscode.TextDocument> {
10393
let doc = await vscode.workspace.openTextDocument(uri);
10494
return doc;
105-
10695
}
10796

10897
public async openFileAndLine(doc: vscode.TextDocument, lineNumber: number) {
@@ -117,18 +106,16 @@ export class EditorHelper {
117106
return await vscode.window.showTextDocument(doc);
118107
}
119108

120-
private async askAndOpenFromSourceControl(editorInfo: EditorInfo) : Promise<vscode.TextDocument | undefined>
121-
{
122-
if(!this._sourceControl.current)
123-
{
109+
private async askAndOpenFromSourceControl(editorInfo: EditorInfo) : Promise<vscode.TextDocument | undefined> {
110+
if(!this._sourceControl.current) {
124111
const sel = await vscode.window.showWarningMessage(
125112
'File version is different from the version recorded in this flow.\nPlease configure source control.',
126113
'configure');
127-
if(sel == 'configure')
114+
if(sel == 'configure') {
128115
await vscode.commands.executeCommand("workbench.action.openWorkspaceSettings", {query: Settings.sourceControl.key});
116+
}
129117
}
130-
else
131-
{
118+
else {
132119
let sel = await vscode.window.showWarningMessage(
133120
`File version is different from the version recorded in this flow, would you like to open the remote version of the file' installed.`,
134121
'yes'
@@ -155,54 +142,32 @@ export class EditorHelper {
155142
return await this._sourceControl.current?.getFile(uri, commit);
156143
}
157144

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-
}
145+
public async getWorkspaceFileUri(
146+
pathInfo: ModulePathInfo,
147+
document?: vscode.TextDocument,
148+
) : Promise<vscode.Uri | undefined> {
149+
if(!document) {
150+
return;
170151
}
171152

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-
153+
const languageExtractor = await this._documentInfoProvider.symbolProvider.getSupportedLanguageExtractor(document);
154+
if(!languageExtractor) {
155+
return;
191156
}
192157

193-
194-
}
158+
const converters = await languageExtractor.getModulePathToUriConverters();
159+
let path;
160+
for (let index = 0; !path && index < converters.length; index++) {
161+
const converter = converters[index];
162+
path = await converter.convert(pathInfo);
163+
}
195164

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

200-
201-
202-
203168
public async getExecutedCodeFromScm(uri: vscode.Uri, commit: string, line: integer) : Promise<string |undefined>{
204-
var doc = await this.getFromSourceControl(uri, commit);
205-
if (doc){
169+
const doc = await this.getFromSourceControl(uri, commit);
170+
if (doc) {
206171
return doc.lineAt(line-1).text.trim();
207172
}
208173
}

src/services/languages/csharp/languageExtractor.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
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';
89
// import { AspNetCoreMvcEndpointExtractor } from './AspNetCoreMvcEndpointExtractor';
910

10-
export class CSharpLanguageExtractor extends LanguageExtractor
11-
{
11+
export class CSharpLanguageExtractor extends LanguageExtractor {
1212
public requiredExtensionLoaded: boolean = false;
1313

1414
public get requiredExtensionId(): string {
@@ -40,4 +40,11 @@ export class CSharpLanguageExtractor extends LanguageExtractor
4040
new CSharpSpanExtractor(codeInspector),
4141
];
4242
}
43+
44+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
45+
return [
46+
new LogicalModulePathToUriConverter(),
47+
new PhysicalModulePathToUriConverter(),
48+
];
49+
}
4350
}

src/services/languages/go/languageExtractor.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@ 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

9-
export class GoLanguageExtractor extends LanguageExtractor
10-
{
10+
export class GoLanguageExtractor extends LanguageExtractor {
1111
public requiredExtensionLoaded: boolean = false;
1212

1313
public get requiredExtensionId(): string {
@@ -45,4 +45,11 @@ export class GoLanguageExtractor extends LanguageExtractor
4545
Logger.info(`Finished activating "${extension.id}" extension`);
4646
}
4747
}
48+
49+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
50+
return [
51+
new LogicalModulePathToUriConverter(),
52+
new PhysicalModulePathToUriConverter(),
53+
];
54+
}
4855
}

src/services/languages/javascript/languageExtractor.ts

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,14 @@ import { IMethodExtractor, ISpanExtractor } from '../extractors';
44
import { LanguageExtractor } from '../languageExtractor';
55
import { IMethodPositionSelector } from '../methodPositionSelector';
66
import { JSMethodPositionSelector } from './methodPositionSelector';
7+
import { IModulePathToUriConverter } from '../modulePathToUriConverters';
78
import { JSMethodExtractor } from './methodExtractor';
89
import { JSSpanExtractor } from './spanExtractor';
10+
import { JSPackageReader } from './packageReader';
11+
import { JSPackageToUriConverter } from './modulePathToUriConverters';
912

10-
export class JSLanguageExtractor extends LanguageExtractor
11-
{
13+
export class JSLanguageExtractor extends LanguageExtractor {
14+
private packageReader: JSPackageReader = new JSPackageReader();
1215
public requiredExtensionLoaded: boolean = false;
1316

1417
public get requiredExtensionId(): string {
@@ -21,7 +24,7 @@ export class JSLanguageExtractor extends LanguageExtractor
2124

2225
public get methodExtractors(): IMethodExtractor[] {
2326
return [
24-
new JSMethodExtractor()
27+
new JSMethodExtractor(this.packageReader),
2528
];
2629
}
2730

@@ -34,4 +37,11 @@ export class JSLanguageExtractor extends LanguageExtractor
3437
new JSSpanExtractor(codeInspector)
3538
];
3639
}
40+
41+
public async getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]> {
42+
const packagesMap = await this.packageReader.loadPackagesMap();
43+
return [
44+
new JSPackageToUriConverter(packagesMap),
45+
];
46+
}
3747
}

src/services/languages/javascript/methodExtractor.ts

Lines changed: 13 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import * as vscode from 'vscode';
22
import * as path from 'path';
33
import { DocumentSymbol } from 'vscode-languageclient';
44
import { IMethodExtractor, SymbolInfo } from '../extractors';
5-
import { Logger } from '../../logger';
65
import { Token, TokenType } from '../tokens';
76
import {
87
MethodSymbolInfoExtractor,
@@ -11,20 +10,23 @@ import {
1110
AnonymousExpressRequestHandlerSymbolInfoExtractor,
1211
VariableFunctionSymbolInfoExtractor,
1312
} from './symbolInfoExtractors';
13+
import { JSPackageReader } from './packageReader';
1414

1515
export class JSMethodExtractor implements IMethodExtractor {
1616

17+
constructor(
18+
private packageReader: JSPackageReader,
19+
) {
20+
}
21+
1722
public async extractMethods(document: vscode.TextDocument, docSymbols: DocumentSymbol[], tokens: Token[]): Promise<SymbolInfo[]> {
18-
const packages = await vscode.workspace.findFiles('**/package.json');
19-
const packageFile = packages.find(f => document.uri.fsPath.startsWith(path.dirname(f.fsPath)));
23+
const packageFile = await this.packageReader.findPackage(document.uri);
2024
if (!packageFile) {
21-
Logger.warn(`Could not resolve package file for '${document.uri.path}'`);
2225
return [];
2326
}
2427

25-
let packageName = await this.getPackageName(packageFile);
26-
if (packageName === undefined || packageName === "") {
27-
Logger.warn(`Could not find package name in '${packageFile.path}'`);
28+
let packageName = await this.packageReader.getPackageName(packageFile);
29+
if (packageName === undefined) {
2830
return [];
2931
}
3032

@@ -46,12 +48,6 @@ export class JSMethodExtractor implements IMethodExtractor {
4648
return this.extractFunctions(document, codeObjectPath, '', docSymbols, tokens);
4749
}
4850

49-
private async getPackageName(packageFile: vscode.Uri): Promise<string | undefined> {
50-
const modDocument = await vscode.workspace.openTextDocument(packageFile);
51-
const pkgjson = JSON.parse(modDocument.getText());
52-
return pkgjson.name;
53-
}
54-
5551
private extractFunctions(document: vscode.TextDocument, codeObjectPath: string, parentSymbolPath: string, symbols: DocumentSymbol[], tokens: Token[]): SymbolInfo[] {
5652
const symbolInfos: SymbolInfo[] = [];
5753

@@ -93,12 +89,10 @@ export class JSMethodExtractor implements IMethodExtractor {
9389
for (const symbol of symbols) {
9490
const symbolPath = (parentSymbolPath ? parentSymbolPath + '.' : '') + symbol.name;
9591

96-
const symbolInfo: SymbolInfo | undefined = symbolInfoExtractors.reduce(
97-
(info: SymbolInfo | undefined, extractor) => info || extractor.extract(symbol, codeObjectPath, symbol.name, document, symbolPath),
98-
undefined,
99-
);
100-
if(symbolInfo) {
101-
symbolInfos.push(symbolInfo);
92+
for (const extractor of symbolInfoExtractors) {
93+
symbolInfos.push(
94+
...extractor.extract(symbol, codeObjectPath, symbol.name, document, symbolPath)
95+
);
10296
}
10397

10498
const hasChildren = symbol.children && symbol.children.length > 0;

0 commit comments

Comments
 (0)