Skip to content

Commit

Permalink
perf: improve script parsing
Browse files Browse the repository at this point in the history
  • Loading branch information
DylanPiercey committed Nov 24, 2024
1 parent f3ca04a commit 124ad10
Show file tree
Hide file tree
Showing 3 changed files with 25 additions and 12 deletions.
5 changes: 5 additions & 0 deletions .changeset/bright-moons-push.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@marko/language-tools": patch
---

Improve script parsing performance.
2 changes: 1 addition & 1 deletion packages/language-tools/src/extractors/script/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ class ScriptExtractor {
this.#ts = opts.ts;
this.#runtimeTypes = opts.runtimeTypesCode;
this.#extractor = new Extractor(parsed);
this.#scriptParser = new ScriptParser(parsed.filename, parsed.code);
this.#scriptParser = new ScriptParser(parsed);
this.#read = parsed.read.bind(parsed);
this.#mutationOffsets = crawlProgramScope(this.#parsed, this.#scriptParser);
this.#writeProgram(parsed.program);
Expand Down
30 changes: 19 additions & 11 deletions packages/language-tools/src/extractors/script/util/script-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,50 +5,58 @@ import {
} from "@babel/parser";
import type * as t from "@babel/types";

import type { Parsed } from "../../../parser";

const plugins: ParserOptions["plugins"] = [
"exportDefaultFrom",
"importAssertions",
"typescript",
];

export class ScriptParser {
#sourceFileName: string;
#whitespace: string;
constructor(sourceFileName: string, code: string) {
this.#sourceFileName = sourceFileName;
this.#whitespace = code.replace(/[^\s]/g, " "); // used to ensure that babel provides the correct source locations.
#parsed: Parsed;
constructor(parsed: Parsed) {
this.#parsed = parsed;
}

statementAt<T = t.Statement[]>(offset: number, src: string) {
statementAt<T = t.Statement[]>(startIndex: number, src: string) {
const pos = this.#parsed.positionAt(startIndex);
try {
return parseStatement(this.#whitespace.slice(0, offset) + src, {
return parseStatement(src, {
plugins,
startIndex,
startLine: pos.line + 1,
startColumn: pos.character,
strictMode: true,
errorRecovery: true,
sourceType: "module",
allowUndeclaredExports: true,
allowSuperOutsideMethod: true,
allowAwaitOutsideFunction: true,
allowReturnOutsideFunction: true,
sourceFilename: this.#sourceFileName,
sourceFilename: this.#parsed.filename,
}).program.body as unknown as T extends unknown[] ? T : Readonly<[T]>;
} catch {
return [];
}
}

expressionAt<T = t.Expression>(offset: number, src: string) {
expressionAt<T = t.Expression>(startIndex: number, src: string) {
const pos = this.#parsed.positionAt(startIndex);
try {
return parseExpression(this.#whitespace.slice(0, offset) + src, {
return parseExpression(src, {
plugins,
startIndex,
startLine: pos.line + 1,
startColumn: pos.character,
strictMode: true,
errorRecovery: true,
sourceType: "module",
allowUndeclaredExports: true,
allowSuperOutsideMethod: true,
allowAwaitOutsideFunction: true,
allowReturnOutsideFunction: true,
sourceFilename: this.#sourceFileName,
sourceFilename: this.#parsed.filename,
}) as unknown as T;
} catch {
return;
Expand Down

0 comments on commit 124ad10

Please sign in to comment.