848 lines
14 KiB
TypeScript
848 lines
14 KiB
TypeScript
|
|
||
|
export type TextSpan = [number, number];
|
||
|
|
||
|
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++;
|
||
|
}
|
||
|
this.offset += text.length;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
|
||
|
public constructor(
|
||
|
public origPath: string,
|
||
|
public text: string,
|
||
|
) {
|
||
|
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export const enum SyntaxKind {
|
||
|
|
||
|
// Tokens
|
||
|
Identifier,
|
||
|
CustomOperator,
|
||
|
LParen,
|
||
|
RParen,
|
||
|
LBrace,
|
||
|
RBrace,
|
||
|
LBracket,
|
||
|
RBracket,
|
||
|
Dot,
|
||
|
DotDot,
|
||
|
Comma,
|
||
|
Colon,
|
||
|
Equals,
|
||
|
Integer,
|
||
|
StringLiteral,
|
||
|
LetKeyword,
|
||
|
PubKeyword,
|
||
|
MutKeyword,
|
||
|
ModKeyword,
|
||
|
ImportKeyword,
|
||
|
StructKeyword,
|
||
|
TypeKeyword,
|
||
|
LineFoldEnd,
|
||
|
BlockEnd,
|
||
|
BlockStart,
|
||
|
EndOfFile,
|
||
|
|
||
|
// Type expressions
|
||
|
ReferenceTypeExpression,
|
||
|
|
||
|
// Patterns
|
||
|
BindPattern,
|
||
|
TuplePattern,
|
||
|
|
||
|
// Expressions
|
||
|
ReferenceExpression,
|
||
|
TupleExpression,
|
||
|
NestedExpression,
|
||
|
ConstantExpression,
|
||
|
PrefixExpression,
|
||
|
PostfixExpression,
|
||
|
InfixExpression,
|
||
|
|
||
|
// Statements
|
||
|
ReturnStatement,
|
||
|
ExpressionStatement,
|
||
|
|
||
|
// Declarations
|
||
|
VariableDeclaration,
|
||
|
PrefixFuncDecl,
|
||
|
SuffixFuncDecl,
|
||
|
LetDeclaration,
|
||
|
StructDeclaration,
|
||
|
ImportDeclaration,
|
||
|
TypeAliasDeclaration,
|
||
|
|
||
|
// Other nodes
|
||
|
StructDeclarationField,
|
||
|
ExprBody,
|
||
|
BlockBody,
|
||
|
TypeAssert,
|
||
|
Param,
|
||
|
Module,
|
||
|
SourceFile,
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Syntax
|
||
|
= SourceFile
|
||
|
| Param
|
||
|
| StructDeclarationField
|
||
|
| Declaration
|
||
|
| Statement
|
||
|
| Expression
|
||
|
| TypeExpression
|
||
|
| Pattern
|
||
|
|
||
|
abstract class SyntaxBase {
|
||
|
|
||
|
public abstract readonly kind: SyntaxKind;
|
||
|
|
||
|
}
|
||
|
|
||
|
abstract class TokenBase extends SyntaxBase {
|
||
|
|
||
|
private endPos: TextPosition | null = null;
|
||
|
|
||
|
constructor(
|
||
|
private startPos: TextPosition,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
public getStartPosition(): TextPosition {
|
||
|
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 {
|
||
|
public readonly kind = SyntaxKind.EndOfFile;
|
||
|
}
|
||
|
|
||
|
export class BlockEnd extends VirtualTokenBase {
|
||
|
public readonly kind = SyntaxKind.BlockEnd;
|
||
|
}
|
||
|
|
||
|
export class BlockStart extends VirtualTokenBase {
|
||
|
public readonly kind = SyntaxKind.BlockStart;
|
||
|
}
|
||
|
|
||
|
export class LineFoldEnd extends VirtualTokenBase {
|
||
|
public readonly kind = SyntaxKind.LineFoldEnd;
|
||
|
}
|
||
|
|
||
|
export class Integer extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Integer;
|
||
|
|
||
|
public constructor(
|
||
|
public value: bigint,
|
||
|
public radix: number,
|
||
|
private startPos: TextPosition,
|
||
|
) {
|
||
|
super(startPos);
|
||
|
}
|
||
|
|
||
|
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(
|
||
|
public contents: string,
|
||
|
private startPos: TextPosition,
|
||
|
) {
|
||
|
super(startPos);
|
||
|
}
|
||
|
|
||
|
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 {
|
||
|
out += '\\u' + code.toString(17).padStart(4, '0');
|
||
|
}
|
||
|
}
|
||
|
out += '"';
|
||
|
return out;
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class Identifier extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Identifier;
|
||
|
|
||
|
public constructor(
|
||
|
public text: string,
|
||
|
private startPos: TextPosition,
|
||
|
) {
|
||
|
super(startPos);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class CustomOperator extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.CustomOperator;
|
||
|
|
||
|
public constructor(
|
||
|
public text: string,
|
||
|
private startPos: TextPosition,
|
||
|
) {
|
||
|
super(startPos);
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class LParen extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.LParen;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '(';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class RParen extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.RParen;
|
||
|
|
||
|
public get text(): string {
|
||
|
return ')';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class LBrace extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.LBrace;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '{';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class RBrace extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.RBrace;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '}';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class LBracket extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.LBracket;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '[';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class RBracket extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.RBracket;
|
||
|
|
||
|
public get text(): string {
|
||
|
return ']';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class Dot extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Dot;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '.';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class Comma extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Comma;
|
||
|
|
||
|
public get text(): string {
|
||
|
return ',';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class DotDot extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.DotDot;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '..';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class Colon extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Colon;
|
||
|
|
||
|
public get text(): string {
|
||
|
return ':';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class Equals extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Equals;
|
||
|
|
||
|
public get text(): string {
|
||
|
return '=';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class StructKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.StructKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'struct';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class ModKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ModKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'mod';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class MutKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.MutKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'mut';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class ImportKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ImportKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'import'
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class TypeKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.TypeKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'type';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class PubKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.PubKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'pub';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class LetKeyword extends TokenBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.LetKeyword;
|
||
|
|
||
|
public get text(): string {
|
||
|
return 'let';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Token
|
||
|
= LParen
|
||
|
| RParen
|
||
|
| LBrace
|
||
|
| RBrace
|
||
|
| LBracket
|
||
|
| RBracket
|
||
|
| Identifier
|
||
|
| CustomOperator
|
||
|
| Integer
|
||
|
| StringLiteral
|
||
|
| Comma
|
||
|
| Dot
|
||
|
| DotDot
|
||
|
| Colon
|
||
|
| Equals
|
||
|
| LetKeyword
|
||
|
| PubKeyword
|
||
|
| MutKeyword
|
||
|
| ModKeyword
|
||
|
| ImportKeyword
|
||
|
| TypeKeyword
|
||
|
| StructKeyword
|
||
|
| EndOfFile
|
||
|
| BlockStart
|
||
|
| BlockEnd
|
||
|
| LineFoldEnd
|
||
|
|
||
|
export type TokenKind
|
||
|
= Token['kind']
|
||
|
|
||
|
export class ReferenceTypeExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ReferenceTypeExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public modulePath: Array<[Identifier, Dot]>,
|
||
|
public name: Identifier,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type TypeExpression
|
||
|
= ReferenceTypeExpression
|
||
|
|
||
|
export class BindPattern extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.BindPattern;
|
||
|
|
||
|
public constructor(
|
||
|
public name: Identifier,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
public get isHole(): boolean {
|
||
|
return this.name.text == '_';
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class TuplePattern extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.TuplePattern;
|
||
|
|
||
|
public constructor(
|
||
|
public elements: Pattern[],
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Pattern
|
||
|
= BindPattern
|
||
|
| TuplePattern
|
||
|
|
||
|
export class TupleExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.TupleExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public lparen: LParen,
|
||
|
public elements: Expression[],
|
||
|
public rparen: RParen,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class NestedExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.NestedExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public lparen: LParen,
|
||
|
public expression: Expression,
|
||
|
public rparen: RParen,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class ConstantExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ConstantExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public token: Integer | StringLiteral,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class ReferenceExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ReferenceExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public modulePath: Array<[Identifier, Dot]>,
|
||
|
public name: Identifier
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class PrefixExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.PrefixExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public operator: Token,
|
||
|
public expression: Expression,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class PostfixExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.PostfixExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public expression: Expression,
|
||
|
public operator: Token,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class InfixExpression extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.InfixExpression;
|
||
|
|
||
|
public constructor(
|
||
|
public left: Expression,
|
||
|
public operator: Token,
|
||
|
public right: Expression,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Expression
|
||
|
= ReferenceExpression
|
||
|
| ConstantExpression
|
||
|
| TupleExpression
|
||
|
| NestedExpression
|
||
|
| PrefixExpression
|
||
|
| InfixExpression
|
||
|
| PostfixExpression
|
||
|
|
||
|
export class ReturnStatement extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ReturnStatement;
|
||
|
|
||
|
public constructor(
|
||
|
public expr: Expression
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class ExpressionStatement extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ExpressionStatement;
|
||
|
|
||
|
public constructor(
|
||
|
public expresion: Expression,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Statement
|
||
|
= ReturnStatement
|
||
|
| ExpressionStatement
|
||
|
|
||
|
export class Param extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Param;
|
||
|
|
||
|
public constructor(
|
||
|
public pattern: Pattern,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class StructDeclarationField extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.StructDeclarationField;
|
||
|
|
||
|
public constructor(
|
||
|
public name: Identifier,
|
||
|
public colon: Colon,
|
||
|
public typeExpr: TypeExpression,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class StructDeclaration extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.StructDeclaration;
|
||
|
|
||
|
public constructor(
|
||
|
public structKeyword: StructKeyword,
|
||
|
public name: Identifier,
|
||
|
public members: StructDeclarationField[] | null,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class TypeAssert extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.TypeAssert;
|
||
|
|
||
|
public constructor(
|
||
|
public colon: Colon,
|
||
|
public typeExpression: TypeExpression,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Body
|
||
|
= ExprBody
|
||
|
| BlockBody
|
||
|
|
||
|
export class ExprBody extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ExprBody;
|
||
|
|
||
|
public constructor(
|
||
|
public equals: Equals,
|
||
|
public expression: Expression,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type LetBodyElement
|
||
|
= LetDeclaration
|
||
|
| Statement
|
||
|
|
||
|
export class BlockBody extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.BlockBody;
|
||
|
|
||
|
public constructor(
|
||
|
public blockStart: BlockStart,
|
||
|
public elements: LetBodyElement[],
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
export class LetDeclaration extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.LetDeclaration;
|
||
|
|
||
|
public constructor(
|
||
|
public pubKeyword: PubKeyword | null,
|
||
|
public letKeyword: LetKeyword,
|
||
|
public mutKeyword: MutKeyword | null,
|
||
|
public pattern: Pattern,
|
||
|
public params: Param[],
|
||
|
public typeAssert: TypeAssert | null,
|
||
|
public body: Body | null,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export class ImportDeclaration extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.ImportDeclaration;
|
||
|
|
||
|
public constructor(
|
||
|
public importKeyword: ImportKeyword,
|
||
|
public importSource: StringLiteral,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type Declaration
|
||
|
= LetDeclaration
|
||
|
| ImportDeclaration
|
||
|
| StructDeclaration
|
||
|
|
||
|
export class Module extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.Module;
|
||
|
|
||
|
public constructor(
|
||
|
public modKeyword: ModKeyword,
|
||
|
public name: Identifier,
|
||
|
public body: Body,
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
}
|
||
|
|
||
|
export type SourceFileElement
|
||
|
= Statement
|
||
|
| Declaration
|
||
|
| Module
|
||
|
|
||
|
export class SourceFile extends SyntaxBase {
|
||
|
|
||
|
public readonly kind = SyntaxKind.SourceFile;
|
||
|
|
||
|
public constructor(
|
||
|
public elements: SourceFileElement[]
|
||
|
) {
|
||
|
super();
|
||
|
}
|
||
|
|
||
|
public *getChildNodes(): Iterable<Syntax> {
|
||
|
for (const element in this.elements) {
|
||
|
yield element;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
}
|