Skip to content

Commit b2cdb4a

Browse files
committed
first step for tracing plugin execution
SQUASHED: AUTO-COMMIT-demos-tom-babel-plugin-tracer.js,AUTO-COMMIT-demos-tom-babel-plugin-tracer.md,AUTO-COMMIT-demos-tom-playground.js,AUTO-COMMIT-demos-tom-plugin-explorer-systemjs-config.js,AUTO-COMMIT-demos-tom-plugin-explorer-worker.js,AUTO-COMMIT-demos-tom-plugin-explorer-worker.md,AUTO-COMMIT-demos-tom-plugin-load-promise.js,AUTO-COMMIT-demos-tom-plugin-load-promise.md,AUTO-COMMIT-demos-tom-trace.js,AUTO-COMMIT-src-babylonian-programming-editor-worker-ast-worker-babel-wrapper.js,AUTO-COMMIT-src-client-reactive-reactive-jsx-babel-plugin-jsx-lively.js,AUTO-COMMIT-src-components-demo-lively-whyline-example.js,AUTO-COMMIT-src-components-demo-lively-whyline.js,AUTO-COMMIT-src-components-tools-babel-plugin-explorer-playground.js,AUTO-COMMIT-src-components-tools-lively-plugin-explorer.js,AUTO-COMMIT-src-components-tools-lively-plugin-explorer-playground2.workspace,AUTO-COMMIT-src-components-tools-lively-plugin-explorer-playground.workspace,AUTO-COMMIT-src-components-tools-plugin-selector.js,AUTO-COMMIT-src-external-babel-plugin-syntax-jsx.js,AUTO-COMMIT-src-external-babel-plugin-var-recorder-explanation.md,AUTO-COMMIT-src-external-babel-plugin-var-recorder.js,AUTO-COMMIT-src-external-systemjs-system.src.js,
1 parent 7ce5b79 commit b2cdb4a

14 files changed

+306
-62
lines changed

demos/tom/babel-plugin-tracer.js

Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import Trace from 'demos/tom/trace.js';
2+
3+
export default function({ types: t }) {
4+
function error(path, message) {
5+
throw path.buildCodeFrameError(message);
6+
}
7+
8+
const returnVisitor = {
9+
ReturnStatement(path) {
10+
if (path.node.alreadyVisited) {
11+
return;
12+
}
13+
path.node.alreadyVisited = true;
14+
const log = callOnTrace('return');
15+
const returnValue = path.node.argument ? path.node.argument : t.identifier('undefined');
16+
path.node.argument = t.sequenceExpression([log, returnValue])
17+
}
18+
}
19+
20+
function callOnTrace(methodName, args = []) {
21+
return t.callExpression(t.memberExpression(t.identifier(Trace.traceIdenifierName), t.identifier(methodName)),
22+
args);
23+
}
24+
25+
function modifyFunction(name, path) {
26+
const body = path.get('body');
27+
body.unshiftContainer('body', t.expressionStatement(callOnTrace('enterFunction', [t.stringLiteral(name)])));
28+
body.pushContainer('body', t.expressionStatement(callOnTrace('leave')));
29+
path.traverse(returnVisitor);
30+
}
31+
32+
function resolveName(callee) {
33+
if(callee.type === 'MemberExpression') {
34+
return resolveName(callee.object) + `.${callee.property.name}`;
35+
} else if(callee.type === 'CallExpression') {
36+
return resolveName(callee.callee);
37+
} else {
38+
return callee.name;
39+
}
40+
}
41+
42+
function nameFromCallExpression(path) {
43+
const callee = path.node.callee;
44+
if (callee.type === 'MemberExpression') {
45+
46+
return resolveName(callee)
47+
} else {
48+
return callee.name || 'anonymous function';
49+
}
50+
}
51+
52+
return {
53+
name: 'tracer',
54+
visitor: {
55+
CallExpression(path) {
56+
if (path.node.alreadyVisited || path.isGenerated()) {
57+
return;
58+
}
59+
debugger
60+
const name = nameFromCallExpression(path);
61+
path.node.alreadyVisited = true;
62+
const log = callOnTrace('aboutToEnter', [t.stringLiteral(name)]);
63+
const sequence = t.sequenceExpression([log, path.node]);
64+
path.replaceWith(t.expressionStatement(sequence));
65+
},
66+
ArrowFunctionExpression(path) {
67+
68+
},
69+
"ClassMethod|ObjectMethod"(path) {
70+
const name = path.node.key.name;
71+
modifyFunction(name, path);
72+
},
73+
"FunctionDeclaration|FunctionExpression"(path) {
74+
const id = path.node.id;
75+
const name = id ? id.name : 'anonymous function';
76+
modifyFunction(name, path);
77+
}
78+
}
79+
}
80+
}

