Skip to content

Commit c8d9db9

Browse files
committed
corrections and bug fixes for logical path identification
1 parent 4761ca0 commit c8d9db9

File tree

8 files changed

+152
-50
lines changed

8 files changed

+152
-50
lines changed

src/services/languages/codeObjectLocationGuesser.ts

Lines changed: 28 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import { PossibleCodeObjectLocation, CodeObjectLocationHints, ICodeObjectLocati
22

33
export class GuessLocationByDefaultCodeObjectIdSchema implements ICodeObjectLocationGuesser {
44

5-
constructor(private extension:string){
5+
constructor(private extension:string, private _defaultLogical:boolean){
66

77
}
88
async guessLocation(codeObjectInfo: CodeObjectLocationHints ): Promise<PossibleCodeObjectLocation> {
@@ -12,11 +12,27 @@ export class GuessLocationByDefaultCodeObjectIdSchema implements ICodeObjectLoca
1212
let idType="method";
1313

1414
if (codeObjectParts.length!==2){
15-
return {};
15+
16+
let codeObjectPath = codeObjectInfo.codeObjectId;
17+
if (this._defaultLogical){
18+
codeObjectPath= codeObjectInfo.codeObjectId.replaceAll(":",".");
19+
return {
20+
modulePhysicalPath: undefined,
21+
spanName: codeObjectInfo.spanName,
22+
moduleLogicalPath: codeObjectPath
23+
};
24+
}
25+
else{
26+
return {
27+
modulePhysicalPath: codeObjectPath,
28+
spanName: codeObjectInfo.spanName,
29+
moduleLogicalPath: undefined
30+
};
31+
}
1632
}
1733

1834
let codeObjectPath = codeObjectParts[0];
19-
35+
2036
const codeObjectIdAndType =codeObjectPath.split(`:`);
2137
if (codeObjectIdAndType.length===2){
2238
idType = codeObjectIdAndType[0];
@@ -26,16 +42,19 @@ export class GuessLocationByDefaultCodeObjectIdSchema implements ICodeObjectLoca
2642
if (idType==='span'){
2743
if (codeObjectParts.length===2){
2844
return {
29-
modulePhysicalPath: codeObjectParts[0].replaceAll(`.`,`/`)+this.extension,
30-
spanName: codeObjectParts[1]
45+
modulePhysicalPath: !this._defaultLogical ?
46+
codeObjectParts[0].replaceAll(`.`,`/`)+this.extension : undefined,
47+
spanName: codeObjectParts[1],
48+
moduleLogicalPath: this._defaultLogical ? codeObjectParts[0] : undefined
3149
};
3250
}
3351
}
3452

3553
else if (idType==='method'){
3654
return {
37-
modulePhysicalPath: codeObjectParts[0],
38-
methodName: codeObjectParts[1]
55+
modulePhysicalPath: !this._defaultLogical ? codeObjectParts[0] : undefined,
56+
methodName: codeObjectParts[1],
57+
moduleLogicalPath: this._defaultLogical? codeObjectParts[0] : undefined
3958
};
4059

4160
}
@@ -46,12 +65,12 @@ export class GuessLocationByDefaultCodeObjectIdSchema implements ICodeObjectLoca
4665
}
4766
}
4867

49-
export class GuessLocationIfInstrumentationLibraryIsRootSymbol implements ICodeObjectLocationGuesser {
68+
export class GuessLocationIfInstrumentationLibraryIsClass implements ICodeObjectLocationGuesser {
5069

5170
async guessLocation(codeObjectInfo: CodeObjectLocationHints ): Promise<PossibleCodeObjectLocation> {
5271

5372
return {
54-
moduleLogicalPath: codeObjectInfo.instrumentationLibrary?.replace(" ", "/"),
73+
moduleLogicalPath: codeObjectInfo.instrumentationLibrary,
5574
spanName: codeObjectInfo.spanName
5675
};
5776

src/services/languages/csharp/languageExtractor.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
import * as vscode from 'vscode';
22
import { CodeInspector } from '../../codeInspector';
33
import { DocumentInfo, DocumentInfoProvider } from '../../documentInfoProvider';
4+
import { GuessLocationByDefaultCodeObjectIdSchema, GuessLocationIfInstrumentationLibraryIsClass } from '../codeObjectLocationGuesser';
45
import { IMethodExtractor, IParametersExtractor, ISpanExtractor } from '../extractors';
56
import { LanguageExtractor } from '../languageExtractor';
67
import { ICodeObjectLocationGuesser, IModulePathToUriConverter, LogicalModulePathToUriConverter, PhysicalModulePathToUriConverter } from '../modulePathToUriConverters';
8+
import { GuessLocationByInstrumentationLibrary } from '../python/codeObjectLocationGuesser';
79
import { CSharpMethodExtractor } from './methodExtractor';
810
import { CSharpParametersExtractor } from './parametersExtractor';
911
import { CSharpSpanExtractor } from './spanExtractor';
1012
// import { AspNetCoreMvcEndpointExtractor } from './AspNetCoreMvcEndpointExtractor';
1113

1214
export class CSharpLanguageExtractor extends LanguageExtractor {
1315

16+
readonly defaultExtension=".cs";
1417
public get guessCodeObjectLocation(): ICodeObjectLocationGuesser[] {
15-
throw new Error('Method not implemented.');
18+
return [new GuessLocationByDefaultCodeObjectIdSchema(this.defaultExtension, true),
19+
new GuessLocationIfInstrumentationLibraryIsClass()];
1620
}
1721
public requiredExtensionLoaded: boolean = false;
1822

@@ -48,7 +52,7 @@ export class CSharpLanguageExtractor extends LanguageExtractor {
4852

4953
public async getModulePathToUriConverters(docInfoProvider: DocumentInfoProvider): Promise<IModulePathToUriConverter[]> {
5054
return [
51-
new LogicalModulePathToUriConverter(),
55+
new LogicalModulePathToUriConverter(docInfoProvider),
5256
new PhysicalModulePathToUriConverter([],docInfoProvider),
5357
];
5458
}

src/services/languages/go/languageExtractor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ export class GoLanguageExtractor extends LanguageExtractor {
5656

5757
public async getModulePathToUriConverters(docInfoProvider: DocumentInfoProvider): Promise<IModulePathToUriConverter[]> {
5858
return [
59-
new LogicalModulePathToUriConverter(),
59+
new LogicalModulePathToUriConverter(docInfoProvider),
6060
new PhysicalModulePathToUriConverter([],docInfoProvider),
6161
];
6262
}

src/services/languages/modulePathToUriConverters.ts

Lines changed: 94 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@ import { Settings } from '../../settings';
33
import { Logger } from '../logger';
44
import { PathUtils } from '../common/pathUtils';
55
import { integer } from 'vscode-languageclient';
6-
import { DocumentInfoProvider } from '../documentInfoProvider';
6+
import { DocumentInfo, DocumentInfoProvider } from '../documentInfoProvider';
7+
import path = require('path');
78

89
export interface PossibleCodeObjectLocation {
910

@@ -40,17 +41,66 @@ export interface IModulePathToUriConverter {
4041
}
4142

4243
export class LogicalModulePathToUriConverter implements IModulePathToUriConverter {
43-
44+
readonly _commonLogic: CommonConverterLogic = new CommonConverterLogic()
45+
46+
public constructor(private _documentInfoProvider: DocumentInfoProvider){
47+
48+
}
4449
async convert( pathInfo: PossibleCodeObjectLocation): Promise<vscode.Location | undefined> {
4550
const { moduleLogicalPath } = pathInfo;
4651
if (moduleLogicalPath){
52+
let range:vscode.Range | undefined= undefined;
4753
let symbols = await this.lookupCodeObjectByFullName(moduleLogicalPath);
48-
symbols = symbols.filter(x=>x.name.endsWith(moduleLogicalPath));
49-
//We have a match
50-
if (symbols.length === 1) {
51-
return symbols[0].location;
52-
54+
symbols = symbols.filter(x=>moduleLogicalPath.endsWith(x.name));
55+
56+
const classesOrModules = symbols.filter(x=>x.kind===vscode.SymbolKind.Class
57+
|| x.kind===vscode.SymbolKind.Module);
58+
59+
60+
//If the logical name resolves to a class or module, our job isn't done
61+
for (const c of classesOrModules){
62+
const textDoc = await vscode.workspace.openTextDocument(c.location.uri);
63+
const docInfo = await this._documentInfoProvider.getDocumentInfo(textDoc);
64+
65+
if (docInfo){
66+
range = this._commonLogic.findInDocument(docInfo,pathInfo);
67+
if (range){
68+
return new vscode.Location(textDoc.uri,range);
69+
}
70+
}
71+
}
72+
73+
var methodMatches =
74+
symbols.filter(symbol=>(symbol.kind===vscode.SymbolKind.Function ||
75+
symbol.kind===vscode.SymbolKind.Method));
76+
77+
78+
if (pathInfo.methodName){
79+
methodMatches=methodMatches.filter(method=>{
80+
if (pathInfo.methodName){
81+
return method.name.endsWith(pathInfo.methodName);
82+
}
83+
});
84+
}
85+
86+
if (pathInfo.moduleLogicalPath){
87+
methodMatches=methodMatches.filter(method=>{
88+
if (pathInfo.moduleLogicalPath){
89+
return pathInfo.moduleLogicalPath.endsWith(method.name);
90+
}
91+
});
5392
}
93+
94+
if (methodMatches.length === 1){
95+
return methodMatches[0].location;
96+
}
97+
98+
if (classesOrModules.length==1){
99+
return classesOrModules[0].location;
100+
101+
}
102+
//We have a match
103+
54104
}
55105
}
56106

@@ -59,9 +109,41 @@ export class LogicalModulePathToUriConverter implements IModulePathToUriConverte
59109
}
60110
}
61111

112+
export class CommonConverterLogic{
113+
public findInDocument(docInfo: DocumentInfo, pathInfo: PossibleCodeObjectLocation): vscode.Range|undefined{
114+
let range:vscode.Range|undefined = undefined;
115+
if (pathInfo.lineNumber){
116+
range=
117+
new vscode.Range(
118+
new vscode.Position(pathInfo.lineNumber,0),
119+
new vscode.Position(pathInfo.lineNumber+1,0));
120+
}
121+
else if (pathInfo.spanName){
122+
var span = docInfo?.spans.filter(x=>x.name==pathInfo.spanName).firstOrDefault();
123+
if (span){
124+
range=new vscode.Range(new vscode.Position(span.range.start.line+1, span.range.start.character),
125+
new vscode.Position(span.range.start.line+2,span.range.start.character+1)); }
126+
}
127+
128+
else if (pathInfo.methodName){
129+
var method = docInfo?.methods.filter(x=>{
130+
const methoId = x.id.split("$_$").lastOrDefault();
131+
if (!methoId){return false};
132+
return methoId===pathInfo.methodName;
133+
}).firstOrDefault();
134+
if (method){
135+
range=new vscode.Range(new vscode.Position(method.range.start.line+1, method.range.start.character),
136+
new vscode.Position(method.range.start.line+2,method.range.start.character+1));
137+
}
138+
}
139+
140+
return range;
141+
}
142+
}
62143

63144
export class PhysicalModulePathToUriConverter implements IModulePathToUriConverter {
64145

146+
readonly _commonLogic: CommonConverterLogic = new CommonConverterLogic()
65147
constructor(
66148
private _specialFolders: string[],
67149
private _documentInfoProvider: DocumentInfoProvider){
@@ -143,27 +225,13 @@ export class PhysicalModulePathToUriConverter implements IModulePathToUriConvert
143225

144226
const textDoc = await vscode.workspace.openTextDocument(fileUri);
145227
const docInfo = await this._documentInfoProvider.getDocumentInfo(textDoc);
146-
if (pathInfo.lineNumber){
147-
range=
148-
new vscode.Range(
149-
new vscode.Position(pathInfo.lineNumber,0),
150-
new vscode.Position(pathInfo.lineNumber+1,0));
151-
}
152-
else if (pathInfo.spanName){
153-
var span = docInfo?.spans.filter(x=>x.name==pathInfo.spanName).firstOrDefault();
154-
if (span){
155-
range=new vscode.Range(new vscode.Position(span.range.start.line+1, span.range.start.character),
156-
new vscode.Position(span.range.start.line+2,span.range.start.character+1)); }
157-
}
228+
229+
if (docInfo){
230+
range = this._commonLogic.findInDocument(docInfo,pathInfo);
158231

159-
else if (pathInfo.methodName){
160-
var method = docInfo?.methods.filter(x=>x.name==pathInfo.methodName).firstOrDefault();
161-
if (method){
162-
range=new vscode.Range(new vscode.Position(method.range.start.line+1, method.range.start.character),
163-
new vscode.Position(method.range.start.line+2,method.range.start.character+1));
164-
}
165232
}
166-
if (!fileUri || !range){
233+
234+
if ( !range){
167235
return undefined;
168236
}
169237

src/services/languages/python/languageExtractor.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { DocumentInfoProvider } from '../../documentInfoProvider';
1515
export class PythonLanguageExtractor extends LanguageExtractor {
1616
public get guessCodeObjectLocation(): ICodeObjectLocationGuesser[] {
1717
return [
18-
new GuessLocationByDefaultCodeObjectIdSchema(PythonConstants.pythonFileSuffix),
18+
new GuessLocationByDefaultCodeObjectIdSchema(PythonConstants.pythonFileSuffix,false),
1919
new GuessLocationByInstrumentationLibrary()
2020
];
2121
}

src/services/methodCallErrorTooltip.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ class MethodCallErrorHoverProvider implements vscode.HoverProvider
8181

8282
private async getMethodMarkdown(methodInfo: MethodInfo): Promise<vscode.MarkdownString | undefined>
8383
{
84-
const errors = await this._documentInfoProvider.analyticsProvider.getCodeObjectsErrors([methodInfo.symbol.id]);
84+
const errors = await this._documentInfoProvider.analyticsProvider.getCodeObjectsErrors(methodInfo.idsWithType);
8585
if(!errors?.length)
8686
return;
8787

src/views/codeAnalytics/InsightListView/SpanInsight.ts

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,35 +23,45 @@ export interface SpanUsagesInsight extends CodeObjectInsight
2323
percentage: Number,
2424
firstService:{
2525
service: string,
26-
span: string
26+
span: string,
27+
codeObjectId: string
2728
},
2829
intermediateSpan: string | undefined,
2930
lastService:{
3031
service: string,
31-
span: string
32+
span: string,
33+
codeObjectId: string
34+
3235
} | undefined,
3336
lastServiceSpan: string | undefined
3437
}[]
3538
}
3639
export class SpanUsagesListViewItemsCreator implements IInsightListViewItemsCreator
3740
{
38-
public constructor(private _viewUris:WebViewUris){
41+
public constructor(private _viewUris:WebViewUris,
42+
private _spanLinkResolver: SpanLinkResolver){
3943

4044
}
4145
public async create( codeObjectsInsight: SpanUsagesInsight []): Promise<IListViewItemBase []>
4246
{
43-
return codeObjectsInsight.map(x=>this.createListViewItem(x));
47+
const result = await await Promise.all(codeObjectsInsight.map(async x=> await this.createListViewItem(x)));
48+
return result;
4449
}
4550

46-
public createListViewItem(insight: SpanUsagesInsight) : IListViewItem
51+
public async createListViewItem(insight: SpanUsagesInsight) : Promise<IListViewItem>
4752
{
53+
4854
// <span class="codicon codicon-server-process" style="margin-right: 3px;"></span>
49-
const usages = insight.flows.map(flow => {
55+
const usages = await Promise.all( insight.flows.map(async flow => {
5056

57+
var firstServiceLocation = await this._spanLinkResolver.searchForSpanByHints({
58+
spanName :flow.firstService.span,
59+
codeObjectId: flow.firstService.codeObjectId,
60+
});
5161
let firstServiceHtml = /*html*/`
5262
<span class="flow-entry ellipsis" title="${flow.firstService.service}: ${flow.firstService.span}">
5363
<span class="flow-service">${flow.firstService.service}:</span>
54-
<span class="flow-span">${flow.firstService.span}</span>
64+
<span class="flow-span span-name ${firstServiceLocation ? "link" : ""}" data-code-uri="${firstServiceLocation?.documentUri}" data-code-line="${firstServiceLocation?.range.end.line!+1}">${flow.firstService.span}</span>
5565
</span>`;
5666

5767
let lastServiceHtml = '';
@@ -89,7 +99,7 @@ export class SpanUsagesListViewItemsCreator implements IInsightListViewItemsCrea
8999
${traceHtml}
90100
</span>
91101
</div>`;
92-
});
102+
}));
93103

94104
const template = new InsightTemplateHtml({
95105
title: "Top Usage",
@@ -138,6 +148,7 @@ export interface SpanDurationsInsight extends CodeObjectInsight{
138148
export interface SpanDurationBreakdownEntry {
139149
spanName: string,
140150
spanDisplayName: string,
151+
codeObjectId:string,
141152
spanInstrumentationLibrary: string,
142153
spanCodeObjectId: string,
143154
percentiles: {
@@ -239,7 +250,7 @@ export class SpanDurationBreakdownListViewItemsCreator implements IInsightListVi
239250
return {
240251
instrumentationLibrary:o.spanInstrumentationLibrary,
241252
spanName: o.spanName,
242-
codeObjectId: undefined,
253+
codeObjectId: o.codeObjectId,
243254
breakdownEntry: o
244255
};
245256
});

src/views/codeAnalytics/codeAnalyticsView.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -197,7 +197,7 @@ class CodeAnalyticsViewProvider implements vscode.WebviewViewProvider,vscode.Dis
197197
listViewItemsCreator.setUnknownTemplate(new UnknownInsightInsight(this._webViewUris));
198198
listViewItemsCreator.add("HotSpot", new HotspotListViewItemsCreator(this._webViewUris));
199199
listViewItemsCreator.add("Errors", new ErrorsListViewItemsCreator(this._webViewUris));
200-
listViewItemsCreator.add("SpanUsages", new SpanUsagesListViewItemsCreator(this._webViewUris));
200+
listViewItemsCreator.add("SpanUsages", new SpanUsagesListViewItemsCreator(this._webViewUris, this._spanLinkResolver));
201201
listViewItemsCreator.add("SpanDurations", new SpanDurationsListViewItemsCreator(this._webViewUris));
202202
listViewItemsCreator.add("SpanDurationBreakdown", new SpanDurationBreakdownListViewItemsCreator(this._webViewUris, _spanLinkResolver));
203203
listViewItemsCreator.add("SlowestSpans", new SlowestSpansListViewItemsCreator(this._webViewUris, editorHelper,_documentInfoProvider,this._channel,_spanLinkResolver));

0 commit comments

Comments
 (0)