tangled
alpha
login
or
join now
notnite.com
/
moonlight
3
fork
atom
this repo has no description
3
fork
atom
overview
issues
pulls
pipelines
Added support for more export types
notnite.com
1 year ago
06d0764d
3a857d59
+46
-22
2 changed files
expand all
collapse all
unified
split
packages
lunast
src
modules
test.ts
utils.ts
+16
-10
packages/lunast/src/modules/test.ts
···
1
1
import { traverse, is } from "estree-toolkit";
2
2
-
import { getExports, getPropertyGetters, register, magicAST } from "../utils";
2
2
+
import { getPropertyGetters, register, magicAST } from "../utils";
3
3
import { BlockStatement } from "estree-toolkit/dist/generated/types";
4
4
5
5
// These aren't actual modules yet, I'm just using this as a testbed for stuff
6
6
-
register({
7
7
-
name: "Margin",
8
8
-
find: "marginCenterHorz:",
9
9
-
process({ ast }) {
10
10
-
const exports = getExports(ast);
11
11
-
// console.log(exports);
12
12
-
return Object.keys(exports).length > 0;
13
13
-
}
14
14
-
});
15
6
16
7
// Exports example
17
8
/*register({
···
20
11
process({ ast }) {
21
12
const exports = getExports(ast);
22
13
return Object.keys(exports).length > 0;
14
14
+
}
15
15
+
});
16
16
+
17
17
+
register({
18
18
+
name: "FluxDispatcher",
19
19
+
find: "addBreadcrumb:",
20
20
+
process({ id, ast, lunast }) {
21
21
+
const exports = getExports(ast);
22
22
+
for (const [name, data] of Object.entries(exports)) {
23
23
+
if (!is.identifier(data.argument)) continue;
24
24
+
const binding = data.scope.getOwnBinding(data.argument.name);
25
25
+
console.log(name, binding);
26
26
+
}
27
27
+
return false;
23
28
}
24
29
});*/
25
30
···
53
58
}
54
59
});
55
60
61
61
+
// Remapping example
56
62
register({
57
63
name: "ClipboardUtils",
58
64
find: 'document.queryCommandEnabled("copy")',
+30
-12
packages/lunast/src/utils.ts
···
1
1
import type { Processor } from "./remap";
2
2
-
import { traverse, is, Scope } from "estree-toolkit";
2
2
+
import { traverse, is, Scope, Binding } from "estree-toolkit";
3
3
// FIXME something's fishy with these types
4
4
import type {
5
5
Expression,
6
6
ExpressionStatement,
7
7
ObjectExpression,
8
8
Program,
9
9
-
Property,
10
9
ReturnStatement
11
10
} from "estree-toolkit/dist/generated/types";
12
11
import { parse } from "meriyah";
···
22
21
return [...processors];
23
22
}
24
23
24
24
+
export type ExpressionWithScope = {
25
25
+
argument: Expression;
26
26
+
scope: Scope;
27
27
+
};
28
28
+
25
29
export function getExports(ast: Program) {
26
26
-
const ret: Record<string, Property["value"]> = {};
30
30
+
const ret: Record<string, ExpressionWithScope> = {};
27
31
28
32
traverse(ast, {
29
33
$: { scope: true },
30
34
BlockStatement(path) {
35
35
+
if (path.scope == null) return;
36
36
+
31
37
// Walk up to make sure we are indeed the top level
32
38
let parent = path.parentPath;
33
39
while (!is.program(parent)) {
···
51
57
for (let i = 0; i < path.parent.params.length; i++) {
52
58
const param = path.parent.params[i];
53
59
if (!is.identifier(param)) continue;
54
54
-
const binding = path.scope?.getBinding(param.name);
60
60
+
const binding: Binding | undefined = path.scope!.getBinding(param.name);
55
61
if (!binding) continue;
56
62
57
63
// module
···
72
78
for (const property of exports.properties) {
73
79
if (!is.property(property)) continue;
74
80
if (!is.identifier(property.key)) continue;
75
75
-
ret[property.key.name] = property.value;
81
81
+
if (!is.expression(property.value)) continue;
82
82
+
ret[property.key.name] = {
83
83
+
argument: property.value,
84
84
+
scope: path.scope
85
85
+
};
76
86
}
77
87
}
78
88
}
79
89
// TODO: exports
80
90
else if (i === 1) {
81
81
-
// console.log("getExports:", path, param, binding);
91
91
+
for (const reference of binding.references) {
92
92
+
if (!is.identifier(reference.node)) continue;
93
93
+
if (reference.parentPath == null) continue;
94
94
+
if (!is.memberExpression(reference.parentPath.node)) continue;
95
95
+
if (!is.identifier(reference.parentPath.node.property)) continue;
96
96
+
97
97
+
const assignmentExpression = reference.parentPath.parentPath?.node;
98
98
+
if (!is.assignmentExpression(assignmentExpression)) continue;
99
99
+
100
100
+
ret[reference.parentPath.node.property.name] = {
101
101
+
argument: assignmentExpression.right,
102
102
+
scope: path.scope
103
103
+
};
104
104
+
}
82
105
}
83
106
}
84
107
}
···
87
110
return ret;
88
111
}
89
112
90
90
-
export type PropertyGetter = {
91
91
-
argument: Expression;
92
92
-
scope: Scope;
93
93
-
};
94
94
-
95
113
// TODO: util function to resolve the value of an expression
96
114
export function getPropertyGetters(ast: Program) {
97
97
-
const ret: Record<string, PropertyGetter> = {};
115
115
+
const ret: Record<string, ExpressionWithScope> = {};
98
116
99
117
traverse(ast, {
100
118
$: { scope: true },