mirror of
https://github.com/Noratrieb/riverdelta.git
synced 2026-01-14 16:35:03 +01:00
Fix folders of items wrt the itemid map
This commit is contained in:
parent
cbbda39688
commit
6bdbf14ecb
4 changed files with 37 additions and 5 deletions
22
src/ast.ts
22
src/ast.ts
|
|
@ -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,
|
||||
|
|
@ -528,7 +548,7 @@ export function superFoldItem(item: Item, folder: Folder): Item {
|
|||
}
|
||||
case "mod": {
|
||||
let kind: ModItemKind;
|
||||
const { modKind: itemKind } = item.node;
|
||||
const { modKind: itemKind } = item.node;
|
||||
switch (itemKind.kind) {
|
||||
case "inline":
|
||||
kind = {
|
||||
|
|
|
|||
|
|
@ -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 };
|
||||
|
|
|
|||
|
|
@ -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 }) => ({
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue