Skip to content

Commit 404d51d

Browse files
committed
add a new part of processScript() which makes classes work in hackmud
it uses the newly added esprima and friends modules to query a syntax tree of the script and modifies it before regenerating code again eventually I'll rip out using `acorn`'s tokenizer and iterating through tokens and replace it all with what I'm doing for classes
1 parent be3bf1c commit 404d51d

File tree

1 file changed

+81
-1
lines changed

1 file changed

+81
-1
lines changed

src/index.ts

Lines changed: 81 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,14 @@
11
import { Token, tokenizer as tokenize, tokTypes as tokenTypes } from "acorn"
22
import { watch as watchDirectory } from "chokidar"
3+
import { generate as generateCodeFromAST } from "escodegen"
4+
import { parseScript } from "esprima"
5+
import { query } from "esquery"
6+
import ASTNodes from "estree"
37
import fs from "fs"
48
import { basename as getBaseName, extname as getFileExtension, resolve as resolvePath } from "path"
59
import { minify } from "terser"
610
import typescript from "typescript"
7-
import { copyFilePersist, hackmudLength, positionToLineNumber, stringSplice, writeFilePersist } from "./lib"
11+
import { clearObject, copyFilePersist, hackmudLength, positionToLineNumber, stringSplice, writeFilePersist } from "./lib"
812

913
const { readFile: readFile, readdir: readDirectory, stat: getFileStatus, writeFile: writeFile } = fs.promises
1014

@@ -609,6 +613,82 @@ export async function processScript(script: string) {
609613

610614
script = outputText.replace(/^export /, "")
611615

616+
await writeFile("./test.json", JSON.stringify(parseScript(script), null, "\t"))
617+
618+
const ast = parseScript(script)
619+
620+
for (const node of query(ast, "ClassBody > MethodDefinition[kind=constructor] > FunctionExpression > BlockStatement") as ASTNodes.BlockStatement[]) {
621+
node.body.unshift({
622+
type: "VariableDeclaration",
623+
declarations: [
624+
{
625+
type: "VariableDeclarator",
626+
id: {
627+
type: "Identifier",
628+
name: "__THIS__"
629+
}
630+
}
631+
],
632+
kind: "let"
633+
})
634+
}
635+
636+
for (const node of query(ast, "ClassBody > MethodDefinition[kind=constructor] > FunctionExpression > BlockStatement !CallExpression > Super") as ASTNodes.CallExpression[]) {
637+
const newNode: ASTNodes.AssignmentExpression = {
638+
type: "AssignmentExpression",
639+
operator: "=",
640+
left: {
641+
type: "Identifier",
642+
name: "__THIS__"
643+
},
644+
right: { ...node }
645+
}
646+
647+
Object.assign(clearObject(node), newNode)
648+
}
649+
650+
for (const node of query(ast, "ClassBody > MethodDefinition > FunctionExpression > BlockStatement !ThisExpression") as ASTNodes.ThisExpression[]) {
651+
const newNode: ASTNodes.Identifier = {
652+
type: "Identifier",
653+
name: "__THIS__"
654+
}
655+
656+
Object.assign(clearObject(node), newNode)
657+
}
658+
659+
for (const node of query(ast, "ClassBody > MethodDefinition[kind=method] > FunctionExpression > BlockStatement") as ASTNodes.BlockStatement[]) {
660+
node.body.unshift({
661+
type: "VariableDeclaration",
662+
declarations: [ {
663+
type: "VariableDeclarator",
664+
id: {
665+
type: "Identifier",
666+
name: "__THIS__"
667+
},
668+
init: {
669+
type: "CallExpression",
670+
callee: {
671+
type: "MemberExpression",
672+
computed: false,
673+
object: {
674+
type: "Super"
675+
},
676+
property: {
677+
type: "Identifier",
678+
name: "valueOf"
679+
},
680+
optional: false
681+
},
682+
arguments: [],
683+
optional: false
684+
}
685+
} ],
686+
"kind": "let"
687+
})
688+
}
689+
690+
script = generateCodeFromAST(ast)
691+
612692
// the typescript inserts semicolons where they weren't already so we take
613693
// all semicolons out of the count and add the number of semicolons in the
614694
// source to make things fair

0 commit comments

Comments
 (0)