Skip to content

Commit 1423868

Browse files
authored
Merge pull request #199 from digma-ai/feature/code-object-id-parsers
Unify CodeObjectInfo objects and introduce CodeObjectIdParsers to fix language-specific code object id alias generation
2 parents 2c1cdb8 + de56b7c commit 1423868

18 files changed

+172
-108
lines changed

src/services/codeObject.ts

Lines changed: 59 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,4 +34,62 @@ export class CodeObjectId {
3434
return spanCodeObjectId.substring(ix + this.codeObjectSeparator.length);
3535
}
3636

37-
}
37+
}
38+
39+
export interface CodeObjectInfo {
40+
id: string;
41+
get displayName(): string;
42+
get ids(): string[];
43+
get idsWithType(): string[];
44+
}
45+
46+
export class EmptyCodeObjectInfo implements CodeObjectInfo {
47+
id: string = '';
48+
get displayName(): string {
49+
return '';
50+
}
51+
get ids(): string[] {
52+
return [this.id];
53+
}
54+
get idsWithType(): string[] {
55+
return this.ids;
56+
}
57+
}
58+
59+
export class MinimalCodeObjectInfo implements CodeObjectInfo {
60+
constructor(
61+
public id: string,
62+
private _displayName: string,
63+
) {
64+
}
65+
get displayName(): string {
66+
return this._displayName;
67+
}
68+
get ids(): string[] {
69+
return [this.id];
70+
}
71+
get idsWithType(): string[] {
72+
return this.ids;
73+
}
74+
}
75+
76+
export interface ICodeObjectIdParser {
77+
parse(codeObjectId: string): CodeObjectInfo;
78+
generateAliases(codeObjectId: string): string[];
79+
}
80+
81+
export class CommonCodeObjectIdParser implements ICodeObjectIdParser {
82+
parse(codeObjectId: string): CodeObjectInfo {
83+
const [path, method] = codeObjectId.split(CodeObjectId.codeObjectSeparator);
84+
return new MinimalCodeObjectInfo(codeObjectId, method);
85+
}
86+
87+
generateAliases(codeObjectId: string): string[] {
88+
const folders = codeObjectId.split('/');
89+
const aliases = [codeObjectId];
90+
for (let i = 1; i < folders.length; i++) {
91+
aliases.push(folders.slice(i, folders.length).join('/'));
92+
}
93+
return aliases;
94+
}
95+
}

