Skip to content

Commit 1ba8283

Browse files
committed
minor bug fixes and documentation
SQUASHED: AUTO-COMMIT-demos-tom-copyAST.js,AUTO-COMMIT-demos-tom-index.md,AUTO-COMMIT-demos-tom-playground.js,AUTO-COMMIT-demos-tom-plugin-explorer-worker.js,AUTO-COMMIT-demos-tom-trace.js,AUTO-COMMIT-demos-tom-TraceLogParser.js,AUTO-COMMIT-demos-tom-wrapAST.js,AUTO-COMMIT-src-components-tools-lively-plugin-explorer-playground.workspace,AUTO-COMMIT-src-components-tools-trace-visualization.js,
1 parent 82f8fe7 commit 1ba8283

File tree

9 files changed

+102
-94
lines changed

9 files changed

+102
-94
lines changed

demos/tom/TraceLogParser.js

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,6 @@ export default class TraceLogParser {
1212
constructor(trace) {
1313
this.trace = trace;
1414
this.index = 0;
15-
16-
this.functionNesting = 0;
17-
this.conditionNesting = 0;
1815
}
1916

2017
get log() {
@@ -76,13 +73,13 @@ export default class TraceLogParser {
7673
if(this.match('leavePlugin')) {
7774
return section;
7875
} else if(this.matchPeek('return')) {
79-
// Todo: escape nested constructs, ie function(condition(return))
8076
const returnEntry = this.consume();
8177
section.addEntry(this.instantiateEvent(returnEntry));
8278

8379
if(returnEntry.position === this.peek().position) {
8480
this.match('left');
8581
}
82+
debugger
8683

8784
throw new EarlyReturn('function');
8885
} else if(this.matchPeek('leave')) {
@@ -123,18 +120,10 @@ export default class TraceLogParser {
123120
section.addEntry(this.consumeAsEvent());
124121
// break out from nesting
125122
throw new EarlyReturn('error');
126-
}
127-
128-
if(this.conditionNesting > 0) {
129-
if(this.match('endCondition')) {
130-
return section;
131-
}
132-
}
133-
134-
if(this.functionNesting > 0) {
135-
if(this.match('left')) {
136-
return section;
137-
}
123+
} else if(this.match('endCondition')) {
124+
return section;
125+
} else if(this.match('left')) {
126+
return section;
138127
}
139128

140129
section.addEntry(this.consumeAsEvent());
@@ -150,9 +139,7 @@ export default class TraceLogParser {
150139

151140
section.addEntry(condition);
152141

153-
this.conditionNesting++;
154142
this.defaultParse(condition, higherSections);
155-
this.conditionNesting--;
156143

157144
return condition;
158145
}
@@ -168,9 +155,6 @@ export default class TraceLogParser {
168155

169156
section.addEntry(fun);
170157

171-
const oldNestingLevel = this.conditionNesting;
172-
this.functionNesting++;
173-
174158
try {
175159
this.defaultParse(fun, higherSections);
176160
} catch(e) {
@@ -181,10 +165,6 @@ export default class TraceLogParser {
181165
}
182166
}
183167

184-
// restore condition nesting level as we maybe escaped from one without properly doing so
185-
this.conditionNesting = oldNestingLevel;
186-
this.functionNesting--;
187-
188168
return fun;
189169
}
190170

demos/tom/copyAST.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ function copyArrayOfRound(arr, roundNumber) {
88
return copy;
99
}
1010

11+
// Todo: merge wrap and copy => copy all nodes without traceID
12+
// roundNumber could result in unncessary copies as in one round there could be multiple edits
1113
export default function copyASTPartsOfRound(object, roundNumber) {
1214
// simply check if the object is an astNode
1315
if (object && object.type) {
@@ -37,7 +39,6 @@ export default function copyASTPartsOfRound(object, roundNumber) {
3739
// ignore functions
3840
break;
3941
case 'object':
40-
// assume it is an astNode
4142
objectCopy[key] = copyASTPartsOfRound(value, roundNumber);
4243
break;
4344
default:

demos/tom/index.md

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,26 @@
1-
Todo: write
1+
2+
## AST worker
3+
Der AST worker nimmt source code und ein Array von Plugin Urls entgegen und generiert aus diesen einen Trace der Ausführung. Dieser Prozess wurde in eine WebWorker ausgelagert, um eine frische JavaScript Umgebung zu erhalten. Normalerweise hat lively ein vorkonfiguriertes SystemJS, welches sich um imports von Files kümmert. Im WebWorker kann SystemJS so konfiguriert werden, dass nur das Trace Plugin auf allen importierten Code angewandt wird (wodurch auch imports von Plugins mit dem nötigen Trace code versehen werden).
4+
5+
## Trace
6+
Trace ist die zentrale Klasse, für welche während der gesamten Aufzeichnung der Plugins sichergestellt ist, dass sie global über ```window[Trace.traceIdentifierName]``` verfügbar ist.
7+
8+
Ihre Aufgabe ist es zum einen den Tracelog zu generieren und zu speichern. Dazu stellt die Klasse Methode bereit, die die nötigen Instanzen von ```Event```, ```ErrorEvent``` oder ```ASTChangeEvent``` mit den nötigen Daten erstellen.
9+
10+
Auch erstellt der Trace die IDs für AST Knoten, die aus der Nummer der aktuell ausgeführten Pluginmethode (leider nur der aus den Babelplugins und nicht den in ```NodePath.traverse``` aufgerufenden Methoden) und einer für den gesamten AST globalen Nummer.
11+
12+
Trace registriert weiterhin die Positionen von AST Knoten im Quelltext und speichert diese mit einigen Optimierungen. Die dadurch vergebenen Positions-IDs kann Trace auh wieder auflösen.
13+
14+
## Events
15+
16+
## TraceLogParser
17+
Der ```TraceLogParser``` ist ein recursive Descent Parser, der dafür verantwortlich ist den generierten Log zu säubern und zusammengehörige Events zusammenzufassen. Es erzeugt aus den ```Event```s eine Composite aus ```TraceSection``` und ```Event```s.
218

319

420
## Debug Trace-Plugin
21+
Es ist möglich das tracer-plugin mit sich selbst zu debuggen. Dazu wird einfach eine Kopie des Plugins (aktuell in demos/tom/plugin-backup.js) an den WebWorker übergeben als Plugin übergeben. Die Kopie ist nötig, da SystemJS das tracer-plugin ganz am Anfang laden muss und dies nun gecached vorhält. Würde man versuchen das originale tracer-plugin noch einmal zu laden würde einfach auf diese Version zugegriffen werden, anstatt das Plugin zu transformieren. Dies wird mit diesem Workaround eines zweiten Files umgangen.
22+
23+
**Sollte die Kopie zur Weiterentwicklung verwendet werden, nicht vergessen die gewünschten Änderungen am Ende in das originale Plugin zu kopieren.**
524

625

726
## Future ideas

demos/tom/playground.js

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -2,20 +2,14 @@ export default function({types: t}) {
22
return {
33
name: 'test',
44
visitor: {
5-
FunctionDeclaration(path) {
6-
if(path.node.alreadyVisited) {
7-
return;
8-
}
9-
10-
const returnNode = t.returnStatement(t.arrowFunctionExpression([], t.numericLiteral(5)));
11-
12-
const node = t.functionDeclaration(
13-
path.node.id,
14-
[],
15-
t.blockStatement([returnNode]));
16-
node.alreadyVisited = true;
17-
18-
path.replaceWith(node);
5+
Conditional(path) {
6+
debugger
7+
path.get('test').insertAfter(t.stringLiteral('afterTest'));
8+
},
9+
10+
AssignmentExpression(path) {
11+
debugger
12+
path.node.loc.start
1913
}
2014
}
2115
}

demos/tom/plugin-explorer-worker.js

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ async function unloadModule(path) {
5454
System.registry.delete(normalizedPath);
5555
// #Hack #issue in SystemJS babel syntax errors do not clear errors
5656
System['@@registerRegistry'][normalizedPath] = undefined;
57+
debugger
5758
delete System.loads[normalizedPath]
5859
}
5960

@@ -106,6 +107,10 @@ self.onmessage = function(msg) {
106107
}
107108
});
108109

110+
const preloadedPlugins = new Set(Object.keys(System['@@registerRegistry']));
111+
112+
debugger
113+
109114
const trace = new Trace();
110115
// make it globally available for use in plugins
111116
window[Trace.traceIdentifierName] = trace;
@@ -140,15 +145,20 @@ self.onmessage = function(msg) {
140145
result = null;
141146
trace.error(e);
142147
}
143-
144-
postMessage({
145-
oldAST: oldASTAsString,
146-
transformedAST: JSON.stringify(result && result.ast),
147-
transformedCode: result && result.code,
148-
trace: trace.serialize()
149-
});
150-
151-
msg.data.urls.forEach(unloadModule)
148+
debugger;
149+
150+
const pluginsToUnload = Object.keys(System['@@registerRegistry']).filter(plugin => !
151+
preloadedPlugins.has(plugin));
152+
153+
Promise.all(pluginsToUnload.map(unloadModule))
154+
.then(_ => {
155+
postMessage({
156+
oldAST: oldASTAsString,
157+
transformedAST: JSON.stringify(result && result.ast),
158+
transformedCode: result && result.code,
159+
trace: trace.serialize()
160+
});
161+
})
152162
})
153163
})
154164
}

demos/tom/trace.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as _ from 'src/external/lodash/lodash.js';
22
import loadPlugin from 'demos/tom/plugin-load-promise.js';
3-
import { ErrorEvent, Event, ASTChangeEvent, eventTypes } from 'demos/tom/Events.js';
3+
import { ErrorEvent, Event, ASTChangeEvent } from 'demos/tom/Events.js';
44
import TraceLogParser from 'demos/tom/TraceLogParser.js';
55

66
function clone(object) {

demos/tom/wrapAST.js

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,15 +23,13 @@ function createObservingAccessorsOn(object, propertyName, observer) {
2323
const handler = (observer, key) => {
2424
return {
2525
set: function(obj, prop, value) {
26-
// Todo: Reflect.set()
2726
if (Number.isInteger(Number.parseInt(prop))) {
2827
const pluginRound = window[Trace.traceIdentifierName].pluginRound;
29-
debugger
3028
wrapAST(value, observer, true);
3129
observer.notify(prop, copyAST(obj[prop], pluginRound), copyAST(value, pluginRound), key);
3230
}
33-
obj[prop] = value;
34-
return true;
31+
32+
return Reflect.set(obj, prop, value);
3533
}
3634
}
3735
};
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
{"source":"/src/components/tools/lively-ast-explorer-example-source.js","plugin":"https://lively-kernel.org/lively4/lively4-tom/demos/tom/playground.js","options":{"autoUpdateAST":true,"autoUpdateTransformation":true,"autoExecute":true,"systemJS":false,"autoRunTests":false,"autoSaveWorkspace":false},"pluginSelection":[{"url":"https://lively-kernel.org/lively4/lively4-tom/demos/tom/playground.js"}]}
1+
{"source":"/src/components/tools/lively-ast-explorer-example-source.js","plugin":"https://lively-kernel.org/lively4/lively4-tom/src/client/reactive/babel-plugin-active-expression-rewriting/index.js","options":{"autoUpdateAST":true,"autoUpdateTransformation":true,"autoExecute":true,"systemJS":false,"autoRunTests":false,"autoSaveWorkspace":false},"pluginSelection":[{"url":"https://lively-kernel.org/lively4/lively4-tom/src/client/reactive/babel-plugin-active-expression-rewriting/index.js"}]}

src/components/tools/trace-visualization.js

Lines changed: 44 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ export default class TraceVisualization extends Morph {
3434
this.setCurrentAST(trace.oldAST);
3535
}
3636

37-
/* UI access */
37+
/*MD ## UI access MD*/
3838

3939
get traceList() {
4040
return this.get('#traceList');
@@ -62,13 +62,38 @@ export default class TraceVisualization extends Morph {
6262
}
6363
this.comparison.updateView(this.curAST, this.nextAST);
6464
}
65+
66+
async setEditorURL(newURL) {
67+
if (this.currentURL !== newURL) {
68+
this.editor.setURL(newURL);
69+
this.currentURL = newURL;
70+
await this.editor.loadFile();
71+
}
72+
}
6573

66-
/* update List */
74+
/*MD ## Update list MD*/
6775

6876
clearList() {
6977
this.traceList.innerHTML = '';
7078
}
7179

80+
markAndScrollTo(position) {
81+
this.editorDoc.scrollIntoView({
82+
line: position.startLine - 1,
83+
ch: position.startColumn
84+
}, 200);
85+
86+
this.lastMark = this.editorDoc.markText({
87+
line: position.startLine - 1,
88+
ch: position.startColumn
89+
}, {
90+
line: position.endLine - 1,
91+
ch: position.endColumn
92+
}, {
93+
css: 'background: #eee'
94+
});
95+
}
96+
7297
setSubEntryEventListener(subEntry, elm, path) {
7398
subEntry.addEventListener('mouseover', async e => {
7499
// prevent outer mouseover listener to overwrite this action
@@ -78,32 +103,14 @@ export default class TraceVisualization extends Morph {
78103
this.lastMark.clear();
79104
}
80105

81-
this.updateAST(path, elm);
106+
this.updateASTs(path, elm);
82107

83108
const position = this.trace.resolve(elm.position);
84-
if(!position) {
85-
return;
86-
}
87-
if (this.currentURL !== position.filename) {
88-
this.editor.setURL(position.filename);
89-
this.currentURL = position.filename;
90-
await this.editor.loadFile();
109+
110+
if(position) {
111+
await this.setEditorURL(position.filename);
112+
this.markAndScrollTo(position);
91113
}
92-
93-
this.editorDoc.scrollIntoView({
94-
line: position.startLine - 1,
95-
ch: position.startColumn
96-
}, 200);
97-
98-
this.lastMark = this.editorDoc.markText({
99-
line: position.startLine - 1,
100-
ch: position.startColumn
101-
}, {
102-
line: position.endLine - 1,
103-
ch: position.endColumn
104-
}, {
105-
css: 'background: #eee'
106-
});
107114
});
108115
}
109116

@@ -172,16 +179,13 @@ export default class TraceVisualization extends Morph {
172179
}
173180
}
174181

175-
/* update AST */
182+
/*MD ## Update AST MD*/
176183

177184
setCurrentAST(ast) {
178-
// this.currentAST.inspect(ast);
179185
this.currentAST.value = babel.transformFromAst(ast).code
180186
}
181187

182-
setTransformedAST(ast) {
183-
// this.transformedAst.inspect(ast);
184-
188+
setTransformedAST(ast) {
185189
this.transformedAst.value = babel.transformFromAst(ast).code
186190
}
187191

@@ -194,24 +198,26 @@ export default class TraceVisualization extends Morph {
194198
}
195199
}
196200

197-
updateAST(path, entry) {
198-
this.curAST = JSON.parse(JSON.stringify(this.trace.oldAST));
199-
this.nextAST;
200-
201-
debugger
202-
201+
walkPath(path, ast) {
203202
let entries = this.trace.sections;
204203

205204
for (const part of path) {
206205
for (const entry of entries) {
207206
if(entry === part) {
208207
break;
209208
}
210-
entry.apply(this.curAST)
209+
entry.apply(ast);
211210
}
212211
entries = part.entries;
213212
}
214-
213+
214+
return entries;
215+
}
216+
217+
updateASTs(path, entry) {
218+
this.curAST = JSON.parse(JSON.stringify(this.trace.oldAST));
219+
220+
const entries = this.walkPath(path, this.curAST);
215221
const index = entries.indexOf(entry);
216222

217223
for (let i = 0; i < index; i++) {

0 commit comments

Comments
 (0)