Skip to content

Commit d3d3d82

Browse files
committed
AEDebugging_ Add stack info to created event and show in timeline
SQUASHED: AUTO-COMMIT-src-client-reactive-active-expression-active-expression.js,AUTO-COMMIT-src-client-reactive-active-expression-rewriting-active-expression-rewriting.js,AUTO-COMMIT-src-client-reactive-components-basic-aexpr-timeline.js,AUTO-COMMIT-src-client-utils-stack.js,AUTO-COMMIT-src-client-utils-stack.js.l4a,
1 parent 8c53d96 commit d3d3d82

File tree

5 files changed

+118
-51
lines changed

5 files changed

+118
-51
lines changed

src/client/reactive/active-expression-rewriting/active-expression-rewriting.js

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -974,12 +974,7 @@ class TracingHandler {
974974

975975
for (let frame of frames.slice()) {
976976
if (!frame.file.includes("active-expression")) {
977-
const loc = await frame.getSourceLoc();
978-
return {
979-
start: { line: loc.line, column: loc.column },
980-
end: { line: loc.line, column: loc.column },
981-
file: loc.source
982-
};
977+
return await frame.getSourceLocBabelStyle();
983978
}
984979
}
985980
return undefined;

src/client/reactive/active-expression/active-expression.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,7 @@ export class BaseActiveExpression {
213213
}
214214

215215
this.initializeEvents();
216-
this.logEvent('created', this);
216+
this.logEvent('created', {ae: this, stack: lively.stack()});
217217

218218
if (new.target === BaseActiveExpression) {
219219
this.addToRegistry();
@@ -333,8 +333,6 @@ export class BaseActiveExpression {
333333
this.storeResult(value);
334334
Promise.resolve(location)
335335
.then(trigger => this.logEvent('changed value', { value, trigger, lastValue }));
336-
//this.findCallee().then(trigger => {
337-
//});
338336

339337
this.notify(value, {
340338
lastValue,
@@ -349,7 +347,7 @@ export class BaseActiveExpression {
349347

350348
for (let frame of frames) {
351349
if (!frame.file.includes("active-expression") && frame.file !== "<anonymous>") {
352-
return await frame.getSourceLoc();
350+
return await frame.getSourceLocBabelStyle();
353351
}
354352
}
355353
return undefined;

src/client/reactive/components/basic/aexpr-timeline.js

Lines changed: 106 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import jQuery from 'src/external/jquery.js';
77
import jstree from 'src/external/jstree/jstree.js';
88
import d3 from 'src/external/d3.v5.js';
99
import { debounce } from "utils";
10+
import ContextMenu from 'src/client/contextmenu.js';
1011

1112
import { AExprRegistry } from 'src/client/reactive/active-expression/active-expression.js';
1213

@@ -48,44 +49,14 @@ export default class EventDrops extends Morph {
4849
return 'black';
4950
}
5051
},
51-
onClick: data => {
52-
switch (data.type) {
53-
case 'changed value':
54-
{
55-
const location = data.value.trigger;
56-
this.openLocationInBrowser(location);
57-
58-
break;
59-
}
60-
case 'created':
61-
case 'disposed':
62-
{
63-
const ae = data.value;
64-
const location = ae.meta().get("location");
65-
this.openLocationInBrowser(location);
66-
break;
67-
}
68-
case 'dependencies changed':
69-
default:
70-
{
71-
lively.openInspector(data);
72-
break;
73-
}
74-
}
52+
onClick: (data, index, group) => {
53+
this.eventClicked(data, group[index]);
7554
},
76-
onMouseOver: event => {
77-
this.tooltip.transition().duration(200).style('opacity', 1).style('pointer-events', 'auto');
78-
this.tooltip.html('');
79-
this.tooltip.append(() => <div class="event">
80-
<div class="content">
81-
<h3 style="font-size: 1em">{event.type}</h3>
82-
<span style="font-size: 1em">{this.humanizeEventData(event)}</span>
83-
<p style="font-size: 1em">at {this.humanizeDate(event.timestamp)}</p>
84-
</div>
85-
</div>);
86-
lively.setGlobalPosition(this.tooltip.node(), lively.pt(d3.event.clientX + 3, d3.event.clientY + 3));
55+
onMouseOver: (event, index, group) => {
56+
this.eventHover(event, group[index]);
8757
},
88-
onMouseOut: () => {
58+
onMouseOut: (data, index, group) => {
59+
group[index].setAttribute("r", 5);
8960
this.tooltip.transition().duration(500).style('opacity', 0).style('pointer-events', 'none');
9061
}
9162
}
@@ -148,23 +119,114 @@ export default class EventDrops extends Morph {
148119
});
149120
}
150121

122+
eventHover(event, circleObject) {
123+
circleObject.setAttribute("r", 10);
124+
this.tooltip.transition().duration(200).style('opacity', 1).style('pointer-events', 'auto');
125+
this.tooltip.html('');
126+
const eventDiv = <div class="event"></div>;
127+
const contentDiv = <div class="content">
128+
<h3 style="font-size: 1em">{event.type}</h3>
129+
</div>;
130+
131+
const appendData = data => {
132+
//contentDiv.append(<div></div>);
133+
const lol = <span style="font-size: 1em">{data}</span>;
134+
contentDiv.append(lol);
135+
};
136+
137+
this.humanizeEventData(event).then(eventData => {
138+
if (eventData.length) {
139+
for (const data of eventData) {
140+
appendData(data);
141+
}
142+
} else {
143+
appendData(eventData);
144+
}
145+
contentDiv.append(<p style="font-size: 1em">at {this.humanizeDate(event.timestamp)}</p>);
146+
eventDiv.append(contentDiv);
147+
this.tooltip.append(() => eventDiv);
148+
});
149+
lively.setGlobalPosition(this.tooltip.node(), lively.pt(d3.event.clientX + 3, d3.event.clientY + 3));
150+
}
151+
152+
async eventClicked(data, circleObject) {
153+
circleObject.setAttribute("r", 10);
154+
const menuItems = [];
155+
menuItems.push(["inspect", () => {
156+
lively.openInspector(data);
157+
}, "", "l"]);
158+
159+
const event = d3.event;
160+
switch (data.type) {
161+
case 'changed value':
162+
{
163+
const location = data.value.trigger;
164+
menuItems.push(["open location", () => {
165+
this.openLocationInBrowser(location);
166+
}, "", "o"]);
167+
break;
168+
}
169+
case 'created':
170+
{
171+
const ae = data.value.ae;
172+
const aeLocation = ae.meta().get("location");
173+
const stack = data.value.stack;
174+
const locations = await Promise.all(stack.frames.map(frame => frame.getSourceLocBabelStyle()));
175+
locations.forEach((location, index) => {
176+
const isAELoaction = aeLocation.file === location.file && aeLocation.start.line === location.start.line;
177+
menuItems.push([this.fileNameString(location.file) + ":" + location.start.line, () => {
178+
this.openLocationInBrowser(isAELoaction ? aeLocation : location);
179+
}, isAELoaction ? "aexpr call" : "", index + 1]);
180+
});
181+
break;
182+
}
183+
case 'disposed':
184+
{
185+
const ae = data.value;
186+
const location = ae.meta().get("location");
187+
menuItems.push(["open location", () => {
188+
this.openLocationInBrowser(location);
189+
}, "", "o"]);
190+
break;
191+
}
192+
case 'dependencies changed':
193+
default:
194+
{
195+
break;
196+
}
197+
}
198+
//group[index].getBoundingClientRect()
199+
const menu = await ContextMenu.openIn(document.body, event, undefined, document.body, menuItems);
200+
menu.addEventListener("DOMNodeRemoved", () => {
201+
this.focus();
202+
});
203+
}
204+
151205
openLocationInBrowser(location) {
152206
const start = { line: location.start.line - 1, ch: location.start.column };
153207
const end = { line: location.end.line - 1, ch: location.end.column };
154208
lively.files.exists(location.file).then(exists => {
155-
if(exists) {
209+
if (exists) {
156210
lively.openBrowser(location.file, true, { start, end }, false, undefined, true);
157211
} else {
158212
lively.notify("Unable to find file:" + location.file);
159213
}
160214
});
161215
}
162216

163-
humanizeEventData(event) {
217+
async humanizeEventData(event) {
164218
switch (event.type) {
165219
case 'changed value':
166220
return <div>{this.humanizePosition(event.value.trigger.file, event.value.trigger.start.line)} <br /> <span style="color:#00AAAA">{event.value.lastValue}</span><span style="color:#00AAAA">{event.value.value}</span></div>;
167221
case 'created':
222+
{
223+
const ae = event.value.ae;
224+
/*const stack = event.value.stack;
225+
const locations = await Promise.all(stack.frames.map(frame => frame.getSourceLoc()));
226+
return locations.map(location => this.humanizePosition(location.source, location.line));*/
227+
const location = ae.meta().get("location");
228+
return this.humanizePosition(location.file, location.start.line);
229+
}
168230
case 'disposed':
169231
{
170232
const ae = event.value;
@@ -180,7 +242,7 @@ export default class EventDrops extends Morph {
180242
get tooltip() {
181243
let existing = document.body.querySelectorAll('#event-drops-tooltip')[0];
182244

183-
return existing ? d3.select(existing) : d3.select('body').append('div').attr('id', 'event-drops-tooltip').classed('tooltip', true).style('opacity', 0).style('width', '200px').style('box-sizing', 'border-box').style('border', '10px solid transparent').style('background-color', '#EEEEEE').style('z-index', 500).style('pointer-events', 'auto');
245+
return existing ? d3.select(existing) : d3.select('body').append('div').attr('id', 'event-drops-tooltip').classed('tooltip', true).style('opacity', 0).style('width', '350px').style('box-sizing', 'border-box').style('border', '10px solid transparent').style('background-color', '#EEEEEE').style('z-index', 500).style('pointer-events', 'auto');
184246
}
185247

186248
getDataFromSource() {
@@ -331,7 +393,11 @@ export default class EventDrops extends Morph {
331393
`;
332394
}
333395
humanizePosition(file, line) {
334-
return <div>in <span style="color:#0000FF">{file.substring(file.lastIndexOf('/') + 1)}</span> line <span style="color:#0000FF">{line}</span></div>;
396+
return <div>in <span style="color:#0000FF">{this.fileNameString(file)}</span> line <span style="color:#0000FF">{line}</span></div>;
397+
}
398+
399+
fileNameString(file) {
400+
return file.substring(file.lastIndexOf('/') + 1);
335401
}
336402

337403
livelyMigrate(other) {

src/client/utils/stack.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,14 @@ export class Frame {
202202
return this._char;
203203
}
204204

205+
async getSourceLocBabelStyle() {
206+
if(!this._sourceLoc) {
207+
await this._determineSourceInfo();
208+
}
209+
const location = {line: this._sourceLoc.line, column: this._sourceLoc.column};
210+
return {start: location, end: location, file: this._sourceLoc.source};
211+
}
212+
205213
async getSourceLoc() {
206214
if(!this._sourceLoc) {
207215
await this._determineSourceInfo();

0 commit comments

Comments
 (0)