demos/tom/playground.js

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
export default function foo(a, b) {
2+
deb(); return a + b;
3+
}
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
*
3+
* This file is meant to be importet in the plugin explorer worker via importScript
4+
*
5+
*/
6+
7+
const pluginTransformationPlugin = lively4url + '/demos/tom/babel-plugin-tracer.js';
8+
9+
10+
function makeOptionsObject(plugins) {
11+
return {
12+
babelOptions: {
13+
es2015: false,
14+
stage2: false,
15+
stage3: false,
16+
plugins
17+
}
18+
}
19+
}
20+
const moduleOptionsNon = makeOptionsObject([]);
21+
const pluginOptions = makeOptionsObject([pluginTransformationPlugin])
22+
23+
SystemJS.config({
24+
baseURL: lively4url + '/',
25+
map: {
26+
// #Discussion have to use absolute paths here, because it is not clear what the baseURL is
27+
'plugin-babel': lively4url + '/src/external/babel/plugin-babel2.js',
28+
'systemjs-plugin-babel': lively4url + '/src/external/babel/plugin-babel.js', // seems not to be loaded
29+
'systemjs-babel-build': lively4url + '/src/external/babel/systemjs-babel-browser.js',
30+
31+
// aexpr support
32+
'active-expression': lively4url + '/src/client/reactive/active-expression/active-expression.js',
33+
'active-expression-rewriting': lively4url +
34+
'/src/client/reactive/active-expression-rewriting/active-expression-rewriting.js',
35+
'active-expression-proxies': lively4url +
36+
'/src/client/reactive/active-expression-proxies/active-expression-proxies.js',
37+
'babel-plugin-active-expression-rewriting': lively4url +
38+
'/src/client/reactive/babel-plugin-active-expression-rewriting/index.js',
39+
'babel-plugin-databindings': lively4url + '/src/client/reactive/babel-plugin-databindings/index.js',
40+
'babel-plugin-active-expression-proxies': lively4url +
41+
'/src/client/reactive/babel-plugin-active-expression-proxies/index.js',
42+
'active-expression-frame-based': lively4url +
43+
'/src/client/reactive/active-expression-convention/active-expression-frame-based.js',
44+
'active-group': lively4url + '/src/client/reactive/active-group/select.js',
45+
46+
// jsx support
47+
'babel-plugin-syntax-jsx': lively4url + '/src/external/babel-plugin-syntax-jsx.js',
48+
'babel-plugin-jsx-lively': lively4url + '/src/client/reactive/reactive-jsx/babel-plugin-jsx-lively.js',
49+
'babel-plugin-rp-jsx': lively4url + '/src/client/reactive/rp-jsx/babel-plugin-rp-jsx.js',
50+
'reactive-jsx': lively4url + '/src/client/reactive/reactive-jsx/reactive-jsx.js',
51+
'babel-plugin-rp19-jsx': lively4url + '/src/client/reactive/rp19-jsx/babel-plugin-rp19-jsx.js',
52+
'rp19-jsx': lively4url + '/src/client/reactive/rp19-jsx/rp19-jsx.js',
53+
54+
// estree support
55+
'babel-plugin-estree': lively4url + '/src/external/babel-plugin-estree.js',
56+
57+
// stage 0 support
58+
'babel-plugin-transform-do-expressions': lively4url +
59+
'/src/external/babel-plugin-transform-do-expressions.js',
60+
'babel-plugin-transform-function-bind': lively4url +
61+
'/src/external/babel-plugin-transform-function-bind.js',
62+
'babel-plugin-syntax-do-expressions': lively4url +
63+
'/src/external/babel-plugin-syntax-do-expressions.js',
64+
'babel-plugin-syntax-function-bind': lively4url + '/src/external/babel-plugin-syntax-function-bind.js',
65+
'babel-plugin-syntax-async-generators': lively4url +
66+
'/src/external/babel-plugin-syntax-async-generators.js',
67+
'babel-plugin-syntax-object-rest-spread': lively4url +
68+
'/src/external/babel-plugin-syntax-object-rest-spread.js',
69+
70+
// support for doits
71+
'babel-plugin-doit-result': lively4url + '/src/external/babel-plugin-doit-result.js',
72+
'babel-plugin-doit-this-ref': lively4url + '/src/external/babel-plugin-doit-this-ref.js',
73+
'babel-plugin-doit-async': lively4url + '/src/external/babel-plugin-doit-async.js',
74+
'babel-plugin-locals': lively4url + '/src/external/babel-plugin-locals.js',
75+
'babel-plugin-var-recorder': lively4url + '/src/external/babel-plugin-var-recorder.js',
76+
'babel-plugin-var-recorder-dev': lively4url + '/src/external/babel-plugin-var-recorder-dev.js',
77+
'workspace-loader': lively4url + '/src/client/workspace-loader.js',
78+
79+
// utils
80+
'lang': lively4url + '/src/client/lang/lang.js',
81+
'lang-ext': lively4url + '/src/client/lang/lang-ext.js',
82+
83+
// utils
84+
'utils': lively4url + '/src/client/utils.js'
85+
},
86+
transpiler: 'plugin-babel',
87+
meta: {}
88+
});
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
// first lines copied from src/worker/livelyworker.js
2+
self.window = self;
3+
4+
// as lively4url would not be defined otherwise we need to compute it here
5+
const myPath = '/demos/tom/plugin-explorer-worker.js';
6+
self.lively4url = self.location.toString().replace(myPath, "");
7+
8+
9+
importScripts(lively4url + '/src/external/systemjs/system.src.js');
10+
importScripts(lively4url + '/demos/tom/plugin-explorer-systemjs-config.js')
11+
12+
// not sure why I need this but without it I cannot import the plugins
13+
System.import(pluginTransformationPlugin);
14+
15+
16+
Promise.all(['demos/tom/trace.js', 'systemjs-babel-build'].map(name => System.import(name)))
17+
.then(function(arr) {
18+
const Trace = arr[0].default;
19+
const babel = arr[1].default.babel;
20+
21+
self.onmessage = function(msg) {
22+
const config = {
23+
filename: 'tmpfile.js',
24+
moduleIds: false,
25+
babelrc: false,
26+
};
27+
System.config({
28+
meta: {
29+
'*.js': pluginOptions,
30+
[pluginTransformationPlugin]: moduleOptionsNon
31+
}
32+
})
33+
34+
Promise.all(msg.data.urls.map(url => System.import(url)))
35+
.then(function(modules) {
36+
config.plugins = modules.map(module => module.default);
37+
config.sourceFileName = 'tmpfile.js';
38+
window[Trace.traceIdenifierName] = new Trace();
39+
const result = babel.transform(msg.data.source, config);
40+
debugger
41+
postMessage({transformedAST: JSON.stringify(result.ast), transformedCode: result.code, trace: window[Trace.traceIdenifierName]});
42+
})
43+
}
44+
});

