Fix folders of items wrt the itemid map

This commit is contained in:
nora 2023-07-31 13:13:30 +02:00
parent cbbda39688
commit 6bdbf14ecb
4 changed files with 37 additions and 5 deletions

View file

@ -447,14 +447,29 @@ export type TypeckResults = {
export type FoldFn<T> = (value: T) => T;
export type Folder = {
ast: () => Ast;
/**
* This should not be overridden.
*/
item: FoldFn<Item>;
itemInner: FoldFn<Item>;
expr: FoldFn<Expr>;
ident: FoldFn<Identifier>;
type: FoldFn<Type>;
};
const ITEM_DEFAULT: symbol = Symbol("item must not be overriden");
export const DEFAULT_FOLDER: Folder = {
ast() {
throw new Error("folders need to implement `ast`");
},
item(item) {
const newItem = this.itemInner(item);
this.ast().itemsById.set(item.id, item);
return newItem;
},
itemInner(item) {
return superFoldItem(item, this);
},
expr(expr) {
@ -467,8 +482,13 @@ export const DEFAULT_FOLDER: Folder = {
return superFoldType(type, this);
},
};
(DEFAULT_FOLDER.item as any)[ITEM_DEFAULT] = ITEM_DEFAULT;
export function foldAst(ast: Ast, folder: Folder): Ast {
if ((folder.item as any)[ITEM_DEFAULT] !== ITEM_DEFAULT) {
throw new Error("must not override `item` on folders");
}
return {
rootItems: ast.rootItems.map((item) => folder.item(item)),
itemsById: ast.itemsById,

View file

@ -658,7 +658,10 @@ function validateAst(ast: Ast) {
const validator: Folder = {
...DEFAULT_FOLDER,
item(item: Item): Item {
ast() {
return ast;
},
itemInner(item: Item): Item {
if (seenItemIds.has(item.id)) {
throw new Error(`duplicate item id: ${item.id} for ${item.node.name}`);
}
@ -719,7 +722,10 @@ function assignIds(rootItems: Item[]): Ast {
const assigner: Folder = {
...DEFAULT_FOLDER,
item(item: Item): Item {
ast() {
return ast;
},
itemInner(item: Item): Item {
const id = itemId.next();
ast.itemsById.set(id, item);
return { ...superFoldItem(item, this), id };

View file

@ -113,7 +113,10 @@ function resolveModule(cx: Context, contents: Item[]): Item[] {
const resolver: Folder = {
...DEFAULT_FOLDER,
item(item) {
ast() {
return cx.ast;
},
itemInner(item) {
switch (item.kind) {
case "function": {
const params = item.node.params.map(({ name, span, type }) => ({

View file

@ -189,7 +189,10 @@ export function typeck(ast: Ast): Ast {
const checker: Folder = {
...DEFAULT_FOLDER,
item(item) {
ast() {
return ast;
},
itemInner(item) {
switch (item.kind) {
case "function": {
const fnTy = typeOfItem(item.id, item.span) as TyFn;