2023-03-11 14:24:02 +01:00
|
|
|
|
|
|
|
import type stream from "stream";
|
|
|
|
import path from "path"
|
|
|
|
|
2023-06-26 19:02:23 +02:00
|
|
|
import { assert, implementationLimitation, IndentWriter, JSONObject, JSONValue, nonenumerable, unreachable } from "./util";
|
2023-02-03 17:51:27 +01:00
|
|
|
import { isNodeWithScope, Scope } from "./scope"
|
2023-08-12 13:46:19 +02:00
|
|
|
import type { Kind, Scheme } from "./checker"
|
2023-06-21 16:56:04 +02:00
|
|
|
import type { Type } from "./types";
|
2023-03-11 14:24:02 +01:00
|
|
|
import { Emitter } from "./emitter";
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export type TextSpan = [number, number];
|
|
|
|
|
2022-09-16 19:43:52 +02:00
|
|
|
export type Value
|
|
|
|
= bigint
|
|
|
|
| string
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class TextPosition {
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public offset: number,
|
|
|
|
public line: number,
|
|
|
|
public column: number,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): TextPosition {
|
|
|
|
return new TextPosition(
|
|
|
|
this.offset,
|
|
|
|
this.line,
|
|
|
|
this.column,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public advance(text: string): void {
|
|
|
|
for (const ch of text) {
|
|
|
|
if (ch === '\n') {
|
|
|
|
this.line++;
|
|
|
|
this.column = 1;
|
|
|
|
} else {
|
|
|
|
this.column++;
|
|
|
|
}
|
|
|
|
}
|
2023-04-12 19:38:45 +02:00
|
|
|
this.offset += text.length;
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TextRange {
|
|
|
|
|
|
|
|
constructor(
|
|
|
|
public start: TextPosition,
|
|
|
|
public end: TextPosition,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): TextRange {
|
|
|
|
return new TextRange(
|
|
|
|
this.start.clone(),
|
|
|
|
this.end.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TextFile {
|
|
|
|
|
2023-07-01 01:26:18 +02:00
|
|
|
public comments = new Map<number, Token[]>();
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
|
|
|
public origPath: string,
|
|
|
|
public text: string,
|
|
|
|
) {
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-11 14:24:02 +01:00
|
|
|
public getFullPath(): string {
|
|
|
|
return path.resolve(this.origPath);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export const enum SyntaxKind {
|
|
|
|
|
|
|
|
// Tokens
|
|
|
|
Identifier,
|
2022-09-01 20:18:47 +02:00
|
|
|
IdentifierAlt,
|
2022-08-28 21:12:25 +02:00
|
|
|
CustomOperator,
|
2022-09-01 20:06:43 +02:00
|
|
|
Assignment,
|
2022-08-28 21:12:25 +02:00
|
|
|
LParen,
|
|
|
|
RParen,
|
|
|
|
LBrace,
|
|
|
|
RBrace,
|
|
|
|
LBracket,
|
|
|
|
RBracket,
|
2022-09-09 22:37:14 +02:00
|
|
|
RArrow,
|
2022-09-16 11:31:34 +02:00
|
|
|
RArrowAlt,
|
|
|
|
VBar,
|
2022-08-28 21:12:25 +02:00
|
|
|
Dot,
|
|
|
|
DotDot,
|
2023-06-30 19:30:42 +02:00
|
|
|
At,
|
2022-08-28 21:12:25 +02:00
|
|
|
Comma,
|
|
|
|
Colon,
|
|
|
|
Equals,
|
2023-02-06 11:50:38 +01:00
|
|
|
Backslash,
|
2022-08-28 21:12:25 +02:00
|
|
|
Integer,
|
|
|
|
StringLiteral,
|
|
|
|
LetKeyword,
|
|
|
|
PubKeyword,
|
|
|
|
MutKeyword,
|
|
|
|
ModKeyword,
|
|
|
|
ImportKeyword,
|
2023-02-03 17:51:27 +01:00
|
|
|
ClassKeyword,
|
|
|
|
InstanceKeyword,
|
2022-08-28 21:12:25 +02:00
|
|
|
StructKeyword,
|
2022-09-10 14:11:04 +02:00
|
|
|
EnumKeyword,
|
2022-08-28 21:12:25 +02:00
|
|
|
TypeKeyword,
|
2022-08-29 16:17:55 +02:00
|
|
|
ReturnKeyword,
|
|
|
|
MatchKeyword,
|
2022-09-16 19:50:18 +02:00
|
|
|
ForeignKeyword,
|
2022-08-29 16:17:55 +02:00
|
|
|
IfKeyword,
|
|
|
|
ElifKeyword,
|
|
|
|
ElseKeyword,
|
2023-06-21 16:56:04 +02:00
|
|
|
ForallKeyword,
|
2022-08-28 21:12:25 +02:00
|
|
|
LineFoldEnd,
|
|
|
|
BlockEnd,
|
|
|
|
BlockStart,
|
|
|
|
EndOfFile,
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
// Annotations
|
|
|
|
TypeAnnotation,
|
|
|
|
ExpressionAnnotation,
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
// Type expressions
|
|
|
|
ReferenceTypeExpression,
|
2022-09-09 22:37:14 +02:00
|
|
|
ArrowTypeExpression,
|
2022-09-10 16:52:14 +02:00
|
|
|
VarTypeExpression,
|
2022-09-11 11:20:21 +02:00
|
|
|
AppTypeExpression,
|
2022-09-14 16:46:30 +02:00
|
|
|
NestedTypeExpression,
|
2022-09-16 12:43:06 +02:00
|
|
|
TupleTypeExpression,
|
2023-06-21 16:56:04 +02:00
|
|
|
ForallTypeExpression,
|
|
|
|
TypeExpressionWithConstraints,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
// Patterns
|
2023-03-11 14:24:02 +01:00
|
|
|
NamedPattern,
|
2022-08-28 21:12:25 +02:00
|
|
|
TuplePattern,
|
2022-08-29 16:17:55 +02:00
|
|
|
StructPattern,
|
|
|
|
NestedPattern,
|
|
|
|
NamedTuplePattern,
|
2022-09-16 11:31:34 +02:00
|
|
|
LiteralPattern,
|
|
|
|
DisjunctivePattern,
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
// Struct expression elements
|
|
|
|
StructExpressionField,
|
|
|
|
PunnedStructExpressionField,
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
// Struct pattern elements
|
2022-09-01 20:06:43 +02:00
|
|
|
StructPatternField,
|
|
|
|
PunnedStructPatternField,
|
2022-08-29 16:17:55 +02:00
|
|
|
VariadicStructPatternElement,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
// Expressions
|
2022-09-16 11:31:34 +02:00
|
|
|
MatchExpression,
|
2022-09-09 00:00:28 +02:00
|
|
|
MemberExpression,
|
2022-08-31 13:29:56 +02:00
|
|
|
CallExpression,
|
2022-08-28 21:12:25 +02:00
|
|
|
ReferenceExpression,
|
2022-08-31 13:29:56 +02:00
|
|
|
StructExpression,
|
2022-08-28 21:12:25 +02:00
|
|
|
TupleExpression,
|
|
|
|
NestedExpression,
|
|
|
|
ConstantExpression,
|
|
|
|
PrefixExpression,
|
|
|
|
PostfixExpression,
|
|
|
|
InfixExpression,
|
2023-02-06 11:50:38 +01:00
|
|
|
FunctionExpression,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
// Statements
|
|
|
|
ReturnStatement,
|
|
|
|
ExpressionStatement,
|
2022-09-01 20:06:43 +02:00
|
|
|
IfStatement,
|
2023-03-19 17:02:59 +01:00
|
|
|
AssignStatement,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
// If statement elements
|
|
|
|
IfStatementCase,
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
// Declarations
|
|
|
|
LetDeclaration,
|
|
|
|
StructDeclaration,
|
2022-09-10 14:11:04 +02:00
|
|
|
EnumDeclaration,
|
2022-08-28 21:12:25 +02:00
|
|
|
ImportDeclaration,
|
2022-09-11 11:20:21 +02:00
|
|
|
TypeDeclaration,
|
2023-02-03 17:51:27 +01:00
|
|
|
ClassDeclaration,
|
|
|
|
InstanceDeclaration,
|
|
|
|
ModuleDeclaration,
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
// Let declaration body members
|
2022-08-28 21:12:25 +02:00
|
|
|
ExprBody,
|
|
|
|
BlockBody,
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
// Structure declaration members
|
|
|
|
StructDeclarationField,
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
// Enum declaration elements
|
|
|
|
EnumDeclarationStructElement,
|
|
|
|
EnumDeclarationTupleElement,
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
// Other nodes
|
2022-09-09 22:37:14 +02:00
|
|
|
WrappedOperator,
|
2022-09-16 11:31:34 +02:00
|
|
|
MatchArm,
|
2022-08-29 16:17:55 +02:00
|
|
|
Initializer,
|
2022-08-28 21:12:25 +02:00
|
|
|
TypeAssert,
|
|
|
|
Param,
|
|
|
|
SourceFile,
|
2023-02-03 17:51:27 +01:00
|
|
|
ClassConstraint,
|
|
|
|
ClassConstraintClause,
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Syntax
|
|
|
|
= SourceFile
|
2022-09-17 13:20:49 +02:00
|
|
|
| ModuleDeclaration
|
2023-02-03 17:51:27 +01:00
|
|
|
| ClassDeclaration
|
|
|
|
| InstanceDeclaration
|
|
|
|
| ClassConstraint
|
2023-02-06 11:50:38 +01:00
|
|
|
| ClassConstraintClause
|
2022-08-31 13:29:56 +02:00
|
|
|
| Token
|
2022-08-28 21:12:25 +02:00
|
|
|
| Param
|
2022-08-31 13:29:56 +02:00
|
|
|
| Body
|
2023-02-06 11:50:38 +01:00
|
|
|
| MatchArm
|
|
|
|
| WrappedOperator
|
|
|
|
| Initializer
|
|
|
|
| IfStatementCase
|
2022-08-28 21:12:25 +02:00
|
|
|
| StructDeclarationField
|
2022-09-11 11:20:21 +02:00
|
|
|
| EnumDeclarationElement
|
2022-09-05 17:25:55 +02:00
|
|
|
| TypeAssert
|
2023-06-30 19:30:42 +02:00
|
|
|
| Annotation
|
2022-08-28 21:12:25 +02:00
|
|
|
| Declaration
|
|
|
|
| Statement
|
|
|
|
| Expression
|
|
|
|
| TypeExpression
|
|
|
|
| Pattern
|
2022-09-07 12:45:38 +02:00
|
|
|
| StructExpressionElement
|
|
|
|
| StructPatternElement
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2023-04-14 19:57:59 +02:00
|
|
|
function isnonenumerabledProperty(key: string): boolean {
|
2022-08-31 13:29:56 +02:00
|
|
|
return key === 'kind' || key === 'parent';
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
abstract class SyntaxBase {
|
|
|
|
|
2023-04-14 19:57:59 +02:00
|
|
|
@nonenumerable
|
|
|
|
public abstract readonly kind: SyntaxKind;
|
|
|
|
|
|
|
|
@nonenumerable
|
2022-08-31 13:29:56 +02:00
|
|
|
public parent: Syntax | null = null;
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public abstract getFirstToken(): Token;
|
|
|
|
|
|
|
|
public abstract getLastToken(): Token;
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public abstract clone(): Syntax;
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getRange(): TextRange {
|
|
|
|
return new TextRange(
|
|
|
|
this.getFirstToken().getStartPosition(),
|
|
|
|
this.getLastToken().getEndPosition(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getSourceFile(): SourceFile {
|
|
|
|
let curr = this as any;
|
|
|
|
do {
|
|
|
|
if (curr.kind === SyntaxKind.SourceFile) {
|
|
|
|
return curr;
|
|
|
|
}
|
|
|
|
curr = curr.parent;
|
|
|
|
} while (curr != null);
|
|
|
|
throw new Error(`Could not find a SourceFile in any of the parent nodes of ${this}`);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getScope(): Scope {
|
|
|
|
let curr: Syntax | null = this as any;
|
|
|
|
do {
|
|
|
|
if (isNodeWithScope(curr!)) {
|
|
|
|
if (curr.scope === undefined) {
|
|
|
|
curr.scope = new Scope(curr);
|
|
|
|
}
|
|
|
|
return curr.scope;
|
|
|
|
}
|
|
|
|
curr = curr!.parent;
|
|
|
|
} while (curr !== null);
|
|
|
|
throw new Error(`Could not find a scope for ${this}. Maybe the parent links are not set?`);
|
|
|
|
}
|
|
|
|
|
2023-08-12 13:46:19 +02:00
|
|
|
public getParentScope(): Scope | null {
|
|
|
|
return this.parent === null ? null : this.parent.getScope();
|
|
|
|
}
|
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
public getEnclosingModule(): ModuleDeclaration | SourceFile {
|
|
|
|
let curr = this.parent!;
|
|
|
|
while (curr !== null) {
|
|
|
|
if (curr.kind === SyntaxKind.SourceFile || curr.kind === SyntaxKind.ModuleDeclaration) {
|
|
|
|
return curr;
|
|
|
|
}
|
|
|
|
curr = curr.parent!;
|
|
|
|
}
|
|
|
|
throw new Error(`Unable to find an enclosing module for ${this.constructor.name}. Perhaps the parent-links are not set?`);
|
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public setParents(): void {
|
|
|
|
|
|
|
|
const visit = (value: any) => {
|
|
|
|
if (value === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
value.forEach(visit);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (value instanceof SyntaxBase) {
|
|
|
|
value.parent = this as any;
|
|
|
|
value.setParents();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const key of Object.getOwnPropertyNames(this)) {
|
2023-04-14 19:57:59 +02:00
|
|
|
if (isnonenumerabledProperty(key)) {
|
2022-08-31 13:29:56 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
visit((this as any)[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-11 14:24:02 +01:00
|
|
|
public *getTokens(): Iterable<Token> {
|
|
|
|
for (const [_, value] of this.getFields()) {
|
|
|
|
yield* filter(value);
|
|
|
|
}
|
|
|
|
function* filter(value: any): Iterable<Token> {
|
|
|
|
if (isToken(value)) {
|
|
|
|
yield value;
|
|
|
|
} else if (Array.isArray(value)) {
|
|
|
|
for (const element of value) {
|
|
|
|
yield* filter(element);
|
|
|
|
}
|
|
|
|
} else if (isSyntax(value)) {
|
|
|
|
yield* value.getTokens();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public *getFields(): Iterable<[string, any]> {
|
|
|
|
for (const key of Object.getOwnPropertyNames(this)) {
|
2023-04-14 19:57:59 +02:00
|
|
|
if (!isnonenumerabledProperty(key)) {
|
2023-03-11 14:24:02 +01:00
|
|
|
yield [key, (this as any)[key]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public *getChildNodes(): Iterable<Syntax> {
|
|
|
|
function* visit(value: any): Iterable<Syntax> {
|
|
|
|
if (value === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
for (const element of value) {
|
|
|
|
yield* visit(element);
|
|
|
|
}
|
|
|
|
} else if (isSyntax(value)) {
|
|
|
|
yield value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (const [_key, value] of this.getFields()) {
|
|
|
|
yield* visit(value);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public emit(file: stream.Writable): void {
|
|
|
|
const emitter = new Emitter(new IndentWriter(file));
|
|
|
|
emitter.emit(this as any);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public toJSON(): JSONObject {
|
|
|
|
|
|
|
|
const obj: JSONObject = {};
|
|
|
|
obj['type'] = this.constructor.name;
|
2023-03-11 14:24:02 +01:00
|
|
|
for (const [key, value] of this.getFields()) {
|
2023-04-14 19:57:59 +02:00
|
|
|
if (isnonenumerabledProperty(key)) {
|
2022-08-29 16:17:55 +02:00
|
|
|
continue;
|
|
|
|
}
|
2023-03-11 14:24:02 +01:00
|
|
|
obj[key] = encode(value);
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
return obj;
|
|
|
|
|
|
|
|
function encode(value: any): JSONValue {
|
|
|
|
if (value === null) {
|
|
|
|
return null;
|
|
|
|
} else if (Array.isArray(value)) {
|
|
|
|
return value.map(encode);
|
2023-03-11 14:24:02 +01:00
|
|
|
} else if (isSyntax(value)) {
|
2022-08-29 16:17:55 +02:00
|
|
|
return value.toJSON();
|
|
|
|
} else {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
public resolveModule(name: string): ModuleDeclaration | null {
|
|
|
|
const node = this as unknown as Syntax;
|
|
|
|
assert(node.kind === SyntaxKind.ModuleDeclaration || node.kind === SyntaxKind.SourceFile);
|
|
|
|
for (const element of node.elements) {
|
|
|
|
if (element.kind === SyntaxKind.ModuleDeclaration && element.name.text === name) {
|
|
|
|
return element;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getModulePath(): string[] {
|
|
|
|
let curr = this.parent;
|
|
|
|
const modulePath = [];
|
|
|
|
while (curr !== null) {
|
|
|
|
if (curr.kind === SyntaxKind.ModuleDeclaration) {
|
|
|
|
modulePath.unshift(curr.name.text);
|
|
|
|
}
|
|
|
|
curr = curr.parent;
|
|
|
|
}
|
|
|
|
return modulePath;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-10 16:52:14 +02:00
|
|
|
export function forEachChild(node: Syntax, callback: (node: Syntax) => void): void {
|
|
|
|
|
|
|
|
for (const key of Object.getOwnPropertyNames(node)) {
|
2023-04-14 19:57:59 +02:00
|
|
|
if (isnonenumerabledProperty(key)) {
|
2022-09-10 16:52:14 +02:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
visitField((node as any)[key]);
|
|
|
|
}
|
|
|
|
|
|
|
|
function visitField(field: any): void {
|
|
|
|
if (field === null) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (Array.isArray(field)) {
|
|
|
|
for (const element of field) {
|
|
|
|
visitField(element);
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (field instanceof SyntaxBase) {
|
|
|
|
callback(field as Syntax);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
abstract class TokenBase extends SyntaxBase {
|
|
|
|
|
2023-04-14 19:57:59 +02:00
|
|
|
@nonenumerable
|
2022-08-28 21:12:25 +02:00
|
|
|
private endPos: TextPosition | null = null;
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
public startPos: TextPosition | null = null,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
2023-07-04 20:38:40 +02:00
|
|
|
return this as Token;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2023-07-04 20:38:40 +02:00
|
|
|
return this as Token;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getRange(): TextRange {
|
|
|
|
return new TextRange(
|
|
|
|
this.getStartPosition(),
|
|
|
|
this.getEndPosition(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public getStartPosition(): TextPosition {
|
2023-02-06 11:50:38 +01:00
|
|
|
assert(this.startPos !== null);
|
2022-08-28 21:12:25 +02:00
|
|
|
return this.startPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getStartLine(): number {
|
|
|
|
return this.getStartPosition().line;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getStartColumn(): number {
|
|
|
|
return this.getStartPosition().column;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getEndPosition(): TextPosition {
|
|
|
|
if (this.endPos === null) {
|
|
|
|
const endPos = this.getStartPosition().clone();
|
|
|
|
endPos.advance(this.text);
|
|
|
|
return this.endPos = endPos;
|
|
|
|
}
|
|
|
|
return this.endPos;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getEndLine(): number {
|
|
|
|
return this.getEndPosition().line;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getEndColumn(): number {
|
|
|
|
return this.getEndPosition().column;
|
|
|
|
}
|
|
|
|
|
|
|
|
public abstract readonly text: string;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
abstract class VirtualTokenBase extends TokenBase {
|
|
|
|
public get text(): string {
|
|
|
|
return '';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export class EndOfFile extends VirtualTokenBase {
|
2023-02-06 11:50:38 +01:00
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public readonly kind = SyntaxKind.EndOfFile;
|
2023-02-06 11:50:38 +01:00
|
|
|
|
|
|
|
public clone(): EndOfFile {
|
|
|
|
return new EndOfFile(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class BlockEnd extends VirtualTokenBase {
|
2023-02-06 11:50:38 +01:00
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public readonly kind = SyntaxKind.BlockEnd;
|
2023-02-06 11:50:38 +01:00
|
|
|
|
|
|
|
public clone(): BlockEnd {
|
|
|
|
return new BlockEnd(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class BlockStart extends VirtualTokenBase {
|
2023-02-06 11:50:38 +01:00
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public readonly kind = SyntaxKind.BlockStart;
|
2023-02-06 11:50:38 +01:00
|
|
|
|
|
|
|
public clone(): BlockStart {
|
|
|
|
return new BlockStart(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class LineFoldEnd extends VirtualTokenBase {
|
2023-02-06 11:50:38 +01:00
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public readonly kind = SyntaxKind.LineFoldEnd;
|
2023-02-06 11:50:38 +01:00
|
|
|
|
|
|
|
public clone(): LineFoldEnd {
|
|
|
|
return new LineFoldEnd(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Integer extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Integer;
|
|
|
|
|
|
|
|
public constructor(
|
2023-04-14 19:57:59 +02:00
|
|
|
startPos: TextPosition | null = null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public value: bigint,
|
|
|
|
public radix: number,
|
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 19:43:52 +02:00
|
|
|
public getValue(): Value {
|
|
|
|
return this.value;
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Integer {
|
|
|
|
return new Integer(
|
2023-04-14 19:57:59 +02:00
|
|
|
this.startPos,
|
2023-02-06 11:50:38 +01:00
|
|
|
this.value,
|
|
|
|
this.radix,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public get text(): string {
|
|
|
|
switch (this.radix) {
|
|
|
|
case 16:
|
|
|
|
return '0x' + this.value.toString(16);
|
|
|
|
case 10:
|
|
|
|
return this.value.toString(10)
|
|
|
|
case 8:
|
|
|
|
return '0o' + this.value.toString(8)
|
|
|
|
case 2:
|
|
|
|
return '0b' + this.value.toString(2);
|
|
|
|
default:
|
|
|
|
throw new Error(`Radix ${this.radix} of Integer not recognised.`)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class StringLiteral extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StringLiteral;
|
|
|
|
|
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
startPos: TextPosition | null = null,
|
2023-04-14 19:57:59 +02:00
|
|
|
public contents: string,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 19:43:52 +02:00
|
|
|
public getValue(): Value {
|
|
|
|
return this.contents;
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StringLiteral {
|
|
|
|
return new StringLiteral(
|
2023-04-14 19:57:59 +02:00
|
|
|
this.startPos,
|
2023-02-06 11:50:38 +01:00
|
|
|
this.contents,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public get text(): string {
|
|
|
|
let out = '"';
|
|
|
|
for (const ch of this.contents) {
|
|
|
|
const code = ch.charCodeAt(0);
|
|
|
|
if (code >= 32 && code <= 127) {
|
|
|
|
out += ch;
|
|
|
|
} else if (code <= 127) {
|
|
|
|
out += '\\x' + code.toString(16).padStart(2, '0');
|
|
|
|
} else {
|
2023-04-12 19:38:45 +02:00
|
|
|
out += '\\u' + code.toString(16).padStart(4, '0');
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
out += '"';
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:18:47 +02:00
|
|
|
export class IdentifierAlt extends TokenBase {
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:18:47 +02:00
|
|
|
public readonly kind = SyntaxKind.IdentifierAlt;
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
startPos: TextPosition | null = null,
|
2023-04-14 19:57:59 +02:00
|
|
|
public text: string,
|
2022-08-29 16:17:55 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): IdentifierAlt {
|
|
|
|
return new IdentifierAlt(
|
2023-04-14 19:57:59 +02:00
|
|
|
this.startPos,
|
2023-02-06 11:50:38 +01:00
|
|
|
this.text,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class Identifier extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Identifier;
|
|
|
|
|
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
startPos: TextPosition | null = null,
|
2023-04-14 19:57:59 +02:00
|
|
|
public text: string,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Identifier {
|
|
|
|
return new Identifier(
|
2023-04-14 19:57:59 +02:00
|
|
|
this.startPos,
|
2023-02-06 11:50:38 +01:00
|
|
|
this.text,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class CustomOperator extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.CustomOperator;
|
|
|
|
|
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
startPos: TextPosition | null = null,
|
2023-04-14 19:57:59 +02:00
|
|
|
public text: string,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): CustomOperator {
|
|
|
|
return new CustomOperator(
|
|
|
|
this.startPos,
|
2023-04-14 19:57:59 +02:00
|
|
|
this.text,
|
2023-02-06 11:50:38 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-18 14:33:22 +02:00
|
|
|
export type ExprOperator
|
|
|
|
= CustomOperator
|
|
|
|
| VBar
|
|
|
|
|
|
|
|
export function isExprOperator(node: Syntax): node is ExprOperator {
|
|
|
|
return node.kind === SyntaxKind.CustomOperator
|
|
|
|
|| node.kind === SyntaxKind.VBar
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class Assignment extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Assignment;
|
|
|
|
|
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
startPos: TextPosition | null = null,
|
2023-04-14 19:57:59 +02:00
|
|
|
public text: string,
|
2022-09-01 20:06:43 +02:00
|
|
|
) {
|
|
|
|
super(startPos);
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Assignment {
|
|
|
|
return new Assignment(
|
2023-04-14 19:57:59 +02:00
|
|
|
this.startPos,
|
2023-02-06 11:50:38 +01:00
|
|
|
this.text,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class LParen extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LParen;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '(';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): LParen {
|
|
|
|
return new LParen(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class RParen extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RParen;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ')';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): RParen {
|
|
|
|
return new RParen(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class LBrace extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LBrace;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '{';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): LBrace {
|
|
|
|
return new LBrace(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class RBrace extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RBrace;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '}';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): RBrace {
|
|
|
|
return new RBrace(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class LBracket extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LBracket;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '[';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): LBracket {
|
|
|
|
return new LBracket(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class RBracket extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RBracket;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ']';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): RBracket {
|
|
|
|
return new RBracket(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Dot extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Dot;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '.';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Dot {
|
|
|
|
return new Dot(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
export class At extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.At;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '@';
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): At {
|
|
|
|
return new At(this.startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class Comma extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Comma;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ',';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Comma {
|
|
|
|
return new Comma(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class DotDot extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.DotDot;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '..';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): DotDot {
|
|
|
|
return new DotDot(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Colon extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Colon;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return ':';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Colon {
|
|
|
|
return new Colon(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class Equals extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Equals;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '=';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Equals {
|
|
|
|
return new Equals(this.startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class Backslash extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Equals;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '\\';
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): Backslash {
|
|
|
|
return new Backslash(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class IfKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.IfKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'if';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): IfKeyword {
|
|
|
|
return new IfKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ElseKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ElseKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'else';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ElseKeyword {
|
|
|
|
return new ElseKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ElifKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ElifKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'elif';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ElifKeyword {
|
|
|
|
return new ElifKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class StructKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'struct';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructKeyword {
|
|
|
|
return new StructKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
export class EnumKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'enum';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): EnumKeyword {
|
|
|
|
return new EnumKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
export class ReturnKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReturnKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'return';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ReturnKeyword {
|
|
|
|
return new ReturnKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class MatchKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MatchKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'match';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): MatchKeyword {
|
|
|
|
return new MatchKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-09-16 19:50:18 +02:00
|
|
|
export class ForeignKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ForeignKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'foreign';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ForeignKeyword {
|
|
|
|
return new ForeignKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 19:50:18 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ModKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ModKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'mod';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ModKeyword {
|
|
|
|
return new ModKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class MutKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MutKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'mut';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): MutKeyword {
|
|
|
|
return new MutKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ImportKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ImportKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'import'
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ImportKeyword {
|
|
|
|
return new ImportKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
export class ClassKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ClassKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'trait';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ClassKeyword {
|
|
|
|
return new ClassKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export class InstanceKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.InstanceKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'impl';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): InstanceKeyword {
|
|
|
|
return new InstanceKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class TypeKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'type';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): TypeKeyword {
|
|
|
|
return new TypeKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class PubKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PubKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'pub';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): PubKeyword {
|
|
|
|
return new PubKeyword();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class LetKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LetKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'let';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): LetKeyword {
|
|
|
|
return new LetKeyword();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
export class RArrow extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RArrow;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '->';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): RArrow {
|
|
|
|
return new RArrow(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
export class RArrowAlt extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.RArrowAlt;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '=>';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): RArrowAlt {
|
|
|
|
return new RArrowAlt(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class VBar extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.VBar;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return '|';
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): VBar {
|
|
|
|
return new VBar(this.startPos);
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
}
|
|
|
|
|
2023-06-21 16:56:04 +02:00
|
|
|
export class ForallKeyword extends TokenBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ForallKeyword;
|
|
|
|
|
|
|
|
public get text(): string {
|
|
|
|
return 'forall';
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): ForallKeyword {
|
|
|
|
return new ForallKeyword(this.startPos);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type Token
|
2022-09-09 22:37:14 +02:00
|
|
|
= RArrow
|
2022-09-16 11:31:34 +02:00
|
|
|
| RArrowAlt
|
|
|
|
| VBar
|
2022-09-09 22:37:14 +02:00
|
|
|
| LParen
|
2022-08-28 21:12:25 +02:00
|
|
|
| RParen
|
|
|
|
| LBrace
|
|
|
|
| RBrace
|
|
|
|
| LBracket
|
|
|
|
| RBracket
|
|
|
|
| Identifier
|
2022-09-01 20:18:47 +02:00
|
|
|
| IdentifierAlt
|
2022-08-28 21:12:25 +02:00
|
|
|
| CustomOperator
|
|
|
|
| Integer
|
|
|
|
| StringLiteral
|
2023-06-30 19:30:42 +02:00
|
|
|
| At
|
2022-08-28 21:12:25 +02:00
|
|
|
| Comma
|
|
|
|
| Dot
|
|
|
|
| DotDot
|
|
|
|
| Colon
|
|
|
|
| Equals
|
2023-02-06 11:50:38 +01:00
|
|
|
| Backslash
|
2022-08-28 21:12:25 +02:00
|
|
|
| LetKeyword
|
|
|
|
| PubKeyword
|
|
|
|
| MutKeyword
|
|
|
|
| ModKeyword
|
|
|
|
| ImportKeyword
|
2023-02-03 17:51:27 +01:00
|
|
|
| ClassKeyword
|
|
|
|
| InstanceKeyword
|
2022-08-28 21:12:25 +02:00
|
|
|
| TypeKeyword
|
|
|
|
| StructKeyword
|
2022-08-29 16:17:55 +02:00
|
|
|
| ReturnKeyword
|
|
|
|
| MatchKeyword
|
2022-08-28 21:12:25 +02:00
|
|
|
| EndOfFile
|
|
|
|
| BlockStart
|
|
|
|
| BlockEnd
|
|
|
|
| LineFoldEnd
|
2022-09-01 20:06:43 +02:00
|
|
|
| Assignment
|
|
|
|
| IfKeyword
|
|
|
|
| ElseKeyword
|
|
|
|
| ElifKeyword
|
2022-09-10 14:11:04 +02:00
|
|
|
| EnumKeyword
|
2022-09-16 19:50:18 +02:00
|
|
|
| ForeignKeyword
|
2023-06-21 16:56:04 +02:00
|
|
|
| ForallKeyword
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export type TokenKind
|
|
|
|
= Token['kind']
|
|
|
|
|
2023-06-21 16:56:04 +02:00
|
|
|
export class ForallTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ForallTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public forallKeyword: ForallKeyword,
|
|
|
|
public varTypeExps: VarTypeExpression[],
|
|
|
|
public dot: Dot,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): ForallTypeExpression {
|
|
|
|
return new ForallTypeExpression(
|
|
|
|
this.forallKeyword.clone(),
|
|
|
|
this.varTypeExps.map(e => e.clone()),
|
|
|
|
this.dot.clone(),
|
|
|
|
this.typeExpr.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.forallKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class TypeExpressionWithConstraints extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeExpressionWithConstraints;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public constraints: ClassConstraint[],
|
|
|
|
public rarrowAlt: RArrowAlt,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): TypeExpressionWithConstraints {
|
|
|
|
return new TypeExpressionWithConstraints(
|
|
|
|
this.constraints.map(c => c.clone()),
|
|
|
|
this.rarrowAlt.clone(),
|
|
|
|
this.typeExpr.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.constraints.length > 0) {
|
|
|
|
return this.constraints[0].getFirstToken();
|
|
|
|
}
|
|
|
|
return this.rarrowAlt;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
export class ArrowTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ArrowTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public paramTypeExprs: TypeExpression[],
|
|
|
|
public returnTypeExpr: TypeExpression
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ArrowTypeExpression {
|
|
|
|
return new ArrowTypeExpression(
|
|
|
|
this.paramTypeExprs.map(te => te.clone()),
|
|
|
|
this.returnTypeExpr.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.paramTypeExprs.length > 0) {
|
|
|
|
return this.paramTypeExprs[0].getFirstToken();
|
|
|
|
}
|
|
|
|
return this.returnTypeExpr.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.returnTypeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-16 12:43:06 +02:00
|
|
|
export class TupleTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TupleTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public elements: TypeExpression[],
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): TupleTypeExpression {
|
|
|
|
return new TupleTypeExpression(
|
|
|
|
this.lparen.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
this.rparen.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-16 12:43:06 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ReferenceTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReferenceTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-17 16:31:05 +02:00
|
|
|
public modulePath: Array<[IdentifierAlt, Dot]>,
|
2022-09-01 20:18:47 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ReferenceTypeExpression {
|
|
|
|
return new ReferenceTypeExpression(
|
|
|
|
this.modulePath.map(([name, dot]) => [name.clone(), dot.clone()]),
|
|
|
|
this.name.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.modulePath.length > 0) {
|
|
|
|
return this.modulePath[0][0];
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
export class AppTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.AppTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public operator: TypeExpression,
|
|
|
|
public args: TypeExpression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): AppTypeExpression {
|
|
|
|
return new AppTypeExpression(
|
|
|
|
this.operator.clone(),
|
|
|
|
this.args.map(arg => arg.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.operator.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.args.length > 0) {
|
|
|
|
return this.args[this.args.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.operator.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-10 16:52:14 +02:00
|
|
|
export class VarTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.VarTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): VarTypeExpression {
|
|
|
|
return new VarTypeExpression( this.name.clone() );
|
|
|
|
}
|
|
|
|
|
2022-09-10 16:52:14 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-14 16:46:30 +02:00
|
|
|
export class NestedTypeExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NestedTypeExpression;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): NestedTypeExpression {
|
|
|
|
return new NestedTypeExpression(
|
|
|
|
this.lparen.clone(),
|
|
|
|
this.typeExpr.clone(),
|
|
|
|
this.rparen.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-14 16:46:30 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type TypeExpression
|
|
|
|
= ReferenceTypeExpression
|
2022-09-09 22:37:14 +02:00
|
|
|
| ArrowTypeExpression
|
2022-09-10 16:52:14 +02:00
|
|
|
| VarTypeExpression
|
2022-09-11 11:20:21 +02:00
|
|
|
| AppTypeExpression
|
2022-09-14 16:46:30 +02:00
|
|
|
| NestedTypeExpression
|
2022-09-16 12:43:06 +02:00
|
|
|
| TupleTypeExpression
|
2023-06-21 16:56:04 +02:00
|
|
|
| ForallTypeExpression
|
|
|
|
| TypeExpressionWithConstraints
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2023-03-11 14:24:02 +01:00
|
|
|
export class NamedPattern extends SyntaxBase {
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2023-03-11 14:24:02 +01:00
|
|
|
public readonly kind = SyntaxKind.NamedPattern;
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
public constructor(
|
2023-04-12 21:16:48 +02:00
|
|
|
public name: Identifier | CustomOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-03-11 14:24:02 +01:00
|
|
|
public clone(): NamedPattern {
|
|
|
|
return new NamedPattern( this.name.clone() );
|
2023-02-06 11:50:38 +01:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public get isHole(): boolean {
|
|
|
|
return this.name.text == '_';
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class TuplePattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TuplePattern;
|
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public lparen: LParen,
|
2022-08-28 21:12:25 +02:00
|
|
|
public elements: Pattern[],
|
2022-08-29 16:17:55 +02:00
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): TuplePattern {
|
|
|
|
return new TuplePattern(
|
|
|
|
this.lparen.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
this.rparen.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class NamedTuplePattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NamedTuplePattern;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-01 20:18:47 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-08-29 16:17:55 +02:00
|
|
|
public elements: Pattern[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): NamedTuplePattern {
|
|
|
|
return new NamedTuplePattern(
|
|
|
|
this.name.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class StructPatternField extends SyntaxBase {
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public readonly kind = SyntaxKind.StructPatternField;
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
public equals: Equals,
|
|
|
|
public pattern: Pattern,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructPatternField {
|
|
|
|
return new StructPatternField(
|
|
|
|
this.name.clone(),
|
|
|
|
this.equals.clone(),
|
|
|
|
this.pattern.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class VariadicStructPatternElement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.VariadicStructPatternElement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public dotdot: DotDot,
|
|
|
|
public pattern: Pattern | null,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): VariadicStructPatternElement {
|
|
|
|
return new VariadicStructPatternElement(
|
|
|
|
this.dotdot.clone(),
|
|
|
|
this.pattern !== null ? this.pattern.clone() : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.dotdot;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.pattern !== null) {
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
return this.dotdot;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class PunnedStructPatternField extends SyntaxBase {
|
2022-08-29 16:17:55 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public readonly kind = SyntaxKind.PunnedStructPatternField;
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): PunnedStructPatternField {
|
|
|
|
return new PunnedStructPatternField( this.name.clone() );
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type StructPatternElement
|
|
|
|
= VariadicStructPatternElement
|
2022-09-01 20:06:43 +02:00
|
|
|
| PunnedStructPatternField
|
|
|
|
| StructPatternField
|
2022-08-29 16:17:55 +02:00
|
|
|
|
|
|
|
export class StructPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructPattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lbrace: LBrace,
|
2022-09-07 12:45:38 +02:00
|
|
|
public members: StructPatternElement[],
|
2022-08-29 16:17:55 +02:00
|
|
|
public rbrace: RBrace,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructPattern {
|
|
|
|
return new StructPattern(
|
|
|
|
this.lbrace.clone(),
|
|
|
|
this.members.map(member => member.clone()),
|
|
|
|
this.rbrace.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
2023-03-11 14:24:02 +01:00
|
|
|
return this.lbrace;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rbrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class NestedPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NestedPattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public pattern: Pattern,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): NestedPattern {
|
|
|
|
return new NestedPattern(
|
|
|
|
this.lparen.clone(),
|
|
|
|
this.pattern.clone(),
|
|
|
|
this.rparen.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
export class DisjunctivePattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.DisjunctivePattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public left: Pattern,
|
|
|
|
public operator: VBar,
|
|
|
|
public right: Pattern,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): DisjunctivePattern {
|
|
|
|
return new DisjunctivePattern(
|
|
|
|
this.left.clone(),
|
|
|
|
this.operator.clone(),
|
|
|
|
this.right.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.left.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.right.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
export class LiteralPattern extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LiteralPattern;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public token: StringLiteral | Integer
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): LiteralPattern {
|
|
|
|
return new LiteralPattern( this.token.clone() );
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type Pattern
|
2023-03-11 14:24:02 +01:00
|
|
|
= NamedPattern
|
2022-08-29 16:17:55 +02:00
|
|
|
| NestedPattern
|
|
|
|
| StructPattern
|
|
|
|
| NamedTuplePattern
|
2022-08-28 21:12:25 +02:00
|
|
|
| TuplePattern
|
2022-09-16 11:31:34 +02:00
|
|
|
| DisjunctivePattern
|
|
|
|
| LiteralPattern
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
export class TypeAnnotation extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeAnnotation;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public at: At,
|
|
|
|
public colon: Colon,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): TypeAnnotation {
|
|
|
|
return new TypeAnnotation(
|
|
|
|
this.at.clone(),
|
|
|
|
this.colon.clone(),
|
|
|
|
this.typeExpr.clone()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.at;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type Annotation
|
|
|
|
= TypeAnnotation
|
|
|
|
|
|
|
|
export type Annotations = Annotation[];
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class TupleExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TupleExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-08-28 21:12:25 +02:00
|
|
|
public lparen: LParen,
|
|
|
|
public elements: Expression[],
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): TupleExpression {
|
|
|
|
return new TupleExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.lparen.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
this.rparen.clone()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class NestedExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.NestedExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-08-28 21:12:25 +02:00
|
|
|
public lparen: LParen,
|
|
|
|
public expression: Expression,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): NestedExpression {
|
|
|
|
return new NestedExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.lparen.clone(),
|
|
|
|
this.expression.clone(),
|
|
|
|
this.rparen.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ConstantExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ConstantExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-08-28 21:12:25 +02:00
|
|
|
public token: Integer | StringLiteral,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ConstantExpression {
|
2023-06-30 19:30:42 +02:00
|
|
|
return new ConstantExpression(
|
|
|
|
this.annotations.map(a => a.clone()),
|
|
|
|
this.token.clone()
|
|
|
|
);
|
2023-02-06 11:50:38 +01:00
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.token;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
export class CallExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.CallExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-08-31 13:29:56 +02:00
|
|
|
public func: Expression,
|
|
|
|
public args: Expression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): CallExpression {
|
|
|
|
return new CallExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.func.clone(),
|
|
|
|
this.args.map(arg => arg.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.func.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.args.length > 0) {
|
|
|
|
return this.args[this.args.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.func.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class StructExpressionField extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructExpressionField;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
public equals: Equals,
|
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructExpressionField {
|
|
|
|
return new StructExpressionField(
|
|
|
|
this.name.clone(),
|
|
|
|
this.equals.clone(),
|
|
|
|
this.expression.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class PunnedStructExpressionField extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PunnedStructExpressionField;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): PunnedStructExpressionField {
|
|
|
|
return new PunnedStructExpressionField( this.name.clone() );
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type StructExpressionElement
|
|
|
|
= StructExpressionField
|
|
|
|
| PunnedStructExpressionField;
|
|
|
|
|
|
|
|
export class StructExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-09-01 20:06:43 +02:00
|
|
|
public lbrace: LBrace,
|
2022-09-07 12:45:38 +02:00
|
|
|
public members: StructExpressionElement[],
|
2022-09-01 20:06:43 +02:00
|
|
|
public rbrace: RBrace,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructExpression {
|
|
|
|
return new StructExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.lbrace.clone(),
|
|
|
|
this.members.map(member => member.clone()),
|
|
|
|
this.rbrace.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getFirstToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
return this.lbrace;
|
2022-09-01 20:06:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rbrace;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
export class FunctionExpression extends SyntaxBase {
|
2022-09-16 11:31:34 +02:00
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
public readonly kind = SyntaxKind.FunctionExpression;
|
2022-09-16 11:31:34 +02:00
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
|
|
|
public backslash: Backslash,
|
|
|
|
public params: Param[],
|
|
|
|
public body: Body,
|
2022-09-16 11:31:34 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
public clone(): FunctionExpression {
|
|
|
|
return new FunctionExpression(
|
|
|
|
this.annotations.map(a => a.clone()),
|
|
|
|
this.backslash.clone(),
|
|
|
|
this.params.map(param => param.clone()),
|
|
|
|
this.body.clone(),
|
2023-02-06 11:50:38 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
public getFirstToken(): Token {
|
2023-06-30 19:30:42 +02:00
|
|
|
return this.backslash;
|
2022-09-16 11:31:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2023-06-30 19:30:42 +02:00
|
|
|
return this.body.getLastToken();
|
2022-09-16 11:31:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
export class MatchArm extends SyntaxBase {
|
2023-02-06 11:50:38 +01:00
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
public readonly kind = SyntaxKind.MatchArm;
|
2023-02-06 11:50:38 +01:00
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public pattern: Pattern,
|
|
|
|
public rarrowAlt: RArrowAlt,
|
|
|
|
public expression: Expression,
|
2023-02-06 11:50:38 +01:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
public clone(): MatchArm {
|
|
|
|
return new MatchArm(
|
|
|
|
this.pattern.clone(),
|
|
|
|
this.rarrowAlt.clone(),
|
|
|
|
this.expression.clone(),
|
2023-02-06 11:50:38 +01:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
2023-06-30 19:30:42 +02:00
|
|
|
return this.pattern.getFirstToken();
|
2023-02-06 11:50:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2023-06-30 19:30:42 +02:00
|
|
|
return this.expression.getLastToken();
|
2023-02-06 11:50:38 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
export class MatchExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MatchExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-09-16 11:31:34 +02:00
|
|
|
public matchKeyword: MatchKeyword,
|
|
|
|
public expression: Expression | null,
|
|
|
|
public arms: MatchArm[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): MatchExpression {
|
|
|
|
return new MatchExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.matchKeyword.clone(),
|
|
|
|
this.expression !== null ? this.expression.clone() : null,
|
|
|
|
this.arms.map(arm => arm.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-16 11:31:34 +02:00
|
|
|
public getFirstToken(): Token {
|
2023-06-30 19:30:42 +02:00
|
|
|
if (this.annotations.length > 0) {
|
|
|
|
return this.annotations[0].getFirstToken();
|
|
|
|
}
|
2022-09-16 11:31:34 +02:00
|
|
|
return this.matchKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.arms.length > 0) {
|
|
|
|
return this.arms[this.arms.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
if (this.expression !== null) {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
return this.matchKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ReferenceExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReferenceExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-09-15 20:33:34 +02:00
|
|
|
public modulePath: Array<[IdentifierAlt, Dot]>,
|
|
|
|
public name: Identifier | IdentifierAlt,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ReferenceExpression {
|
|
|
|
return new ReferenceExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.modulePath.map(([name, dot]) => [name.clone(), dot.clone()]),
|
|
|
|
this.name.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
if (this.modulePath.length > 0) {
|
|
|
|
return this.modulePath[0][0];
|
|
|
|
}
|
|
|
|
return this.name;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
return this.name;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-09 00:00:28 +02:00
|
|
|
export class MemberExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.MemberExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-09-09 00:00:28 +02:00
|
|
|
public expression: Expression,
|
2023-06-30 19:30:42 +02:00
|
|
|
public path: [Dot, Identifier | Integer][],
|
2022-09-09 00:00:28 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): MemberExpression {
|
|
|
|
return new MemberExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.expression.clone(),
|
|
|
|
this.path.map(([dot, name]) => [dot.clone(), name.clone()]),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-09 00:00:28 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.expression.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.path[this.path.length-1][1];
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class PrefixExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PrefixExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-09-18 14:33:22 +02:00
|
|
|
public operator: ExprOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): PrefixExpression {
|
|
|
|
return new PrefixExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.operator.clone(),
|
|
|
|
this.expression.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.operator;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class PostfixExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.PostfixExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-08-28 21:12:25 +02:00
|
|
|
public expression: Expression,
|
2022-09-18 14:33:22 +02:00
|
|
|
public operator: ExprOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): PostfixExpression {
|
|
|
|
return new PostfixExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.expression.clone(),
|
|
|
|
this.operator.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.expression.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.operator;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class InfixExpression extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.InfixExpression;
|
|
|
|
|
|
|
|
public constructor(
|
2023-06-30 19:30:42 +02:00
|
|
|
public annotations: Annotations,
|
2022-08-28 21:12:25 +02:00
|
|
|
public left: Expression,
|
2022-09-18 14:33:22 +02:00
|
|
|
public operator: ExprOperator,
|
2022-08-28 21:12:25 +02:00
|
|
|
public right: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): InfixExpression {
|
|
|
|
return new InfixExpression(
|
2023-06-30 19:30:42 +02:00
|
|
|
this.annotations.map(a => a.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.left.clone(),
|
|
|
|
this.operator.clone(),
|
|
|
|
this.right.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.left.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.right.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
export function isExpression(node: Syntax): node is Expression {
|
|
|
|
switch (node.kind) {
|
|
|
|
case SyntaxKind.MemberExpression:
|
|
|
|
case SyntaxKind.CallExpression:
|
|
|
|
case SyntaxKind.StructExpression:
|
|
|
|
case SyntaxKind.ReferenceExpression:
|
|
|
|
case SyntaxKind.ConstantExpression:
|
|
|
|
case SyntaxKind.TupleExpression:
|
|
|
|
case SyntaxKind.MatchExpression:
|
|
|
|
case SyntaxKind.NestedExpression:
|
|
|
|
case SyntaxKind.PrefixExpression:
|
|
|
|
case SyntaxKind.InfixExpression:
|
|
|
|
case SyntaxKind.PostfixExpression:
|
|
|
|
case SyntaxKind.FunctionExpression:
|
|
|
|
return true;
|
|
|
|
default:
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export type Expression
|
2022-09-09 00:00:28 +02:00
|
|
|
= MemberExpression
|
|
|
|
| CallExpression
|
2022-09-01 20:06:43 +02:00
|
|
|
| StructExpression
|
2022-08-31 13:29:56 +02:00
|
|
|
| ReferenceExpression
|
2022-08-28 21:12:25 +02:00
|
|
|
| ConstantExpression
|
|
|
|
| TupleExpression
|
2022-09-16 11:31:34 +02:00
|
|
|
| MatchExpression
|
2022-08-28 21:12:25 +02:00
|
|
|
| NestedExpression
|
|
|
|
| PrefixExpression
|
|
|
|
| InfixExpression
|
|
|
|
| PostfixExpression
|
2023-02-06 11:50:38 +01:00
|
|
|
| FunctionExpression
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
export class IfStatementCase extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.IfStatementCase;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public keyword: IfKeyword | ElseKeyword | ElifKeyword,
|
|
|
|
public test: Expression | null,
|
|
|
|
public blockStart: BlockStart,
|
|
|
|
public elements: LetBodyElement[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): IfStatementCase {
|
|
|
|
return new IfStatementCase(
|
|
|
|
this.keyword.clone(),
|
|
|
|
this.test !== null ? this.test.clone() : null,
|
|
|
|
this.blockStart.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.keyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class IfStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.IfStatement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public cases: IfStatementCase[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): IfStatement {
|
|
|
|
return new IfStatement(
|
|
|
|
this.cases.map(caze => caze.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-01 20:06:43 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.cases[0].getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.cases[this.cases.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ReturnStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ReturnStatement;
|
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public returnKeyword: ReturnKeyword,
|
2022-08-31 13:54:22 +02:00
|
|
|
public expression: Expression | null
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ReturnStatement {
|
|
|
|
return new ReturnStatement(
|
|
|
|
this.returnKeyword.clone(),
|
|
|
|
this.expression !== null ? this.expression.clone() : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.returnKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.expression !== null) {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
return this.returnKeyword;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2023-03-19 17:02:59 +01:00
|
|
|
export class AssignStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.AssignStatement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pattern: Pattern,
|
|
|
|
public operator: Assignment,
|
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
|
|
|
public clone(): AssignStatement {
|
|
|
|
return new AssignStatement(
|
|
|
|
this.pattern.clone(),
|
|
|
|
this.operator.clone(),
|
|
|
|
this.expression.clone()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.pattern.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class ExpressionStatement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ExpressionStatement;
|
|
|
|
|
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public expression: Expression,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ExpressionStatement {
|
|
|
|
return new ExpressionStatement( this.expression.clone() );
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.expression.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Statement
|
|
|
|
= ReturnStatement
|
|
|
|
| ExpressionStatement
|
2022-09-01 20:06:43 +02:00
|
|
|
| IfStatement
|
2023-03-19 17:02:59 +01:00
|
|
|
| AssignStatement
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export class Param extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Param;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pattern: Pattern,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Param {
|
|
|
|
return new Param(
|
|
|
|
this.pattern.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.pattern.getFirstToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
export class EnumDeclarationStructElement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumDeclarationStructElement;
|
|
|
|
|
2022-09-15 16:56:02 +02:00
|
|
|
public scheme?: Scheme;
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
public constructor(
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public blockStart: BlockStart,
|
2022-09-15 20:33:34 +02:00
|
|
|
public fields: StructDeclarationField[],
|
2022-09-10 14:11:04 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): EnumDeclarationStructElement {
|
|
|
|
return new EnumDeclarationStructElement(
|
|
|
|
this.name.clone(),
|
|
|
|
this.blockStart.clone(),
|
|
|
|
this.fields.map(field => field.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
if (this.fields.length > 0) {
|
|
|
|
return this.fields[this.fields.length-1].getLastToken();
|
2022-09-10 14:11:04 +02:00
|
|
|
}
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class EnumDeclarationTupleElement extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumDeclarationTupleElement;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public elements: TypeExpression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): EnumDeclarationElement {
|
|
|
|
return new EnumDeclarationTupleElement(
|
|
|
|
this.name.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type EnumDeclarationElement
|
|
|
|
= EnumDeclarationStructElement
|
|
|
|
| EnumDeclarationTupleElement
|
|
|
|
|
|
|
|
export class EnumDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.EnumDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public enumKeyword: EnumKeyword,
|
|
|
|
public name: IdentifierAlt,
|
2022-09-14 16:46:30 +02:00
|
|
|
public varExps: Identifier[],
|
2022-09-10 14:11:04 +02:00
|
|
|
public members: EnumDeclarationElement[] | null,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): EnumDeclaration {
|
|
|
|
return new EnumDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.enumKeyword.clone(),
|
|
|
|
this.name.clone(),
|
|
|
|
this.varExps.map(ve => ve.clone()),
|
|
|
|
this.members !== null ? this.members.map(member => member.clone()) : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-10 14:11:04 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.enumKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.members !== null && this.members.length > 0) {
|
|
|
|
return this.members[this.members.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class StructDeclarationField extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructDeclarationField;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: Identifier,
|
|
|
|
public colon: Colon,
|
|
|
|
public typeExpr: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructDeclarationField {
|
|
|
|
return new StructDeclarationField(
|
|
|
|
this.name.clone(),
|
|
|
|
this.colon.clone(),
|
|
|
|
this.typeExpr.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpr.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class StructDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.StructDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
2022-09-10 14:11:04 +02:00
|
|
|
public pubKeyword: PubKeyword | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public structKeyword: StructKeyword,
|
2022-09-07 12:45:38 +02:00
|
|
|
public name: IdentifierAlt,
|
2022-09-15 11:49:53 +02:00
|
|
|
public varExps: Identifier[],
|
2022-09-15 20:33:34 +02:00
|
|
|
public fields: StructDeclarationField[] | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): StructDeclaration {
|
|
|
|
return new StructDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.structKeyword.clone(),
|
|
|
|
this.name.clone(),
|
|
|
|
this.varExps.map(ve => ve.clone()),
|
|
|
|
this.fields !== null ? this.fields.map(field => field.clone()) : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
2022-09-10 14:11:04 +02:00
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
2022-08-29 16:17:55 +02:00
|
|
|
return this.structKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-15 20:33:34 +02:00
|
|
|
if (this.fields && this.fields.length > 0) {
|
|
|
|
return this.fields[this.fields.length-1].getLastToken();
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class TypeAssert extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeAssert;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public colon: Colon,
|
|
|
|
public typeExpression: TypeExpression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): TypeAssert {
|
|
|
|
return new TypeAssert(
|
|
|
|
this.colon.clone(),
|
|
|
|
this.typeExpression.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.colon;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Body
|
|
|
|
= ExprBody
|
|
|
|
| BlockBody
|
|
|
|
|
|
|
|
export class ExprBody extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ExprBody;
|
|
|
|
|
|
|
|
public constructor(
|
2023-02-06 11:50:38 +01:00
|
|
|
public equals: Equals | RArrow,
|
2022-08-28 21:12:25 +02:00
|
|
|
public expression: Expression,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ExprBody {
|
|
|
|
return new ExprBody(
|
|
|
|
this.equals.clone(),
|
|
|
|
this.expression.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.equals;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type LetBodyElement
|
|
|
|
= LetDeclaration
|
|
|
|
| Statement
|
|
|
|
|
|
|
|
export class BlockBody extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.BlockBody;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public blockStart: BlockStart,
|
|
|
|
public elements: LetBodyElement[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): BlockBody {
|
|
|
|
return new BlockBody(
|
|
|
|
this.blockStart.clone(),
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.blockStart;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
2022-09-09 22:37:14 +02:00
|
|
|
|
|
|
|
export class WrappedOperator extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.WrappedOperator;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public lparen: LParen,
|
|
|
|
public operator: CustomOperator,
|
|
|
|
public rparen: RParen,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): WrappedOperator {
|
|
|
|
return new WrappedOperator(
|
|
|
|
this.lparen.clone(),
|
|
|
|
this.operator.clone(),
|
|
|
|
this.rparen.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-09 22:37:14 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.lparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rparen;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
export class TypeDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.TypeDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public typeKeyword: TypeKeyword,
|
|
|
|
public name: IdentifierAlt,
|
2022-09-15 11:49:53 +02:00
|
|
|
public varExps: Identifier[],
|
2022-09-11 11:20:21 +02:00
|
|
|
public equals: Equals,
|
|
|
|
public typeExpression: TypeExpression
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): TypeDeclaration {
|
|
|
|
return new TypeDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.typeKeyword.clone(),
|
|
|
|
this.name.clone(),
|
|
|
|
this.varExps.map(ve => ve.clone()),
|
|
|
|
this.equals.clone(),
|
|
|
|
this.typeExpression.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-09-11 11:20:21 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.typeKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.typeExpression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
export class LetDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.LetDeclaration;
|
|
|
|
|
2023-04-14 19:57:59 +02:00
|
|
|
@nonenumerable
|
2022-09-01 20:06:43 +02:00
|
|
|
public scope?: Scope;
|
2023-04-14 19:57:59 +02:00
|
|
|
|
|
|
|
@nonenumerable
|
2022-09-18 14:33:22 +02:00
|
|
|
public activeCycle?: boolean;
|
2023-06-22 15:30:14 +02:00
|
|
|
@nonenumerable
|
|
|
|
public visited?: boolean;
|
2023-04-14 19:57:59 +02:00
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public letKeyword: LetKeyword,
|
2022-09-16 19:50:18 +02:00
|
|
|
public foreignKeyword: ForeignKeyword | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public mutKeyword: MutKeyword | null,
|
2023-04-12 21:16:48 +02:00
|
|
|
public pattern: Pattern,
|
2022-08-28 21:12:25 +02:00
|
|
|
public params: Param[],
|
|
|
|
public typeAssert: TypeAssert | null,
|
|
|
|
public body: Body | null,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-04-12 21:16:48 +02:00
|
|
|
public get name(): Identifier | CustomOperator {
|
|
|
|
switch (this.pattern.kind) {
|
|
|
|
case SyntaxKind.NamedPattern:
|
|
|
|
return this.pattern.name;
|
|
|
|
case SyntaxKind.NestedPattern:
|
|
|
|
assert(this.pattern.pattern.kind === SyntaxKind.NamedPattern);
|
|
|
|
return this.pattern.pattern.name;
|
|
|
|
default:
|
|
|
|
unreachable();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): LetDeclaration {
|
|
|
|
return new LetDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.letKeyword.clone(),
|
|
|
|
this.foreignKeyword !== null ? this.foreignKeyword.clone() : null,
|
|
|
|
this.mutKeyword !== null ? this.mutKeyword.clone() : null,
|
|
|
|
this.pattern.clone(),
|
|
|
|
this.params.map(param => param.clone()),
|
|
|
|
this.typeAssert !== null ? this.typeAssert.clone() : null,
|
|
|
|
this.body !== null ? this.body.clone() : null,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.letKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.body !== null) {
|
|
|
|
return this.body.getLastToken();
|
|
|
|
}
|
|
|
|
if (this.typeAssert !== null) {
|
|
|
|
return this.typeAssert.getLastToken();
|
|
|
|
}
|
|
|
|
if (this.params.length > 0) {
|
|
|
|
return this.params[this.params.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.pattern.getLastToken();
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export class ImportDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ImportDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public importKeyword: ImportKeyword,
|
|
|
|
public importSource: StringLiteral,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ImportDeclaration {
|
|
|
|
return new ImportDeclaration(
|
|
|
|
this.importKeyword.clone(),
|
|
|
|
this.importSource.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.importKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.importSource;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type Declaration
|
|
|
|
= LetDeclaration
|
|
|
|
| ImportDeclaration
|
|
|
|
| StructDeclaration
|
2022-09-10 14:11:04 +02:00
|
|
|
| EnumDeclaration
|
2022-09-11 11:20:21 +02:00
|
|
|
| TypeDeclaration
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
export class Initializer extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.Initializer;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public equals: Equals,
|
|
|
|
public expression: Expression
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): Initializer {
|
|
|
|
return new Initializer(
|
|
|
|
this.equals.clone(),
|
|
|
|
this.expression.clone()
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.equals;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.expression.getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
export class ClassConstraint extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ClassConstraint;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public types: TypeExpression[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ClassConstraint {
|
|
|
|
return new ClassConstraint(
|
|
|
|
this.name.clone(),
|
|
|
|
this.types.map(ty => ty.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
return this.name;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.types[this.types.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export class ClassConstraintClause extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ClassConstraintClause;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public constraints: ClassConstraint[],
|
|
|
|
public rarrowAlt: RArrowAlt,
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ClassConstraintClause {
|
|
|
|
return new ClassConstraintClause(
|
|
|
|
this.constraints.map(constraint => constraint.clone()),
|
|
|
|
this.rarrowAlt.clone(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.constraints.length > 0) {
|
|
|
|
return this.constraints[0].getFirstToken();
|
|
|
|
}
|
|
|
|
return this.rarrowAlt;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
return this.rarrowAlt;
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type ClassDeclarationElement
|
|
|
|
= LetDeclaration
|
|
|
|
| TypeDeclaration
|
|
|
|
|
|
|
|
export class ClassDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.ClassDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public classKeyword: ClassKeyword,
|
2023-03-16 21:50:15 +01:00
|
|
|
public constraintClause: ClassConstraintClause | null,
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public types: VarTypeExpression[],
|
2023-02-03 17:51:27 +01:00
|
|
|
public elements: ClassDeclarationElement[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-03-16 21:50:15 +01:00
|
|
|
public *getSupers(): Iterable<IdentifierAlt> {
|
|
|
|
if (this.constraintClause !== null) {
|
|
|
|
for (const constraint of this.constraintClause.constraints) {
|
|
|
|
yield constraint.name;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
public lookup(element: InstanceDeclarationElement): ClassDeclarationElement | null {
|
|
|
|
|
|
|
|
switch (element.kind) {
|
|
|
|
|
|
|
|
case SyntaxKind.LetDeclaration:
|
2023-03-16 21:50:15 +01:00
|
|
|
implementationLimitation(element.pattern.kind === SyntaxKind.NamedPattern);
|
2023-02-03 17:51:27 +01:00
|
|
|
for (const other of this.elements) {
|
|
|
|
if (other.kind === SyntaxKind.LetDeclaration
|
2023-03-11 14:24:02 +01:00
|
|
|
&& other.pattern.kind === SyntaxKind.NamedPattern
|
2023-02-03 17:51:27 +01:00
|
|
|
&& other.pattern.name.text === element.pattern.name.text) {
|
|
|
|
return other;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
case SyntaxKind.TypeDeclaration:
|
|
|
|
for (const other of this.elements) {
|
|
|
|
if (other.kind === SyntaxKind.TypeDeclaration
|
|
|
|
&& other.name.text === element.name.text) {
|
|
|
|
return other;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2023-03-11 14:24:02 +01:00
|
|
|
public *getInstances(): Iterable<InstanceDeclaration> {
|
|
|
|
let curr = this.parent!;
|
|
|
|
for (;;) {
|
|
|
|
if (!canHaveInstanceDeclaration(curr)) {
|
|
|
|
curr = curr.parent!;
|
|
|
|
}
|
|
|
|
for (const element of getElements(curr)) {
|
2023-03-16 21:50:15 +01:00
|
|
|
if (element.kind === SyntaxKind.InstanceDeclaration && element.name.text === this.name.text) {
|
2023-03-11 14:24:02 +01:00
|
|
|
yield element;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ClassDeclaration {
|
|
|
|
return new ClassDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.classKeyword.clone(),
|
2023-03-16 21:50:15 +01:00
|
|
|
this.constraintClause !== null ? this.constraintClause.clone() : null,
|
|
|
|
this.name.clone(),
|
|
|
|
this.types.map(t => t.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.classKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
2023-03-16 21:50:15 +01:00
|
|
|
if (this.types.length > 0) {
|
|
|
|
return this.types[this.types.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
2023-02-03 17:51:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
export type InstanceDeclarationElement
|
|
|
|
= LetDeclaration
|
|
|
|
| TypeDeclaration
|
|
|
|
|
|
|
|
export class InstanceDeclaration extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.InstanceDeclaration;
|
|
|
|
|
|
|
|
public constructor(
|
|
|
|
public pubKeyword: PubKeyword | null,
|
|
|
|
public classKeyword: InstanceKeyword,
|
2023-03-16 21:50:15 +01:00
|
|
|
public constraintClause: ClassConstraintClause | null,
|
|
|
|
public name: IdentifierAlt,
|
|
|
|
public types: TypeExpression[],
|
2023-02-03 17:51:27 +01:00
|
|
|
public elements: InstanceDeclarationElement[],
|
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): InstanceDeclaration {
|
|
|
|
return new InstanceDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.classKeyword.clone(),
|
2023-03-16 21:50:15 +01:00
|
|
|
this.constraintClause !== null ? this.constraintClause.clone() : null,
|
|
|
|
this.name.clone(),
|
|
|
|
this.types.map(t => t.clone()),
|
2023-02-06 11:50:38 +01:00
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2023-02-03 17:51:27 +01:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.classKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
2023-03-16 21:50:15 +01:00
|
|
|
if (this.types.length > 0) {
|
|
|
|
return this.types[this.types.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.name;
|
2023-02-03 17:51:27 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
}
|
2022-09-17 13:20:49 +02:00
|
|
|
export class ModuleDeclaration extends SyntaxBase {
|
2022-08-28 21:12:25 +02:00
|
|
|
|
2022-09-17 13:20:49 +02:00
|
|
|
public readonly kind = SyntaxKind.ModuleDeclaration;
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
2022-08-29 16:17:55 +02:00
|
|
|
public pubKeyword: PubKeyword | null,
|
2022-08-28 21:12:25 +02:00
|
|
|
public modKeyword: ModKeyword,
|
2022-09-17 13:20:49 +02:00
|
|
|
public name: IdentifierAlt,
|
|
|
|
public blockStart: BlockStart,
|
|
|
|
public elements: SourceFileElement[],
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): ModuleDeclaration {
|
|
|
|
return new ModuleDeclaration(
|
|
|
|
this.pubKeyword !== null ? this.pubKeyword.clone() : null,
|
|
|
|
this.modKeyword.clone(),
|
|
|
|
this.name.clone(),
|
|
|
|
this.blockStart.clone(),
|
|
|
|
this.elements.map(element => element.clone())
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.pubKeyword !== null) {
|
|
|
|
return this.pubKeyword;
|
|
|
|
}
|
|
|
|
return this.modKeyword;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
2022-09-17 13:20:49 +02:00
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
|
|
|
}
|
|
|
|
return this.blockStart;
|
2022-08-29 16:17:55 +02:00
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
export type SourceFileElement
|
|
|
|
= Statement
|
|
|
|
| Declaration
|
2023-02-03 17:51:27 +01:00
|
|
|
| ClassDeclaration
|
|
|
|
| InstanceDeclaration
|
2022-09-17 13:20:49 +02:00
|
|
|
| ModuleDeclaration
|
2022-08-28 21:12:25 +02:00
|
|
|
|
|
|
|
export class SourceFile extends SyntaxBase {
|
|
|
|
|
|
|
|
public readonly kind = SyntaxKind.SourceFile;
|
|
|
|
|
2023-04-14 19:57:59 +02:00
|
|
|
@nonenumerable
|
2022-09-01 20:06:43 +02:00
|
|
|
public scope?: Scope;
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
public constructor(
|
2022-08-31 13:29:56 +02:00
|
|
|
private file: TextFile,
|
2022-08-29 16:17:55 +02:00
|
|
|
public elements: SourceFileElement[],
|
|
|
|
public eof: EndOfFile,
|
2022-08-28 21:12:25 +02:00
|
|
|
) {
|
|
|
|
super();
|
|
|
|
}
|
|
|
|
|
2023-02-06 11:50:38 +01:00
|
|
|
public clone(): SourceFile {
|
|
|
|
return new SourceFile(
|
|
|
|
this.file,
|
|
|
|
this.elements.map(element => element.clone()),
|
|
|
|
this.eof,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2022-08-29 16:17:55 +02:00
|
|
|
public getFirstToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[0].getFirstToken();
|
|
|
|
}
|
|
|
|
return this.eof;
|
|
|
|
}
|
|
|
|
|
|
|
|
public getLastToken(): Token {
|
|
|
|
if (this.elements.length > 0) {
|
|
|
|
return this.elements[this.elements.length-1].getLastToken();
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
2022-08-29 16:17:55 +02:00
|
|
|
return this.eof;
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
|
|
|
|
2022-08-31 13:29:56 +02:00
|
|
|
public getFile() {
|
|
|
|
return this.file;
|
|
|
|
}
|
|
|
|
|
2022-08-28 21:12:25 +02:00
|
|
|
}
|
2023-03-11 14:24:02 +01:00
|
|
|
|
|
|
|
export function isSyntax(value: any): value is Syntax {
|
|
|
|
return typeof value === 'object'
|
|
|
|
&& value !== null
|
|
|
|
&& value instanceof SyntaxBase;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function isToken(value: any): value is Token {
|
|
|
|
return typeof value === 'object'
|
|
|
|
&& value !== null
|
|
|
|
&& value instanceof TokenBase;
|
|
|
|
}
|
|
|
|
|
2023-06-30 19:30:42 +02:00
|
|
|
export function visitEachChild<T extends Syntax>(node: T, proc: (node: Syntax) => Syntax | void): Syntax {
|
2023-03-11 14:24:02 +01:00
|
|
|
|
|
|
|
const newArgs = [];
|
|
|
|
let changed = false;
|
|
|
|
|
|
|
|
const traverse = (value: any): any => {
|
|
|
|
if (Array.isArray(value)) {
|
|
|
|
const newElements = [];
|
|
|
|
let changed = false;
|
|
|
|
for (const element of value) {
|
|
|
|
const newElement = traverse(element);
|
|
|
|
if (newElement !== element) {
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
newElements.push(newElement);
|
|
|
|
}
|
|
|
|
return changed ? newElements : value;
|
|
|
|
} else if (isSyntax(value)) {
|
|
|
|
let newValue = proc(value);
|
|
|
|
if (newValue === undefined) {
|
|
|
|
newValue = value;
|
|
|
|
}
|
|
|
|
if (newValue !== value) {
|
|
|
|
changed = true;
|
|
|
|
}
|
|
|
|
return newValue;
|
|
|
|
} else {
|
|
|
|
return value;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const [_key, value] of node.getFields()) {
|
|
|
|
newArgs.push(traverse(value));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!changed) {
|
|
|
|
return node;
|
|
|
|
}
|
2023-03-16 21:50:15 +01:00
|
|
|
return new (node as any).constructor(...newArgs);
|
2023-03-11 14:24:02 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
export function canHaveInstanceDeclaration(node: Syntax): boolean {
|
|
|
|
return node.kind === SyntaxKind.SourceFile
|
|
|
|
|| node.kind === SyntaxKind.ModuleDeclaration
|
|
|
|
|| node.kind === SyntaxKind.LetDeclaration;
|
|
|
|
}
|
|
|
|
|
|
|
|
export function getElements(node: Syntax): Iterable<Syntax> {
|
|
|
|
switch (node.kind) {
|
|
|
|
case SyntaxKind.SourceFile:
|
|
|
|
case SyntaxKind.ModuleDeclaration:
|
|
|
|
return node.elements;
|
|
|
|
case SyntaxKind.LetDeclaration:
|
|
|
|
if (node.body !== null && node.body.kind === SyntaxKind.BlockBody) {
|
|
|
|
return node.body.elements;
|
|
|
|
}
|
|
|
|
// falls through
|
|
|
|
default:
|
|
|
|
return [];
|
|
|
|
}
|
|
|
|
}
|