First steps in supporting 'trait' and 'impl'

This commit is contained in:
Sam Vervaeck 2020-06-16 20:45:53 +02:00
parent 421831161a
commit 509d5a3c69
7 changed files with 168 additions and 70 deletions

View file

@ -21,6 +21,25 @@ export abstract class Syntax {
public errors: Diagnostic[] = [];
// --------------------------------------------------------------------------------
// NOTE The following properties and methods are only valid when inside a BoltTraitDeclaration
// TODO Move this to BoltTraitDeclaration as soon as tsastgen supports this
private impls?: BoltImplDeclaration[] = [];
public addImplDeclaration(node: BoltImplDeclaration) {
if (this.impls === undefined) {
this.impls = [];
}
this.impls.push(node);
}
public getImplDeclarations(): BoltImplDeclaration[] {
return this.impls ?? [];
}
// --------------------------------------------------------------------------------
public abstract kind: SyntaxKind;
public abstract parentNode: Syntax | null = null;
@ -31,7 +50,7 @@ export abstract class Syntax {
this.id = nextNodeId++;
}
protected [inspectTag](depth: number | null, options: InspectOptionsStylized) {
private [inspectTag](depth: number | null, options: InspectOptionsStylized) {
const proto = Object.getPrototypeOf(this);
if (depth !== null && depth < 0) {
return options.stylize(`[${proto.constructor.name}]`, 'special')
@ -51,7 +70,7 @@ export abstract class Syntax {
return out;
}
[serializeTag]() {
private [serializeTag]() {
const result: any[] = [];
for (const key of Object.keys(this)) {
if (key === 'kind' || key === 'span' || key === 'parentNode' || key === 'errors' || key === 'type' || key === 'id') {
@ -63,7 +82,7 @@ export abstract class Syntax {
return result;
}
*preorder() {
public *preorder() {
const stack: Syntax[] = [ this as unknown as Syntax ] ;
while (stack.length > 0) {
const node = stack.pop()!;
@ -75,11 +94,11 @@ export abstract class Syntax {
}
mayContainKind(kind: SyntaxKind) {
// TODO
// TODO should be generated by tsastgen
return true;
}
getParentOfKind(kind: SyntaxKind) {
public getParentOfKind(kind: SyntaxKind) {
let currNode = this.parentNode;
while (currNode !== null) {
if (currNode.kind === kind) {
@ -90,7 +109,7 @@ export abstract class Syntax {
return null;
}
*findAllChildrenOfKind<K extends SyntaxKind>(kind: K): IterableIterator<ResolveSyntaxKind<K>> {
public *findAllChildrenOfKind<K extends SyntaxKind>(kind: K): IterableIterator<ResolveSyntaxKind<K>> {
for (const node of this.preorder()) {
if (!node.mayContainKind(kind)) {
break;
@ -426,7 +445,7 @@ export interface BoltExportDirective extends BoltSourceElement {
export interface BoltTraitOrImplElement {}
export interface BoltTraitDeclaration extends BoltDeclarationLike, BoltTypeDeclaration {
export interface BoltTraitDeclaration extends BoltDeclarationLike {
modifiers: BoltModifiers,
typeParams: BoltTypeParameter[] | null,
name: BoltIdentifier,
@ -434,11 +453,11 @@ export interface BoltTraitDeclaration extends BoltDeclarationLike, BoltTypeDecla
elements: BoltTraitOrImplElement[] | null,
}
export interface BoltImplDeclaration extends BoltTypeDeclaration, BoltDeclarationLike {
export interface BoltImplDeclaration extends BoltDeclarationLike {
modifiers: BoltModifiers,
typeParams: BoltTypeParameter[] | null,
name: BoltIdentifier,
traitTypeExpr: BoltTypeExpression | null,
traitTypeExpr: BoltReferenceTypeExpression,
typeExpr: BoltReferenceTypeExpression,
elements: BoltTraitOrImplElement[],
}

View file

@ -22,13 +22,27 @@ export abstract class SyntaxBase {
public id: number;
public type?: Type;
public errors: Diagnostic[] = [];
// --------------------------------------------------------------------------------
// NOTE The following properties and methods are only valid when inside a BoltTraitDeclaration
// TODO Move this to BoltTraitDeclaration as soon as tsastgen supports this
private impls?: BoltImplDeclaration[] = [];
public addImplDeclaration(node: BoltImplDeclaration) {
if (this.impls === undefined) {
this.impls = [];
}
this.impls.push(node);
}
public getImplDeclarations(): BoltImplDeclaration[] {
return this.impls ?? [];
}
// --------------------------------------------------------------------------------
public abstract kind: SyntaxKind;
public abstract parentNode: Syntax | null = null;
public abstract getChildNodes(): IterableIterator<Syntax>;
constructor(public span: TextSpan | null = null) {
this.id = nextNodeId++;
}
protected [inspectTag](depth: number | null, options: InspectOptionsStylized) {
private [inspectTag](depth: number | null, options: InspectOptionsStylized) {
const proto = Object.getPrototypeOf(this);
if (depth !== null && depth < 0) {
return options.stylize(`[${proto.constructor.name}]`, 'special');
@ -47,7 +61,7 @@ export abstract class SyntaxBase {
out += '}\n';
return out;
}
[serializeTag]() {
private [serializeTag]() {
const result: any[] = [];
for (const key of Object.keys(this)) {
if (key === 'kind' || key === 'span' || key === 'parentNode' || key === 'errors' || key === 'type' || key === 'id') {
@ -58,7 +72,7 @@ export abstract class SyntaxBase {
result.push(this.span);
return result;
}
*preorder() {
public *preorder() {
const stack: Syntax[] = [this as unknown as Syntax];
while (stack.length > 0) {
const node = stack.pop()!;
@ -69,10 +83,10 @@ export abstract class SyntaxBase {
}
}
mayContainKind(kind: SyntaxKind) {
// TODO
// TODO should be generated by tsastgen
return true;
}
getParentOfKind(kind: SyntaxKind) {
public getParentOfKind(kind: SyntaxKind) {
let currNode = this.parentNode;
while (currNode !== null) {
if (currNode.kind === kind) {
@ -82,7 +96,7 @@ export abstract class SyntaxBase {
}
return null;
}
*findAllChildrenOfKind<K extends SyntaxKind>(kind: K): IterableIterator<ResolveSyntaxKind<K>> {
public *findAllChildrenOfKind<K extends SyntaxKind>(kind: K): IterableIterator<ResolveSyntaxKind<K>> {
for (const node of this.preorder()) {
if (!node.mayContainKind(kind)) {
break;
@ -132,7 +146,7 @@ export type FunctionBodyElement = JSLetDeclaration | JSArrowFunctionDeclaration
export type ReturnStatement = JSReturnStatement | BoltReturnStatement;
export type BoltSyntax = BoltMacroCall | BoltRecordField | BoltPlainExportSymbol | BoltImportDirective | BoltPlainImportSymbol | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltImplDeclaration | BoltTraitDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltParameter | BoltConditionalCase | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | BoltCase | BoltMatchArm | BoltConstantExpression | BoltBlockExpression | BoltCaseExpression | BoltMatchExpression | BoltYieldExpression | BoltCallExpression | BoltFunctionExpression | BoltMemberExpression | BoltReferenceExpression | BoltTupleExpression | BoltQuoteExpression | BoltRecordFieldPattern | BoltTuplePatternElement | BoltRecordPattern | BoltTuplePattern | BoltExpressionPattern | BoltTypePattern | BoltBindPattern | BoltTypeParameter | BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltQualName | BoltSourceFile | BoltBracketed | BoltBraced | BoltParenthesized | BoltImplKeyword | BoltTraitKeyword | BoltTypeKeyword | BoltStructKeyword | BoltEnumKeyword | BoltMutKeyword | BoltModKeyword | BoltPubKeyword | BoltExportKeyword | BoltImportKeyword | BoltMatchKeyword | BoltYieldKeyword | BoltLoopKeyword | BoltReturnKeyword | BoltLetKeyword | BoltForKeyword | BoltForeignKeyword | BoltFnKeyword | BoltQuoteKeyword | BoltWhereKeyword | BoltVBar | BoltLtSign | BoltExMark | BoltGtSign | BoltEqSign | BoltLArrow | BoltRArrowAlt | BoltRArrow | BoltDotDot | BoltDot | BoltColonColon | BoltColon | BoltSemi | BoltComma | BoltAssignment | BoltOperator | BoltIdentifier | BoltIntegerLiteral | BoltStringLiteral | EndOfFile;
export type BoltSyntax = BoltMacroCall | BoltRecordField | BoltPlainExportSymbol | BoltImportDirective | BoltPlainImportSymbol | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltParameter | BoltConditionalCase | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | BoltCase | BoltMatchArm | BoltConstantExpression | BoltBlockExpression | BoltCaseExpression | BoltMatchExpression | BoltYieldExpression | BoltCallExpression | BoltFunctionExpression | BoltMemberExpression | BoltReferenceExpression | BoltTupleExpression | BoltQuoteExpression | BoltRecordFieldPattern | BoltTuplePatternElement | BoltRecordPattern | BoltTuplePattern | BoltExpressionPattern | BoltTypePattern | BoltBindPattern | BoltTypeParameter | BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltQualName | BoltSourceFile | BoltBracketed | BoltBraced | BoltParenthesized | BoltImplKeyword | BoltTraitKeyword | BoltTypeKeyword | BoltStructKeyword | BoltEnumKeyword | BoltMutKeyword | BoltModKeyword | BoltPubKeyword | BoltExportKeyword | BoltImportKeyword | BoltMatchKeyword | BoltYieldKeyword | BoltLoopKeyword | BoltReturnKeyword | BoltLetKeyword | BoltForKeyword | BoltForeignKeyword | BoltFnKeyword | BoltQuoteKeyword | BoltWhereKeyword | BoltVBar | BoltLtSign | BoltExMark | BoltGtSign | BoltEqSign | BoltLArrow | BoltRArrowAlt | BoltRArrow | BoltDotDot | BoltDot | BoltColonColon | BoltColon | BoltSemi | BoltComma | BoltAssignment | BoltOperator | BoltIdentifier | BoltIntegerLiteral | BoltStringLiteral | EndOfFile;
export type BoltToken = BoltBracketed | BoltBraced | BoltParenthesized | BoltImplKeyword | BoltTraitKeyword | BoltTypeKeyword | BoltStructKeyword | BoltEnumKeyword | BoltMutKeyword | BoltModKeyword | BoltPubKeyword | BoltExportKeyword | BoltImportKeyword | BoltMatchKeyword | BoltYieldKeyword | BoltLoopKeyword | BoltReturnKeyword | BoltLetKeyword | BoltForKeyword | BoltForeignKeyword | BoltFnKeyword | BoltQuoteKeyword | BoltWhereKeyword | BoltVBar | BoltLtSign | BoltExMark | BoltGtSign | BoltEqSign | BoltLArrow | BoltRArrowAlt | BoltRArrow | BoltDotDot | BoltDot | BoltColonColon | BoltColon | BoltSemi | BoltComma | BoltAssignment | BoltOperator | BoltIdentifier | BoltIntegerLiteral | BoltStringLiteral | EndOfFile;
@ -167,7 +181,7 @@ export class BoltIdentifier extends SyntaxBase {
*getChildNodes(): IterableIterator<BoltIdentifierChild> { }
}
type BoltIdentifierParent = BoltQualName | BoltTypeParameter | BoltBindPattern | BoltRecordFieldPattern | BoltMemberExpression | BoltPlainImportSymbol | BoltPlainExportSymbol | BoltRecordField | BoltFunctionDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltTypeAliasDeclaration | BoltRecordDeclaration | BoltModule | BoltMacroCall | never;
type BoltIdentifierParent = BoltQualName | BoltTypeParameter | BoltBindPattern | BoltRecordFieldPattern | BoltMemberExpression | BoltPlainImportSymbol | BoltPlainExportSymbol | BoltTraitDeclaration | BoltRecordField | BoltFunctionDeclaration | BoltTypeAliasDeclaration | BoltRecordDeclaration | BoltModule | BoltMacroCall | never;
type BoltIdentifierChild = never;
@ -616,7 +630,7 @@ export class BoltSourceFile extends SyntaxBase {
type BoltSourceFileParent = never;
type BoltSourceFileChild = BoltMacroCall | BoltExportDirective | BoltImportDirective | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltImplDeclaration | BoltTraitDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | never;
type BoltSourceFileChild = BoltMacroCall | BoltExportDirective | BoltImportDirective | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | never;
export class BoltQualName extends SyntaxBase {
parentNode: null | BoltQualNameParent = null;
@ -639,7 +653,7 @@ export class BoltTypeOfExpression extends SyntaxBase {
*getChildNodes(): IterableIterator<BoltTypeOfExpressionChild> { yield this.expression; }
}
type BoltTypeOfExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltTypeAliasDeclaration | never;
type BoltTypeOfExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltTraitDeclaration | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTypeAliasDeclaration | never;
type BoltTypeOfExpressionChild = BoltConstantExpression | BoltBlockExpression | BoltCaseExpression | BoltMatchExpression | BoltYieldExpression | BoltCallExpression | BoltFunctionExpression | BoltMemberExpression | BoltReferenceExpression | BoltTupleExpression | BoltQuoteExpression | never;
@ -652,7 +666,7 @@ export class BoltReferenceTypeExpression extends SyntaxBase {
yield element; }
}
type BoltReferenceTypeExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltTypeAliasDeclaration | never;
type BoltReferenceTypeExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltTraitDeclaration | BoltImplDeclaration | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTypeAliasDeclaration | never;
type BoltReferenceTypeExpressionChild = BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltQualName | never;
@ -665,7 +679,7 @@ export class BoltFunctionTypeExpression extends SyntaxBase {
yield this.returnType; }
}
type BoltFunctionTypeExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltTypeAliasDeclaration | never;
type BoltFunctionTypeExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltTraitDeclaration | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTypeAliasDeclaration | never;
type BoltFunctionTypeExpressionChild = BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltParameter | never;
@ -676,7 +690,7 @@ export class BoltLiftedTypeExpression extends SyntaxBase {
*getChildNodes(): IterableIterator<BoltLiftedTypeExpressionChild> { yield this.expression; }
}
type BoltLiftedTypeExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltTypeAliasDeclaration | never;
type BoltLiftedTypeExpressionParent = BoltReferenceTypeExpression | BoltFunctionTypeExpression | BoltTypeParameter | BoltTypePattern | BoltRecordPattern | BoltFunctionExpression | BoltParameter | BoltTraitDeclaration | BoltRecordField | BoltFunctionDeclaration | BoltVariableDeclaration | BoltTypeAliasDeclaration | never;
type BoltLiftedTypeExpressionChild = BoltConstantExpression | BoltBlockExpression | BoltCaseExpression | BoltMatchExpression | BoltYieldExpression | BoltCallExpression | BoltFunctionExpression | BoltMemberExpression | BoltReferenceExpression | BoltTupleExpression | BoltQuoteExpression | never;
@ -689,7 +703,7 @@ export class BoltTypeParameter extends SyntaxBase {
yield this.defaultType; }
}
type BoltTypeParameterParent = BoltFunctionDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltTypeAliasDeclaration | BoltRecordDeclaration | never;
type BoltTypeParameterParent = BoltTraitDeclaration | BoltImplDeclaration | BoltFunctionDeclaration | BoltTypeAliasDeclaration | BoltRecordDeclaration | never;
type BoltTypeParameterChild = BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltIdentifier | never;
@ -1018,7 +1032,7 @@ type BoltParameterChild = BoltConstantExpression | BoltBlockExpression | BoltCas
export type BoltDeclaration = BoltRecordDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration;
export type BoltTypeDeclaration = BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltImplDeclaration | BoltTraitDeclaration;
export type BoltTypeDeclaration = BoltRecordDeclaration | BoltTypeAliasDeclaration;
export class BoltModule extends SyntaxBase {
parentNode: null | BoltModuleParent = null;
@ -1031,7 +1045,7 @@ export class BoltModule extends SyntaxBase {
type BoltModuleParent = BoltSourceFile | BoltModule | never;
type BoltModuleChild = BoltMacroCall | BoltExportDirective | BoltImportDirective | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltImplDeclaration | BoltTraitDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | BoltIdentifier | never;
type BoltModuleChild = BoltMacroCall | BoltExportDirective | BoltImportDirective | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | BoltIdentifier | never;
export type BoltDeclarationLike = BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltImplDeclaration | BoltTraitDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration;
@ -1049,7 +1063,7 @@ export class BoltFunctionDeclaration extends SyntaxBase {
yield element; }
}
type BoltFunctionDeclarationParent = BoltSourceFile | BoltFunctionExpression | BoltBlockExpression | BoltConditionalCase | BoltLoopStatement | BoltFunctionDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltModule | never;
type BoltFunctionDeclarationParent = BoltSourceFile | BoltFunctionExpression | BoltBlockExpression | BoltConditionalCase | BoltTraitDeclaration | BoltImplDeclaration | BoltLoopStatement | BoltFunctionDeclaration | BoltModule | never;
type BoltFunctionDeclarationChild = BoltMacroCall | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement | BoltTypeParameter | BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltParameter | BoltOperator | BoltVBar | BoltLtSign | BoltExMark | BoltGtSign | BoltIdentifier | never;
@ -1132,24 +1146,23 @@ export class BoltTraitDeclaration extends SyntaxBase {
yield element; }
}
type BoltTraitDeclarationParent = BoltSourceFile | BoltModule | never;
type BoltTraitDeclarationParent = never;
type BoltTraitDeclarationChild = BoltMacroCall | BoltTypeAliasDeclaration | BoltFunctionDeclaration | BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltIdentifier | BoltTypeParameter | never;
export class BoltImplDeclaration extends SyntaxBase {
parentNode: null | BoltImplDeclarationParent = null;
kind: SyntaxKind.BoltImplDeclaration = SyntaxKind.BoltImplDeclaration;
constructor(public modifiers: BoltModifiers, public typeParams: BoltTypeParameter[] | null, public name: BoltIdentifier, public traitTypeExpr: BoltTypeExpression | null, public elements: BoltTraitOrImplElement[], span: TextSpan | null = null) { super(span); }
constructor(public modifiers: BoltModifiers, public typeParams: BoltTypeParameter[] | null, public traitTypeExpr: BoltReferenceTypeExpression, public typeExpr: BoltReferenceTypeExpression, public elements: BoltTraitOrImplElement[], span: TextSpan | null = null) { super(span); }
*getChildNodes(): IterableIterator<BoltImplDeclarationChild> { if (this.typeParams !== null)
for (let element of this.typeParams)
yield element; yield this.name; if (this.traitTypeExpr !== null)
yield this.traitTypeExpr; for (let element of this.elements)
yield element; yield this.traitTypeExpr; yield this.typeExpr; for (let element of this.elements)
yield element; }
}
type BoltImplDeclarationParent = BoltSourceFile | BoltModule | never;
type BoltImplDeclarationParent = never;
type BoltImplDeclarationChild = BoltMacroCall | BoltTypeAliasDeclaration | BoltFunctionDeclaration | BoltLiftedTypeExpression | BoltFunctionTypeExpression | BoltReferenceTypeExpression | BoltTypeOfExpression | BoltIdentifier | BoltTypeParameter | never;
type BoltImplDeclarationChild = BoltMacroCall | BoltTypeAliasDeclaration | BoltFunctionDeclaration | BoltReferenceTypeExpression | BoltTypeParameter | never;
export class BoltTypeAliasDeclaration extends SyntaxBase {
parentNode: null | BoltTypeAliasDeclarationParent = null;
@ -1192,7 +1205,7 @@ type BoltRecordDeclarationParent = BoltSourceFile | BoltModule | never;
type BoltRecordDeclarationChild = BoltMacroCall | BoltRecordField | BoltTypeParameter | BoltIdentifier | never;
export type BoltSourceElement = BoltMacroCall | BoltExportDirective | BoltImportDirective | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltImplDeclaration | BoltTraitDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement;
export type BoltSourceElement = BoltMacroCall | BoltExportDirective | BoltImportDirective | BoltModule | BoltRecordDeclaration | BoltTypeAliasDeclaration | BoltVariableDeclaration | BoltFunctionDeclaration | BoltLoopStatement | BoltExpressionStatement | BoltResumeStatement | BoltConditionalStatement | BoltReturnStatement;
export class BoltMacroCall extends SyntaxBase {
parentNode: null | BoltMacroCallParent = null;
@ -1201,7 +1214,7 @@ export class BoltMacroCall extends SyntaxBase {
*getChildNodes(): IterableIterator<BoltMacroCallChild> { yield this.name; }
}
type BoltMacroCallParent = BoltSourceFile | BoltFunctionExpression | BoltBlockExpression | BoltConditionalCase | BoltLoopStatement | BoltFunctionDeclaration | BoltTraitDeclaration | BoltImplDeclaration | BoltRecordDeclaration | BoltModule | never;
type BoltMacroCallParent = BoltSourceFile | BoltFunctionExpression | BoltBlockExpression | BoltConditionalCase | BoltTraitDeclaration | BoltImplDeclaration | BoltLoopStatement | BoltFunctionDeclaration | BoltRecordDeclaration | BoltModule | never;
type BoltMacroCallChild = BoltIdentifier | never;
@ -2109,7 +2122,7 @@ export function createBoltExportDirective(file: string, symbols: BoltExportSymbo
export function createBoltTraitDeclaration(modifiers: BoltModifiers, typeParams: BoltTypeParameter[] | null, name: BoltIdentifier, typeBoundExpr: BoltTypeExpression | null, elements: BoltTraitOrImplElement[] | null, span: TextSpan | null = null): BoltTraitDeclaration { return new BoltTraitDeclaration(modifiers, typeParams, name, typeBoundExpr, elements, span); }
export function createBoltImplDeclaration(modifiers: BoltModifiers, typeParams: BoltTypeParameter[] | null, name: BoltIdentifier, traitTypeExpr: BoltTypeExpression | null, elements: BoltTraitOrImplElement[], span: TextSpan | null = null): BoltImplDeclaration { return new BoltImplDeclaration(modifiers, typeParams, name, traitTypeExpr, elements, span); }
export function createBoltImplDeclaration(modifiers: BoltModifiers, typeParams: BoltTypeParameter[] | null, traitTypeExpr: BoltReferenceTypeExpression, typeExpr: BoltReferenceTypeExpression, elements: BoltTraitOrImplElement[], span: TextSpan | null = null): BoltImplDeclaration { return new BoltImplDeclaration(modifiers, typeParams, traitTypeExpr, typeExpr, elements, span); }
export function createBoltTypeAliasDeclaration(modifiers: BoltModifiers, name: BoltIdentifier, typeParams: BoltTypeParameter[] | null, typeExpr: BoltTypeExpression, span: TextSpan | null = null): BoltTypeAliasDeclaration { return new BoltTypeAliasDeclaration(modifiers, name, typeParams, typeExpr, span); }
@ -2255,7 +2268,7 @@ export function isFunctionBodyElement(value: any): value is FunctionBodyElement
export function isReturnStatement(value: any): value is ReturnStatement { return value.kind === SyntaxKind.JSReturnStatement || value.kind === SyntaxKind.BoltReturnStatement; }
export function isBoltSyntax(value: any): value is BoltSyntax { return value.kind === SyntaxKind.BoltMacroCall || value.kind === SyntaxKind.BoltRecordField || value.kind === SyntaxKind.BoltPlainExportSymbol || value.kind === SyntaxKind.BoltImportDirective || value.kind === SyntaxKind.BoltPlainImportSymbol || value.kind === SyntaxKind.BoltModule || value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltTypeAliasDeclaration || value.kind === SyntaxKind.BoltImplDeclaration || value.kind === SyntaxKind.BoltTraitDeclaration || value.kind === SyntaxKind.BoltVariableDeclaration || value.kind === SyntaxKind.BoltFunctionDeclaration || value.kind === SyntaxKind.BoltParameter || value.kind === SyntaxKind.BoltConditionalCase || value.kind === SyntaxKind.BoltLoopStatement || value.kind === SyntaxKind.BoltExpressionStatement || value.kind === SyntaxKind.BoltResumeStatement || value.kind === SyntaxKind.BoltConditionalStatement || value.kind === SyntaxKind.BoltReturnStatement || value.kind === SyntaxKind.BoltCase || value.kind === SyntaxKind.BoltMatchArm || value.kind === SyntaxKind.BoltConstantExpression || value.kind === SyntaxKind.BoltBlockExpression || value.kind === SyntaxKind.BoltCaseExpression || value.kind === SyntaxKind.BoltMatchExpression || value.kind === SyntaxKind.BoltYieldExpression || value.kind === SyntaxKind.BoltCallExpression || value.kind === SyntaxKind.BoltFunctionExpression || value.kind === SyntaxKind.BoltMemberExpression || value.kind === SyntaxKind.BoltReferenceExpression || value.kind === SyntaxKind.BoltTupleExpression || value.kind === SyntaxKind.BoltQuoteExpression || value.kind === SyntaxKind.BoltRecordFieldPattern || value.kind === SyntaxKind.BoltTuplePatternElement || value.kind === SyntaxKind.BoltRecordPattern || value.kind === SyntaxKind.BoltTuplePattern || value.kind === SyntaxKind.BoltExpressionPattern || value.kind === SyntaxKind.BoltTypePattern || value.kind === SyntaxKind.BoltBindPattern || value.kind === SyntaxKind.BoltTypeParameter || value.kind === SyntaxKind.BoltLiftedTypeExpression || value.kind === SyntaxKind.BoltFunctionTypeExpression || value.kind === SyntaxKind.BoltReferenceTypeExpression || value.kind === SyntaxKind.BoltTypeOfExpression || value.kind === SyntaxKind.BoltQualName || value.kind === SyntaxKind.BoltSourceFile || value.kind === SyntaxKind.BoltBracketed || value.kind === SyntaxKind.BoltBraced || value.kind === SyntaxKind.BoltParenthesized || value.kind === SyntaxKind.BoltImplKeyword || value.kind === SyntaxKind.BoltTraitKeyword || value.kind === SyntaxKind.BoltTypeKeyword || value.kind === SyntaxKind.BoltStructKeyword || value.kind === SyntaxKind.BoltEnumKeyword || value.kind === SyntaxKind.BoltMutKeyword || value.kind === SyntaxKind.BoltModKeyword || value.kind === SyntaxKind.BoltPubKeyword || value.kind === SyntaxKind.BoltExportKeyword || value.kind === SyntaxKind.BoltImportKeyword || value.kind === SyntaxKind.BoltMatchKeyword || value.kind === SyntaxKind.BoltYieldKeyword || value.kind === SyntaxKind.BoltLoopKeyword || value.kind === SyntaxKind.BoltReturnKeyword || value.kind === SyntaxKind.BoltLetKeyword || value.kind === SyntaxKind.BoltForKeyword || value.kind === SyntaxKind.BoltForeignKeyword || value.kind === SyntaxKind.BoltFnKeyword || value.kind === SyntaxKind.BoltQuoteKeyword || value.kind === SyntaxKind.BoltWhereKeyword || value.kind === SyntaxKind.BoltVBar || value.kind === SyntaxKind.BoltLtSign || value.kind === SyntaxKind.BoltExMark || value.kind === SyntaxKind.BoltGtSign || value.kind === SyntaxKind.BoltEqSign || value.kind === SyntaxKind.BoltLArrow || value.kind === SyntaxKind.BoltRArrowAlt || value.kind === SyntaxKind.BoltRArrow || value.kind === SyntaxKind.BoltDotDot || value.kind === SyntaxKind.BoltDot || value.kind === SyntaxKind.BoltColonColon || value.kind === SyntaxKind.BoltColon || value.kind === SyntaxKind.BoltSemi || value.kind === SyntaxKind.BoltComma || value.kind === SyntaxKind.BoltAssignment || value.kind === SyntaxKind.BoltOperator || value.kind === SyntaxKind.BoltIdentifier || value.kind === SyntaxKind.BoltIntegerLiteral || value.kind === SyntaxKind.BoltStringLiteral || value.kind === SyntaxKind.EndOfFile; }
export function isBoltSyntax(value: any): value is BoltSyntax { return value.kind === SyntaxKind.BoltMacroCall || value.kind === SyntaxKind.BoltRecordField || value.kind === SyntaxKind.BoltPlainExportSymbol || value.kind === SyntaxKind.BoltImportDirective || value.kind === SyntaxKind.BoltPlainImportSymbol || value.kind === SyntaxKind.BoltModule || value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltTypeAliasDeclaration || value.kind === SyntaxKind.BoltVariableDeclaration || value.kind === SyntaxKind.BoltFunctionDeclaration || value.kind === SyntaxKind.BoltParameter || value.kind === SyntaxKind.BoltConditionalCase || value.kind === SyntaxKind.BoltLoopStatement || value.kind === SyntaxKind.BoltExpressionStatement || value.kind === SyntaxKind.BoltResumeStatement || value.kind === SyntaxKind.BoltConditionalStatement || value.kind === SyntaxKind.BoltReturnStatement || value.kind === SyntaxKind.BoltCase || value.kind === SyntaxKind.BoltMatchArm || value.kind === SyntaxKind.BoltConstantExpression || value.kind === SyntaxKind.BoltBlockExpression || value.kind === SyntaxKind.BoltCaseExpression || value.kind === SyntaxKind.BoltMatchExpression || value.kind === SyntaxKind.BoltYieldExpression || value.kind === SyntaxKind.BoltCallExpression || value.kind === SyntaxKind.BoltFunctionExpression || value.kind === SyntaxKind.BoltMemberExpression || value.kind === SyntaxKind.BoltReferenceExpression || value.kind === SyntaxKind.BoltTupleExpression || value.kind === SyntaxKind.BoltQuoteExpression || value.kind === SyntaxKind.BoltRecordFieldPattern || value.kind === SyntaxKind.BoltTuplePatternElement || value.kind === SyntaxKind.BoltRecordPattern || value.kind === SyntaxKind.BoltTuplePattern || value.kind === SyntaxKind.BoltExpressionPattern || value.kind === SyntaxKind.BoltTypePattern || value.kind === SyntaxKind.BoltBindPattern || value.kind === SyntaxKind.BoltTypeParameter || value.kind === SyntaxKind.BoltLiftedTypeExpression || value.kind === SyntaxKind.BoltFunctionTypeExpression || value.kind === SyntaxKind.BoltReferenceTypeExpression || value.kind === SyntaxKind.BoltTypeOfExpression || value.kind === SyntaxKind.BoltQualName || value.kind === SyntaxKind.BoltSourceFile || value.kind === SyntaxKind.BoltBracketed || value.kind === SyntaxKind.BoltBraced || value.kind === SyntaxKind.BoltParenthesized || value.kind === SyntaxKind.BoltImplKeyword || value.kind === SyntaxKind.BoltTraitKeyword || value.kind === SyntaxKind.BoltTypeKeyword || value.kind === SyntaxKind.BoltStructKeyword || value.kind === SyntaxKind.BoltEnumKeyword || value.kind === SyntaxKind.BoltMutKeyword || value.kind === SyntaxKind.BoltModKeyword || value.kind === SyntaxKind.BoltPubKeyword || value.kind === SyntaxKind.BoltExportKeyword || value.kind === SyntaxKind.BoltImportKeyword || value.kind === SyntaxKind.BoltMatchKeyword || value.kind === SyntaxKind.BoltYieldKeyword || value.kind === SyntaxKind.BoltLoopKeyword || value.kind === SyntaxKind.BoltReturnKeyword || value.kind === SyntaxKind.BoltLetKeyword || value.kind === SyntaxKind.BoltForKeyword || value.kind === SyntaxKind.BoltForeignKeyword || value.kind === SyntaxKind.BoltFnKeyword || value.kind === SyntaxKind.BoltQuoteKeyword || value.kind === SyntaxKind.BoltWhereKeyword || value.kind === SyntaxKind.BoltVBar || value.kind === SyntaxKind.BoltLtSign || value.kind === SyntaxKind.BoltExMark || value.kind === SyntaxKind.BoltGtSign || value.kind === SyntaxKind.BoltEqSign || value.kind === SyntaxKind.BoltLArrow || value.kind === SyntaxKind.BoltRArrowAlt || value.kind === SyntaxKind.BoltRArrow || value.kind === SyntaxKind.BoltDotDot || value.kind === SyntaxKind.BoltDot || value.kind === SyntaxKind.BoltColonColon || value.kind === SyntaxKind.BoltColon || value.kind === SyntaxKind.BoltSemi || value.kind === SyntaxKind.BoltComma || value.kind === SyntaxKind.BoltAssignment || value.kind === SyntaxKind.BoltOperator || value.kind === SyntaxKind.BoltIdentifier || value.kind === SyntaxKind.BoltIntegerLiteral || value.kind === SyntaxKind.BoltStringLiteral || value.kind === SyntaxKind.EndOfFile; }
export function isBoltToken(value: any): value is BoltToken { return value.kind === SyntaxKind.BoltBracketed || value.kind === SyntaxKind.BoltBraced || value.kind === SyntaxKind.BoltParenthesized || value.kind === SyntaxKind.BoltImplKeyword || value.kind === SyntaxKind.BoltTraitKeyword || value.kind === SyntaxKind.BoltTypeKeyword || value.kind === SyntaxKind.BoltStructKeyword || value.kind === SyntaxKind.BoltEnumKeyword || value.kind === SyntaxKind.BoltMutKeyword || value.kind === SyntaxKind.BoltModKeyword || value.kind === SyntaxKind.BoltPubKeyword || value.kind === SyntaxKind.BoltExportKeyword || value.kind === SyntaxKind.BoltImportKeyword || value.kind === SyntaxKind.BoltMatchKeyword || value.kind === SyntaxKind.BoltYieldKeyword || value.kind === SyntaxKind.BoltLoopKeyword || value.kind === SyntaxKind.BoltReturnKeyword || value.kind === SyntaxKind.BoltLetKeyword || value.kind === SyntaxKind.BoltForKeyword || value.kind === SyntaxKind.BoltForeignKeyword || value.kind === SyntaxKind.BoltFnKeyword || value.kind === SyntaxKind.BoltQuoteKeyword || value.kind === SyntaxKind.BoltWhereKeyword || value.kind === SyntaxKind.BoltVBar || value.kind === SyntaxKind.BoltLtSign || value.kind === SyntaxKind.BoltExMark || value.kind === SyntaxKind.BoltGtSign || value.kind === SyntaxKind.BoltEqSign || value.kind === SyntaxKind.BoltLArrow || value.kind === SyntaxKind.BoltRArrowAlt || value.kind === SyntaxKind.BoltRArrow || value.kind === SyntaxKind.BoltDotDot || value.kind === SyntaxKind.BoltDot || value.kind === SyntaxKind.BoltColonColon || value.kind === SyntaxKind.BoltColon || value.kind === SyntaxKind.BoltSemi || value.kind === SyntaxKind.BoltComma || value.kind === SyntaxKind.BoltAssignment || value.kind === SyntaxKind.BoltOperator || value.kind === SyntaxKind.BoltIdentifier || value.kind === SyntaxKind.BoltIntegerLiteral || value.kind === SyntaxKind.BoltStringLiteral || value.kind === SyntaxKind.EndOfFile; }
@ -2429,7 +2442,7 @@ export function isBoltParameter(value: any): value is BoltParameter { return val
export function isBoltDeclaration(value: any): value is BoltDeclaration { return value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltVariableDeclaration || value.kind === SyntaxKind.BoltFunctionDeclaration; }
export function isBoltTypeDeclaration(value: any): value is BoltTypeDeclaration { return value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltTypeAliasDeclaration || value.kind === SyntaxKind.BoltImplDeclaration || value.kind === SyntaxKind.BoltTraitDeclaration; }
export function isBoltTypeDeclaration(value: any): value is BoltTypeDeclaration { return value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltTypeAliasDeclaration; }
export function isBoltModule(value: any): value is BoltModule { return value.kind === SyntaxKind.BoltModule; }
@ -2467,7 +2480,7 @@ export function isBoltRecordField(value: any): value is BoltRecordField { return
export function isBoltRecordDeclaration(value: any): value is BoltRecordDeclaration { return value.kind === SyntaxKind.BoltRecordDeclaration; }
export function isBoltSourceElement(value: any): value is BoltSourceElement { return value.kind === SyntaxKind.BoltMacroCall || value.kind === SyntaxKind.BoltExportDirective || value.kind === SyntaxKind.BoltImportDirective || value.kind === SyntaxKind.BoltModule || value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltTypeAliasDeclaration || value.kind === SyntaxKind.BoltImplDeclaration || value.kind === SyntaxKind.BoltTraitDeclaration || value.kind === SyntaxKind.BoltVariableDeclaration || value.kind === SyntaxKind.BoltFunctionDeclaration || value.kind === SyntaxKind.BoltLoopStatement || value.kind === SyntaxKind.BoltExpressionStatement || value.kind === SyntaxKind.BoltResumeStatement || value.kind === SyntaxKind.BoltConditionalStatement || value.kind === SyntaxKind.BoltReturnStatement; }
export function isBoltSourceElement(value: any): value is BoltSourceElement { return value.kind === SyntaxKind.BoltMacroCall || value.kind === SyntaxKind.BoltExportDirective || value.kind === SyntaxKind.BoltImportDirective || value.kind === SyntaxKind.BoltModule || value.kind === SyntaxKind.BoltRecordDeclaration || value.kind === SyntaxKind.BoltTypeAliasDeclaration || value.kind === SyntaxKind.BoltVariableDeclaration || value.kind === SyntaxKind.BoltFunctionDeclaration || value.kind === SyntaxKind.BoltLoopStatement || value.kind === SyntaxKind.BoltExpressionStatement || value.kind === SyntaxKind.BoltResumeStatement || value.kind === SyntaxKind.BoltConditionalStatement || value.kind === SyntaxKind.BoltReturnStatement; }
export function isBoltMacroCall(value: any): value is BoltMacroCall { return value.kind === SyntaxKind.BoltMacroCall; }
@ -3187,8 +3200,8 @@ export class Visitor {
protected visitBoltPlainExportSymbol(node: BoltPlainExportSymbol): void { this.visitBoltExportSymbol(node); }
protected visitBoltExportDirective(node: BoltExportDirective): void { this.visitBoltSourceElement(node); }
protected visitBoltTraitOrImplElement(node: BoltTraitOrImplElement): void { this.visitSyntax(node); }
protected visitBoltTraitDeclaration(node: BoltTraitDeclaration): void { this.visitBoltDeclarationLike(node); this.visitBoltTypeDeclaration(node); }
protected visitBoltImplDeclaration(node: BoltImplDeclaration): void { this.visitBoltTypeDeclaration(node); this.visitBoltDeclarationLike(node); }
protected visitBoltTraitDeclaration(node: BoltTraitDeclaration): void { this.visitBoltDeclarationLike(node); }
protected visitBoltImplDeclaration(node: BoltImplDeclaration): void { this.visitBoltDeclarationLike(node); }
protected visitBoltTypeAliasDeclaration(node: BoltTypeAliasDeclaration): void { this.visitBoltDeclarationLike(node); this.visitBoltTypeDeclaration(node); this.visitBoltTraitOrImplElement(node); }
protected visitBoltRecordMember(node: BoltRecordMember): void { this.visitBoltSyntax(node); }
protected visitBoltRecordField(node: BoltRecordField): void { this.visitBoltRecordMember(node); }

View file

@ -21,8 +21,6 @@ import { Parser } from "../parser"
import { Scanner } from "../scanner"
import { TextFile, TextPos, TextSpan } from "../text"
import { deserializable, deserialize, Json, JsonObject, MapLike, serialize, serializeTag, upsearchSync, assert } from "../util"
import { resolve } from "path"
import { expect } from "chai"
const PACKAGE_ROOT = path.resolve(path.dirname(upsearchSync('package.json')!));
const DEFAULT_STORAGE_DIR = 'test-storage';

View file

@ -20,7 +20,7 @@ import { BOLT_SUPPORTED_LANGUAGES } from "./constants"
import { FastStringMap, enumOr, escapeChar, assert, registerClass, Newable } from "./util";
import { TextSpan, TextPos, TextFile } from "./text";
import { Scanner } from "./scanner";
import { convertNodeToSymbolPath } from "./resolver";
import { convertNodeToSymbolPath, SymbolPath } from "./resolver";
import { TYPE_ERROR_MESSAGES } from "./diagnostics";
import { NODE_TYPES } from "./ast"
@ -231,7 +231,7 @@ export function hasDiagnostic(node: Syntax, message: string): boolean {
return node.errors.some(d => d.message === message);
}
export function getFullyQualifiedPathToNode(node: Syntax) {
export function getFullyQualifiedPathToNode(node: Syntax): SymbolPath {
const symbolPath = convertNodeToSymbolPath(node);
while (true) {
const parentNode = node.parentNode;

View file

@ -1300,8 +1300,8 @@ export class Parser {
let modifiers = 0;
let typeParams = null;
let traitTypeExpr = null;
let name;
let traitTypeExpr;
let typeExpr = null;
// Parse the 'pub' keyword
let t0 = tokens.get();
@ -1337,16 +1337,26 @@ export class Parser {
if (foundForKeyword) {
// Parse the type expression that references the trait the user wants to implement
traitTypeExpr = this.parseTypeExpression(tokens);
// Skip the 'for' keyword itself
tokens.get();
}
assertToken(tokens.get(), SyntaxKind.BoltForKeyword);
// Parse the name of the type that this implementation is for
const t3 = tokens.get();
assertToken(t3, SyntaxKind.BoltIdentifier);
name = t3 as BoltIdentifier;
// Parse the type that this implementation is for
typeExpr = this.parseTypeExpression(tokens);
} else {
// Just parse the trait the user wants to implement and leave the rest as is
const resultTypeExpr = this.parseTypeExpression(tokens);
// We cheat a bit by assigning the referenced trait to both fields
// NOTE Assigning the same node by reference to different fields should be done with great care.
typeExpr = resultTypeExpr;
traitTypeExpr = resultTypeExpr;
}
// Parse all 'fn ...' and 'type ...' elements
const t5 = tokens.get();
@ -1354,7 +1364,7 @@ export class Parser {
const elements = this.parseTraitOrImplElements(createTokenStream(t5));
// Create and return the result
const result = createBoltImplDeclaration(modifiers, typeParams, name, traitTypeExpr, elements);
const result = createBoltImplDeclaration(modifiers, typeParams, typeExpr, traitTypeExpr, elements);
setOrigNodeRange(result, firstToken, t5);
return result;
}

View file

@ -57,7 +57,13 @@ export function convertNodeToSymbolPath(node: Syntax): SymbolPath {
return new SymbolPath(
node.name.modulePath.map(id => id.text),
node.name.isAbsolute,
emitNode(node.name),
emitNode(node.name.name),
);
case SyntaxKind.BoltReferenceTypeExpression:
return new SymbolPath(
node.name.modulePath.map(id => id.text),
node.name.isAbsolute,
emitNode(node.name.name),
);
case SyntaxKind.BoltIdentifier:
return new SymbolPath([], false, emitNode(node));
@ -164,7 +170,7 @@ export class BoltSymbolResolutionStrategy implements ResolutionStrategy {
case SyntaxKind.BoltTraitDeclaration:
return node.name.text;
case SyntaxKind.BoltImplDeclaration:
return node.name.text;
return node.type;
default:
throw new Error(`Could not derive symbol name of node ${kindToString(node.kind)}`)
}

View file

@ -1,6 +1,6 @@
import { FastStringMap, assert, isPlainObject, some, prettyPrintTag, map, flatMap, filter, memoize, comparator, createTransparentProxy, TransparentProxy, every, FastMultiMap, getKeyTag } from "./util";
import { SyntaxKind, Syntax, isBoltTypeExpression, BoltExpression, BoltFunctionDeclaration, BoltFunctionBodyElement, kindToString, SourceFile, isBoltExpression, BoltCallExpression, BoltIdentifier, isBoltDeclarationLike, isBoltPattern, isJSExpression, isBoltStatement, isJSStatement, isJSPattern, isJSParameter, isBoltParameter, isBoltMatchArm, isBoltRecordField, isBoltRecordFieldPattern, isEndOfFile, isSyntax, isBoltFunctionDeclaration, isBoltTypeDeclaration, isBoltRecordDeclaration, } from "./ast";
import { SyntaxKind, Syntax, isBoltTypeExpression, BoltExpression, BoltFunctionDeclaration, BoltFunctionBodyElement, kindToString, SourceFile, isBoltExpression, BoltCallExpression, BoltIdentifier, isBoltDeclarationLike, isBoltPattern, isJSExpression, isBoltStatement, isJSStatement, isJSPattern, isJSParameter, isBoltParameter, isBoltMatchArm, isBoltRecordField, isBoltRecordFieldPattern, isEndOfFile, isSyntax, isBoltFunctionDeclaration, isBoltTypeDeclaration, isBoltRecordDeclaration, BoltImplDeclaration, isBoltTraitDeclaration, isBoltImplDeclaration, BoltTypeExpression, BoltDeclaration, BoltTypeDeclaration, BoltReferenceExpression, BoltReferenceTypeExpression, } from "./ast";
import { convertNodeToSymbolPath, ScopeType, SymbolResolver, SymbolInfo, SymbolPath } from "./resolver";
import { Value, Record } from "./evaluator";
import { getReturnStatementsInFunctionBody, getAllReturnStatementsInFunctionBody, getFullyQualifiedPathToNode, hasDiagnostic, hasTypeError } from "./common";
@ -27,6 +27,7 @@ enum TypeKind {
UnionType,
TupleType,
ReturnType,
TraitType,
}
export type Type
@ -40,6 +41,7 @@ export type Type
| TupleType
| UnionType
| PlainRecordFieldType
| TraitType
let nextTypeId = 1;
@ -65,6 +67,9 @@ function areTypesLexicallyEquivalent(a: Type, b: Type): boolean {
if (a.kind === TypeKind.RecordType && b.kind === TypeKind.RecordType) {
return a.source.id === b.source.id;
}
if (a.kind === TypeKind.TraitType && b.kind === TypeKind.TraitType) {
return a.source.id === b.source.id;
}
throw new Error(`I did not expected to see the provided type combination.`)
@ -107,6 +112,9 @@ function areTypesLexicallyLessThan(a: Type, b: Type): boolean {
assert(b.source.id !== undefined)
return a.source.id < b.source.id;
}
if (a.kind === TypeKind.TraitType && b.kind === TypeKind.TraitType) {
return a.source.id < b.source.id;
}
throw new Error(`I did not expected to see the provided type combination.`)
}
@ -238,6 +246,21 @@ class PlainRecordFieldType extends TypeBase {
}
export class TraitType extends TypeBase {
public kind: TypeKind.TraitType = TypeKind.TraitType;
private functionTypesByName = new FastStringMap<string, FunctionType>();
constructor(public source: Syntax, public memberTypes: Iterable<[string, FunctionType]>) {
super();
for (const [name, type] of memberTypes) {
this.functionTypesByName.set(name, type);
}
}
}
export class RecordType extends TypeBase {
public kind: TypeKind.RecordType = TypeKind.RecordType;
@ -491,7 +514,7 @@ export class TypeChecker {
}
private *diagnoseTypeMismatch(a: Type, b: Type): IterableIterator<Diagnostic> {
// FIXME Implement this method
}
public registerSourceFile(sourceFile: SourceFile): void {
@ -499,6 +522,14 @@ export class TypeChecker {
if (introducesType(node)) {
node.type = new AnyType;
}
if (isBoltImplDeclaration(node)) {
const scope = this.resolver.getScopeSurroundingNode(node, ScopeType.Type);
assert(scope !== null);
const traitSymbol = this.resolver.resolveSymbolPath(convertNodeToSymbolPath(node.traitTypeExpr), scope!)
for (const traitDecl of traitSymbol!.declarations) {
traitDecl.addImplDeclaration(node);
}
}
}
}
@ -564,9 +595,12 @@ export class TypeChecker {
node.type!.solved.nextType = narrowedType;
}
for (const dependantNode of this.getParentsThatMightNeedUpdate(node)) {
if (introducesType(dependantNode)) {
nextQueue.add(dependantNode);
}
}
for (const dependantNode of this.getNodesRequiringUpdate(node)) {
assert(introducesType(dependantNode));
nextQueue.add(dependantNode);
}
}
@ -644,6 +678,7 @@ export class TypeChecker {
case TypeKind.OpaqueType:
case TypeKind.FunctionType:
case TypeKind.RecordType:
case TypeKind.TraitType:
elementTypes.push(elementType);
break;
@ -676,6 +711,7 @@ export class TypeChecker {
case TypeKind.FunctionType:
case TypeKind.RecordType:
case TypeKind.OpaqueType:
case TypeKind.TraitType:
elementTypes.push(elementType);
break
@ -838,16 +874,27 @@ export class TypeChecker {
return new AnyType;
}
case SyntaxKind.BoltImplDeclaration:
{
return new AnyType;
}
//case SyntaxKind.BoltImplDeclaration:
//{
// return new TraitType(
// node,
// node.elements
// .filter(isBoltFunctionDeclaration)
// .map(element => {
// this.markNodeAsRequiringUpdate(element, node);
// return [
// emitNode(element.name),
// element.type!.solved
// ] as [string, FunctionType];
// })
// );
//}
case SyntaxKind.BoltTraitDeclaration:
{
// TODO
return new AnyType;
}
//case SyntaxKind.BoltTraitDeclaration:
//{
// // TODO
// return new AnyType;
//}
case SyntaxKind.BoltVariableDeclaration:
{
@ -1121,9 +1168,13 @@ export class TypeChecker {
if (a.kind === TypeKind.RecordType && b.kind === TypeKind.RecordType) {
return a.source === b.source;
}
if (a.kind === TypeKind.TraitType && b.kind === TypeKind.TraitType) {
return a.source === b.source;
}
// FIXME There are probably more cases that should be covered.
throw new Error(`I did not know how to calculate the equivalence of ${TypeKind[a.kind]} and ${TypeKind[b.kind]}`)
return false;
//throw new Error(`I did not know how to calculate the equivalence of ${TypeKind[a.kind]} and ${TypeKind[b.kind]}`)
}
private resolveReturnType(type: ReturnType): Type {
@ -1318,11 +1369,12 @@ export class TypeChecker {
case TypeKind.FunctionType:
case TypeKind.NeverType:
case TypeKind.OpaqueType:
case TypeKind.TraitType:
resultTypes.push(elementType);
break;
default:
throw new Error(`I did not know how to simpllify type ${TypeKind[elementType.kind]}`)
throw new Error(`I did not know how to simplify type ${TypeKind[elementType.kind]}`)
}