demos/tom/plugin-load-promise.js

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
const worker = new Worker('demos/tom/plugin-explorer-worker.js')
2+
3+
export default function(source, urls) {
4+
return new Promise((resolve, reject) => {
5+
worker.onmessage = function(msg) {
6+
resolve(msg.data)
7+
}
8+
worker.onerror = function(msg) {
9+
reject(msg)
10+
}
11+
worker.postMessage({source, urls})
12+
})
13+
}

demos/tom/trace.js

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
class Event {
2+
constructor(type, data) {
3+
this.type = type;
4+
this.data = data;
5+
}
6+
}
7+
8+
class Trace {
9+
constructor() {
10+
this._log = [];
11+
}
12+
13+
log(event) {
14+
this._log.push(event);
15+
}
16+
17+
aboutToEnter(name) {
18+
this.log(new Event('aboutToEnter', name));
19+
}
20+
21+
enterFunction(name) {
22+
this.log(new Event('enterFunction', name));
23+
}
24+
25+
leave() {
26+
this.log(new Event('leave'));
27+
}
28+
29+
return() {
30+
this.log(new Event('return'));
31+
}
32+
}
33+
34+
Trace.traceIdenifierName = 'currentTrace';
35+
36+
export default Trace;

src/components/demo/lively-whyline-example.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,15 +4,15 @@ obj.v.w.x = obj ? "cool" : "oh no";
44
var boo, a, b;
55
([a, b, ...boo] = "abcdef");
66
({a, mojo: b} = {a: 1, mojo: 3});
7-
7+
88
if (a < 0) {
99
a--
1010
} else if (a == 0) {
1111
a *= a;
1212
} else {
1313
a++
1414
}
15-
15+
1616
function foo(a,b) {
1717
let c = a + b;
1818
for (var i = 0; i < 2; i++) {
@@ -25,6 +25,7 @@ function foo(a,b) {
2525
}
2626
return;
2727
}
28-
28+
2929
foo(a, b)
30-
let d = a + b
30+
let d = a + b
31+
Lines changed: 10 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,36 +1,13 @@
1-
export default function (babel) {
2-
const { types: t, template, transformFromAst, traverse } = babel;
3-
return {
4-
name: "underscore-decorator",
5-
visitor: {
6-
FunctionDeclaration(path) {
7-
if(path.node.isDecorated) {
8-
return;
9-
}
10-
const nameParts = path.node.id.name.split('_');
11-
if (nameParts.length < 2) {
12-
return;
13-
}
14-
let body = path.node.body;
15-
16-
for (const id of nameParts.slice(0, -1).reverse()) {
17-
body = t.callExpression(
18-
t.identifier(id),
19-
[t.arrowFunctionExpression([], body)])
20-
}
21-
22-
const fun = t.functionDeclaration(
23-
path.node.id,
24-
path.node.params,
25-
t.blockStatement([t.returnStatement(body)]
26-
));
27-
fun.isDecorated = true;
28-
path.replaceWith(fun);
29-
},//*/
30-
31-
ReturnStatement(path) {
32-
// debugger
1+
export default function({ types: t }) {
2+
return {
3+
name: 'test-plugin',
4+
visitor: {
5+
Program(path) {
6+
debugger;
7+
8+
path.unshiftContainer('body', t.debuggerStatement());
9+
10+
}
3311
}
3412
}
35-
};
3613
}

0 commit comments

Comments
 (0)