@samitouri / QOS-React / commits / 2eded946f8

Make CompilerEntrypoint a little more generic

These are still quite Babel specific, but the interface is slightly more generic: CompilerEntrypoint takes a non-Babel specific CompilerPass as an argument instead of passing Babel's PluginPass directly. In the future we can consider lowering the whole Program into HIR but that involves a significant lift in our representation and a small amount of new syntax to support (eg import statements), so this PR is the extent of this stack for now

Lauren Tan committed Jun 2, 2023 at 13:06 UTC 2eded946f8e1d75b2e6d078cceb7589439cf5bf4
2 files changed +15 -9
compiler/forget/src/Babel/BabelPlugin.ts
+6 -1
@@ -10,6 +10,7 @@
10 import jsx from "@babel/plugin-syntax-jsx";
11 import type * as BabelCore from "@babel/core";
12 import { compileProgram } from "../CompilerEntrypoint";
13 +import { parsePluginOptions } from "../CompilerOptions";
14
15 /**
16 * The React Forget Babel Plugin
@@ -27,7 +28,11 @@ export default function ReactForgetBabelPlugin(
28 // prior to B, if A does not have a Program visitor and B does, B will run first. We always
29 // want Forget to run true to source as possible.
30 Program(prog, pass): void {
30 - compileProgram(prog, pass);
31 + compileProgram(prog, {
32 + opts: parsePluginOptions(pass.opts),
33 + filename: pass.filename ?? null,
34 + comments: pass.file.ast.comments ?? [],
35 + });
36 },
37 },
38 };
compiler/forget/src/CompilerEntrypoint.ts
+9 -8
@@ -5,7 +5,7 @@
5 * LICENSE file in the root directory of this source tree.
6 */
7
8 -import { NodePath, PluginPass } from "@babel/core";
8 +import { NodePath } from "@babel/core";
9 import * as t from "@babel/types";
10 import {
11 CompilerError,
@@ -21,9 +21,10 @@ import {
21 parsePluginOptions,
22 } from "./CompilerOptions";
23
24 -type BabelPluginPass = {
24 +export type CompilerPass = {
25 opts: PluginOptions;
26 filename: string | null;
27 + comments: (t.CommentBlock | t.CommentLine)[];
28 };
29
30 function hasUseForgetDirective(directive: t.Directive): boolean {
@@ -41,13 +42,13 @@ function hasAnyUseForgetDirectives(directives: t.Directive[]): boolean {
42
43 export function compileProgram(
44 program: NodePath<t.Program>,
44 - pass: PluginPass
45 + pass: CompilerPass
46 ): void {
47 let hasForgetCompiledCode: boolean = false;
48
49 function visitFn(
50 fn: NodePath<t.FunctionDeclaration>,
50 - pass: BabelPluginPass
51 + pass: CompilerPass
52 ): void {
53 try {
54 const compiled = compile(fn, pass.opts.environment);
@@ -147,7 +148,7 @@ export function compileProgram(
148 const visitor = {
149 FunctionDeclaration(
150 fn: NodePath<t.FunctionDeclaration>,
150 - pass: BabelPluginPass
151 + pass: CompilerPass
152 ): void {
153 if (!shouldCompile(fn, pass)) {
154 return;
@@ -158,7 +159,7 @@ export function compileProgram(
159
160 ArrowFunctionExpression(
161 fn: NodePath<t.ArrowFunctionExpression>,
161 - pass: BabelPluginPass
162 + pass: CompilerPass
163 ): void {
164 if (!shouldCompile(fn, pass)) {
165 return;
@@ -190,7 +191,7 @@ export function compileProgram(
191 const options = parsePluginOptions(pass.opts);
192
193 const violations = [];
193 - const fileComments = pass.file.ast.comments;
194 + const fileComments = pass.comments;
195 let fileHasUseForgetDirective = false;
196 if (Array.isArray(fileComments)) {
197 for (const comment of fileComments) {
@@ -340,7 +341,7 @@ export function compileProgram(
341
342 function shouldCompile(
343 fn: NodePath<t.FunctionDeclaration | t.ArrowFunctionExpression>,
343 - pass: BabelPluginPass
344 + pass: CompilerPass
345 ): boolean {
346 if (pass.opts.enableOnlyOnUseForgetDirective) {
347 const body = fn.get("body");