src/services/documentInfoProvider.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Logger } from "./logger";
55
import { SymbolProvider } from './languages/symbolProvider';
66
import { Token, TokenType } from './languages/tokens';
77
import { Dictionary, Future } from './utils';
8-
import { EndpointInfo, SpanLocationInfo as SpanLocationInfo, SymbolInfo, CodeObjectInfo, IParametersExtractor, CodeObjectLocationInfo } from './languages/extractors';
8+
import { EndpointInfo, SpanLocationInfo as SpanLocationInfo, SymbolInfo, IParametersExtractor, CodeObjectLocationInfo } from './languages/extractors';
99
import { InstrumentationInfo } from './EditorHelper';
1010
import { SymbolInformation } from 'vscode';
1111
import { WorkspaceState } from '../state';
@@ -311,16 +311,15 @@ export class DocumentInfoProvider implements vscode.Disposable
311311
spans: SpanLocationInfo[],
312312
endpoints: EndpointInfo[],
313313
): Promise<MethodInfo[]> {
314+
const codeObjectIdParser = await this.symbolProvider.getCodeObjectIdParser(document);
315+
if(!codeObjectIdParser) {
316+
return [];
317+
}
318+
314319
let methods: MethodInfo[] = [];
315320

316321
for(let symbol of symbols) {
317-
var folders = symbol.id.split("/");
318-
let aliases = [];
319-
aliases.push(symbol.id);
320-
for (let i=1;i<folders.length;i++){
321-
aliases.push(folders.slice(i, folders.length).join("/"));
322-
323-
}
322+
const aliases = codeObjectIdParser.generateAliases(symbol.id);
324323
const method = new MethodInfo(
325324
symbol.id,
326325
symbol.name,

src/services/languages/extractors.ts

Lines changed: 23 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import * as vscode from 'vscode';
22
import { DocumentSymbol } from 'vscode-languageclient';
3+
import { CodeObjectInfo } from '../codeObject';
34
import { DocumentInfoProvider, ParameterInfo } from '../documentInfoProvider';
45
import { SymbolProvider, SymbolTree } from './symbolProvider';
56
import { Token } from './tokens';
@@ -13,16 +14,9 @@ export interface SymbolInfo {
1314
documentUri: vscode.Uri;
1415
}
1516

16-
export interface CodeObjectInfo {
17-
id: string;
18-
get ids(): string[];
19-
get idsWithType(): string[];
20-
}
21-
22-
export interface CodeObjectLocationInfo extends CodeObjectInfo{
17+
export interface CodeObjectLocationInfo extends CodeObjectInfo {
2318
range: vscode.Range;
2419
documentUri: vscode.Uri;
25-
2620
}
2721

2822
export class EndpointInfo implements CodeObjectLocationInfo {
@@ -31,13 +25,20 @@ export class EndpointInfo implements CodeObjectLocationInfo {
3125
public method: string,
3226
public path: string,
3327
public range: vscode.Range,
34-
public documentUri: vscode.Uri) { }
35-
get idsWithType() {
36-
return ['endpoint:' + this.id];
37-
}
38-
get ids() {
39-
return [ this.id];
40-
}
28+
public documentUri: vscode.Uri,
29+
) { }
30+
31+
get displayName(): string {
32+
return this.method;
33+
}
34+
35+
get idsWithType() {
36+
return ['endpoint:' + this.id];
37+
}
38+
39+
get ids() {
40+
return [ this.id];
41+
}
4142
}
4243

4344
export class SpanLocationInfo implements CodeObjectLocationInfo {
@@ -47,7 +48,12 @@ export class SpanLocationInfo implements CodeObjectLocationInfo {
4748
public aliases: string[],
4849
public duplicates: SpanLocationInfo[],
4950
public range: vscode.Range,
50-
public documentUri: vscode.Uri) { }
51+
public documentUri: vscode.Uri,
52+
) { }
53+
54+
get displayName(): string {
55+
return this.name;
56+
}
5157

5258
get idsWithType() {
5359
return this.ids.map(x=> 'span:' + x);
@@ -65,7 +71,7 @@ export interface IMethodExtractor {
6571
extractMethods(
6672
document: vscode.TextDocument,
6773
docSymbols: DocumentSymbol[],
68-
tokens: Token []
74+
tokens: Token [],
6975
): Promise<SymbolInfo[]>;
7076
}
7177

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { CodeObjectId, CodeObjectInfo, ICodeObjectIdParser } from './../../codeObject';
2+
3+
export class JSCodeObjectInfo implements CodeObjectInfo {
4+
constructor(
5+
public id: string,
6+
public packageName: string,
7+
public modulePath: string,
8+
public symbol: string,
9+
) {
10+
}
11+
12+
get displayName(): string {
13+
return this.symbol || '';
14+
}
15+
16+
get ids(): string[] {
17+
return [this.id];
18+
}
19+
20+
get idsWithType(): string[] {
21+
return this.ids;
22+
}
23+
}
24+
25+
export class JSCodeObjectIdParser implements ICodeObjectIdParser {
26+
parse(codeObjectId: string): JSCodeObjectInfo {
27+
const pattern = /([\w\@/-]+):(.+)\$_\$(.*)/;
28+
const matches = codeObjectId.match(pattern);
29+
const [ , packageName, modulePath, symbol ] = matches ?? ['', '', '', ''];
30+
return new JSCodeObjectInfo(
31+
codeObjectId,
32+
packageName,
33+
modulePath,
34+
symbol,
35+
);
36+
}
37+
38+
generateAliases(codeObjectId: string): string[] {
39+
const objectPrefix = 'Object.';
40+
const info: JSCodeObjectInfo = this.parse(codeObjectId);
41+
const prefixedAliased = info.symbol.startsWith(objectPrefix)
42+
? info.symbol.substring(objectPrefix.length)
43+
: `${objectPrefix}${info.symbol}`;
44+
return [
45+
codeObjectId,
46+
`${info.packageName}:${info.modulePath}${CodeObjectId.codeObjectSeparator}${prefixedAliased}`,
47+
];
48+
}
49+
}

src/services/languages/javascript/languageExtractor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ import { JSMethodExtractor } from './methodExtractor';
99
import { JSSpanExtractor } from './spanExtractor';
1010
import { JSPackageReader } from './packageReader';
1111
import { JSPackageToUriConverter } from './modulePathToUriConverters';
12+
import { ICodeObjectIdParser } from '../../codeObject';
13+
import { JSCodeObjectIdParser } from './codeObjectIdParser';
1214

1315
export class JSLanguageExtractor extends LanguageExtractor {
1416
private packageReader: JSPackageReader = new JSPackageReader();
@@ -44,4 +46,8 @@ export class JSLanguageExtractor extends LanguageExtractor {
4446
new JSPackageToUriConverter(packagesMap),
4547
];
4648
}
49+
50+
public getCodeObjectIdParser(): ICodeObjectIdParser {
51+
return new JSCodeObjectIdParser();
52+
}
4753
}
Lines changed: 1 addition & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { dirname, join } from 'path';
22
import * as vscode from 'vscode';
33
import { IModulePathToUriConverter, ModulePathInfo } from '../modulePathToUriConverters';
4+
import { JSCodeObjectIdParser } from './codeObjectIdParser';
45

56
export class JSPackageToUriConverter implements IModulePathToUriConverter {
67

@@ -26,30 +27,3 @@ export class JSPackageToUriConverter implements IModulePathToUriConverter {
2627
}
2728
}
2829
}
29-
30-
interface JSCodeObjectInfo {
31-
packageName: string
32-
modulePath: string
33-
symbol: string
34-
}
35-
36-
class JSCodeObjectIdParser {
37-
parse(codeObjectId: string): JSCodeObjectInfo {
38-
const pattern = /([\w\@/-]+):(?:.)+\$_\$(?:.)*/;
39-
const matches = codeObjectId.match(pattern);
40-
if(matches) {
41-
const [ , packageName, modulePath, symbol ] = matches;
42-
return {
43-
packageName,
44-
modulePath,
45-
symbol,
46-
};
47-
}
48-
49-
return {
50-
packageName: '',
51-
modulePath: '',
52-
symbol: '',
53-
};
54-
}
55-
}

src/services/languages/javascript/symbolInfoExtractors.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,7 @@ export class NamedFunctionDeclarationSymbolInfoExtractor extends SymbolInfoExtra
6464
const functionMatch = `\\s*function\\s*${symbol.name}`; //should handle only function declaration, and filter out function call like db.getAll()
6565
const match = textLine.text.match(functionMatch);
6666
if(match !== undefined && match !== null) {
67-
const names = [name, `Object.${name}`];
68-
return super.extract(symbol, codeObjectPath, names, document, symbolPath);
67+
return super.extract(symbol, codeObjectPath, name, document, symbolPath);
6968
}
7069
}
7170
return [];

src/services/languages/languageExtractor.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import { IMethodPositionSelector, DefaultMethodPositionSelector } from './method
44
import { IMethodExtractor, IParametersExtractor, IEndpointExtractor, ISpanExtractor } from './extractors';
55
import { BasicParametersExtractor } from './defaultImpls';
66
import { IModulePathToUriConverter } from './modulePathToUriConverters';
7+
import { ICodeObjectIdParser, CommonCodeObjectIdParser } from '../codeObject';
78

89
export interface ILanguageExtractor {
910
requiredExtensionLoaded: boolean;
@@ -16,6 +17,7 @@ export interface ILanguageExtractor {
1617
getSpanExtractors(codeInspector: CodeInspector): ISpanExtractor[];
1718
validateConfiguration(): Promise<void>;
1819
getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]>;
20+
getCodeObjectIdParser(): ICodeObjectIdParser;
1921
}
2022

2123
export abstract class LanguageExtractor implements ILanguageExtractor {
@@ -45,4 +47,8 @@ export abstract class LanguageExtractor implements ILanguageExtractor {
4547
}
4648

4749
public abstract getModulePathToUriConverters(): Promise<IModulePathToUriConverter[]>;
50+
51+
public getCodeObjectIdParser(): ICodeObjectIdParser {
52+
return new CommonCodeObjectIdParser();
53+
}
4854
}

src/services/languages/symbolProvider.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ILanguageExtractor } from './languageExtractor';
99
import { Token, TokenType } from './tokens';
1010
import { BasicParametersExtractor } from './defaultImpls';
1111
import { IMethodPositionSelector, DefaultMethodPositionSelector } from './methodPositionSelector';
12+
import { ICodeObjectIdParser } from '../codeObject';
1213

1314
export function trendToCodIcon(trend: number): string
1415
{
@@ -250,6 +251,13 @@ export class SymbolProvider
250251
return supportedLanguage;
251252
}
252253

254+
public async getCodeObjectIdParser(document: vscode.TextDocument): Promise<ICodeObjectIdParser | undefined> {
255+
const supportedLanguage = await this.getSupportedLanguageExtractor(document);
256+
if(supportedLanguage) {
257+
return supportedLanguage.getCodeObjectIdParser();
258+
}
259+
}
260+
253261
private async loadRequiredExtension(language: ILanguageExtractor) : Promise<boolean> {
254262
const extension = vscode.extensions.getExtension(language.requiredExtensionId);
255263
if (!extension)

src/views/codeAnalytics/InsightListView/ErrorsInsight.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
import { CodeObjectId } from "../../../services/codeObject";
22
import { IListViewItemBase } from "../../ListView/IListViewItem";
33
import { WebViewUris } from "../../webViewUtils";
4-
import { CodeObjectInfo } from "../codeAnalyticsView";
54
import { HtmlHelper } from "../common";
65
import {
76
CodeObjectInsight,

0 commit comments

Comments
 (0)