[codegen] assign some locations in generated code (#802)
Jan Kassens committed
Nov 21, 2022 at 15:14 UTC
1228bc8ce5eadd15a4d25ba373afcb4eef8543be
2 files changed
+31
-8
compiler/forget/packages/playground/components/Editor/HIRTabContent.tsx
+3
-5
@@ -38,7 +38,7 @@ export default function HIRTabContent({ source }: { source: string }) {
38
});
39
40
return (
41
- <div className="h-full flex flex-col">
41
+ <div className="flex flex-col h-full">
42
<div className="flex-1">
43
{astFunctions.map((func, index): React.ReactNode => {
44
let body;
@@ -61,8 +61,6 @@ export default function HIRTabContent({ source }: { source: string }) {
61
62
if (flags.codegen) {
63
const ast = codegen(ir);
64
- // TODO: codegen should set this correctly directly
65
- ast.loc = func.node.loc;
64
const generated = generate(
65
ast,
66
{
@@ -100,8 +98,8 @@ export default function HIRTabContent({ source }: { source: string }) {
98
}
99
const name = func.node.id?.name ?? "anonymous";
100
return (
103
- <div key={index} className="border-b py-4 px-2">
104
- <h3 className="font-medium mb-2">Function: {name}</h3>
101
+ <div key={index} className="px-2 py-4 border-b">
102
+ <h3 className="mb-2 font-medium">Function: {name}</h3>
103
{body}
104
</div>
105
);
compiler/forget/src/HIR/Codegen.ts
+28
-3
@@ -9,6 +9,7 @@ import * as t from "@babel/types";
9
import { assertExhaustive } from "../Common/utils";
10
import { invariant } from "../CompilerError";
11
import {
12
+ GeneratedSource,
13
HIRFunction,
14
Identifier,
15
IdentifierId,
@@ -17,10 +18,28 @@ import {
18
InstructionValue,
19
LValue,
20
Place,
21
+ SourceLocation,
22
} from "./HIR";
23
import { BlockTerminal, Visitor, visitTree } from "./HIRTreeVisitor";
24
import { todoInvariant } from "./todo";
25
26
+function withLoc<TNode extends t.Node, T extends (...args: any[]) => TNode>(
27
+ fn: T
28
+): (loc: SourceLocation, ...args: Parameters<T>) => ReturnType<T> {
29
+ return (loc: SourceLocation, ...args: Parameters<T>): ReturnType<T> => {
30
+ const node = fn(...args);
31
+ if (loc != GeneratedSource) {
32
+ node.loc = loc;
33
+ }
34
+ // @ts-ignore
35
+ return node;
36
+ };
37
+}
38
+
39
+const createFunctionDeclaration = withLoc(t.functionDeclaration);
40
+const createVariableDeclaration = withLoc(t.variableDeclaration);
41
+const createAssignmentExpression = withLoc(t.assignmentExpression);
42
+
43
/**
44
* Converts HIR into Babel nodes, which can then be printed into source text.
45
* Note that converting source to HIR and back is not guaranteed to produce
@@ -46,7 +65,8 @@ export default function codegen(fn: HIRFunction): t.Function {
65
const body = visitTree(fn, visitor);
66
invariant(t.isBlockStatement(body), "Expected a block statement");
67
const params = fn.params.map((param) => convertIdentifier(param.identifier));
49
- return t.functionDeclaration(
68
+ return createFunctionDeclaration(
69
+ fn.loc,
70
fn.id !== null ? convertIdentifier(fn.id) : null,
71
params,
72
body,
@@ -101,13 +121,18 @@ class CodegenVisitor
121
]);
122
}
123
case InstructionKind.Let: {
104
- return t.variableDeclaration("let", [
124
+ return createVariableDeclaration(instr.loc, "let", [
125
t.variableDeclarator(codegenLVal(instr.lvalue), value),
126
]);
127
}
128
case InstructionKind.Reassign: {
129
return t.expressionStatement(
110
- t.assignmentExpression("=", codegenLVal(instr.lvalue), value)
130
+ createAssignmentExpression(
131
+ instr.loc,
132
+ "=",
133
+ codegenLVal(instr.lvalue),
134
+ value
135
+ )
136
);
137
}
138
default: {