mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-26 21:21:54 +00:00
Program elements and resolve infrastructure; Stdlib ideas; Restructuring
This commit is contained in:
178
src/ast.ts
178
src/ast.ts
@ -66,6 +66,7 @@
|
||||
|
||||
*/
|
||||
|
||||
import { GETTER_PREFIX, SETTER_PREFIX, PATH_DELIMITER, PARENT_SUBST, STATIC_DELIMITER, INSTANCE_DELIMITER } from "./constants";
|
||||
import { Token, Tokenizer, operatorTokenToString, Range } from "./tokenizer";
|
||||
import { CharCode, I64, normalizePath, resolvePath } from "./util";
|
||||
|
||||
@ -139,59 +140,6 @@ export enum NodeKind {
|
||||
WHILE
|
||||
}
|
||||
|
||||
export function nodeKindToString(kind: NodeKind): string {
|
||||
switch (kind) {
|
||||
case NodeKind.SOURCE: return "SOURCE";
|
||||
case NodeKind.TYPE: return "TYPE";
|
||||
case NodeKind.TYPEPARAMETER: return "TYPEPARAMETER";
|
||||
case NodeKind.IDENTIFIER: return "IDENTIFIER";
|
||||
case NodeKind.ASSERTION: return "ASSERTION";
|
||||
case NodeKind.BINARY: return "BINARY";
|
||||
case NodeKind.CALL: return "CALL";
|
||||
case NodeKind.ELEMENTACCESS: return "ELEMENTACCESS";
|
||||
case NodeKind.LITERAL: return "LITERAL";
|
||||
case NodeKind.NEW: return "NEW";
|
||||
case NodeKind.PARENTHESIZED: return "PARENTHESIZED";
|
||||
case NodeKind.PROPERTYACCESS: return "PROPERTYACCESS";
|
||||
case NodeKind.SELECT: return "SELECT";
|
||||
case NodeKind.UNARYPOSTFIX: return "UNARYPOSTFIX";
|
||||
case NodeKind.UNARYPREFIX: return "UNARYPREFIX";
|
||||
case NodeKind.BLOCK: return "BLOCK";
|
||||
case NodeKind.BREAK: return "BREAK";
|
||||
case NodeKind.CLASS: return "CLASS";
|
||||
case NodeKind.CONTINUE: return "CONTINUE";
|
||||
case NodeKind.DO: return "DO";
|
||||
case NodeKind.EMPTY: return "EMPTY";
|
||||
case NodeKind.ENUM: return "ENUM";
|
||||
case NodeKind.ENUMVALUE: return "ENUMVALUE";
|
||||
case NodeKind.EXPORT: return "EXPORT";
|
||||
case NodeKind.EXPORTIMPORT: return "EXPORTIMPORT";
|
||||
case NodeKind.EXPRESSION: return "EXPRESSION";
|
||||
case NodeKind.INTERFACE: return "INTERFACE";
|
||||
case NodeKind.FALSE: return "FALSE";
|
||||
case NodeKind.FOR: return "FOR";
|
||||
case NodeKind.FUNCTION: return "FUNCTION";
|
||||
case NodeKind.IF: return "IF";
|
||||
case NodeKind.IMPORT: return "IMPORT";
|
||||
case NodeKind.IMPORTDECLARATION: return "IMPORTDECLARATION";
|
||||
case NodeKind.METHOD: return "METHOD";
|
||||
case NodeKind.NAMESPACE: return "NAMESPACE";
|
||||
case NodeKind.NULL: return "NULL";
|
||||
case NodeKind.FIELD: return "PROPERTY";
|
||||
case NodeKind.RETURN: return "RETURN";
|
||||
case NodeKind.SUPER: return "SUPER";
|
||||
case NodeKind.SWITCH: return "SWITCH";
|
||||
case NodeKind.THIS: return "THIS";
|
||||
case NodeKind.THROW: return "THROW";
|
||||
case NodeKind.TRUE: return "TRUE";
|
||||
case NodeKind.TRY: return "TRY";
|
||||
case NodeKind.VARIABLE: return "VARIABLE";
|
||||
case NodeKind.VARIABLEDECLARATION: return "VARIABLEDECLARATION";
|
||||
case NodeKind.WHILE: return "WHILE";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
// types
|
||||
|
||||
export class TypeNode extends Node {
|
||||
@ -416,18 +364,6 @@ export const enum LiteralKind {
|
||||
OBJECT
|
||||
}
|
||||
|
||||
export function literalKindToString(kind: LiteralKind): string {
|
||||
switch (kind) {
|
||||
case LiteralKind.FLOAT: return "FLOAT";
|
||||
case LiteralKind.INTEGER: return "INTEGER";
|
||||
case LiteralKind.STRING: return "STRING";
|
||||
case LiteralKind.REGEXP: return "REGEXP";
|
||||
case LiteralKind.ARRAY: return "ARRAY";
|
||||
case LiteralKind.OBJECT: return "OBJECT";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class LiteralExpression extends Expression {
|
||||
kind = NodeKind.LITERAL;
|
||||
literalKind: LiteralKind;
|
||||
@ -840,24 +776,6 @@ export enum ModifierKind {
|
||||
SET
|
||||
}
|
||||
|
||||
export function modifierKindToString(kind: ModifierKind): string {
|
||||
switch (kind) {
|
||||
case ModifierKind.ASYNC: return "ASYNC";
|
||||
case ModifierKind.CONST: return "CONST";
|
||||
case ModifierKind.DECLARE: return "DECLARE";
|
||||
case ModifierKind.EXPORT: return "EXPORT";
|
||||
case ModifierKind.IMPORT: return "IMPORT";
|
||||
case ModifierKind.STATIC: return "STATIC";
|
||||
case ModifierKind.ABSTRACT: return "ABSTRACT";
|
||||
case ModifierKind.PUBLIC: return "PUBLIC";
|
||||
case ModifierKind.PRIVATE: return "PRIVATE";
|
||||
case ModifierKind.PROTECTED: return "PROTECTED";
|
||||
case ModifierKind.GET: return "GET";
|
||||
case ModifierKind.SET: return "SET";
|
||||
default: return "";
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class Statement extends Node {
|
||||
|
||||
static createBlock(statements: Statement[], range: Range): BlockStatement {
|
||||
@ -943,6 +861,7 @@ export abstract class Statement extends Node {
|
||||
for (i = 0, k = (stmt.members = members).length; i < k; ++i) members[i].parent = stmt;
|
||||
stmt.path = path;
|
||||
stmt.normalizedPath = path ? resolvePath(normalizePath(path.value), range.source.normalizedPath) : null;
|
||||
stmt.internalPath = stmt.normalizedPath ? mangleInternalPath(stmt.normalizedPath) : null;
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@ -984,6 +903,7 @@ export abstract class Statement extends Node {
|
||||
for (let i: i32 = 0, k: i32 = (stmt.declarations = declarations).length; i < k; ++i) declarations[i].parent = stmt;
|
||||
stmt.path = path;
|
||||
stmt.normalizedPath = resolvePath(normalizePath(path.value), range.source.normalizedPath);
|
||||
stmt.internalPath = mangleInternalPath(stmt.normalizedPath);
|
||||
return stmt;
|
||||
}
|
||||
|
||||
@ -995,7 +915,7 @@ export abstract class Statement extends Node {
|
||||
return elem;
|
||||
}
|
||||
|
||||
static createInterface(modifiers: Modifier[], extendsType: TypeNode | null, members: Statement[], range: Range): InterfaceDeclaration {
|
||||
static createInterface(modifiers: Modifier[], extendsType: TypeNode | null, members: DeclarationStatement[], range: Range): InterfaceDeclaration {
|
||||
const stmt: InterfaceDeclaration = new InterfaceDeclaration();
|
||||
stmt.range = range;
|
||||
let i: i32, k: i32;
|
||||
@ -1164,6 +1084,7 @@ export class Source extends Node {
|
||||
parent = null;
|
||||
path: string;
|
||||
normalizedPath: string;
|
||||
internalPath: string;
|
||||
statements: Statement[];
|
||||
|
||||
text: string;
|
||||
@ -1174,6 +1095,7 @@ export class Source extends Node {
|
||||
super();
|
||||
this.path = path;
|
||||
this.normalizedPath = normalizePath(path, true);
|
||||
this.internalPath = mangleInternalPath(this.normalizedPath);
|
||||
this.statements = new Array();
|
||||
this.range = new Range(this, 0, text.length);
|
||||
this.text = text;
|
||||
@ -1199,14 +1121,15 @@ export abstract class DeclarationStatement extends Statement {
|
||||
|
||||
identifier: IdentifierExpression;
|
||||
modifiers: Modifier[] | null;
|
||||
private _cachedInternalName: string | null = null;
|
||||
globalExportName: string | null = null;
|
||||
|
||||
get internalName(): string {
|
||||
if (this._cachedInternalName == null)
|
||||
this._cachedInternalName = mangleInternalName(this);
|
||||
return this._cachedInternalName;
|
||||
}
|
||||
protected _cachedInternalName: string | null = null;
|
||||
|
||||
get internalName(): string { return this._cachedInternalName === null ? this._cachedInternalName = mangleInternalName(this) : this._cachedInternalName; }
|
||||
}
|
||||
|
||||
export abstract class VariableLikeDeclarationStatement extends DeclarationStatement {
|
||||
type: TypeNode | null;
|
||||
initializer: Expression | null;
|
||||
}
|
||||
|
||||
export class BlockStatement extends Statement {
|
||||
@ -1250,6 +1173,16 @@ export class ClassDeclaration extends DeclarationStatement {
|
||||
members: DeclarationStatement[];
|
||||
decorators: DecoratorStatement[];
|
||||
|
||||
get internalName(): string {
|
||||
if (this._cachedInternalName !== null)
|
||||
return this._cachedInternalName;
|
||||
const globalDecorator: DecoratorStatement | null = getDecoratorByName("global", this.decorators);
|
||||
if (globalDecorator && globalDecorator.expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>globalDecorator.expression).name == "global")
|
||||
return this._cachedInternalName = this.identifier.name;
|
||||
else
|
||||
return this._cachedInternalName = mangleInternalName(this);
|
||||
}
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = this.decorators.length; i < k; ++i) {
|
||||
@ -1429,6 +1362,7 @@ export class ExportStatement extends Statement {
|
||||
members: ExportMember[];
|
||||
path: StringLiteralExpression | null;
|
||||
normalizedPath: string | null;
|
||||
internalPath: string | null;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
let i: i32, k: i32;
|
||||
@ -1461,11 +1395,9 @@ export class ExpressionStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
export class FieldDeclaration extends DeclarationStatement {
|
||||
export class FieldDeclaration extends VariableLikeDeclarationStatement {
|
||||
|
||||
kind = NodeKind.FIELD;
|
||||
type: TypeNode | null;
|
||||
initializer: Expression | null;
|
||||
decorators: DecoratorStatement[];
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
@ -1527,6 +1459,16 @@ export class FunctionDeclaration extends DeclarationStatement {
|
||||
statements: Statement[] | null;
|
||||
decorators: DecoratorStatement[];
|
||||
|
||||
get internalName(): string {
|
||||
if (this._cachedInternalName !== null)
|
||||
return this._cachedInternalName;
|
||||
const globalDecorator: DecoratorStatement | null = getDecoratorByName("global", this.decorators);
|
||||
if (globalDecorator && globalDecorator.expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>globalDecorator.expression).name == "global")
|
||||
return this._cachedInternalName = this.identifier.name;
|
||||
else
|
||||
return this._cachedInternalName = mangleInternalName(this);
|
||||
}
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
let i: i32, k: i32;
|
||||
for (i = 0, k = this.decorators.length; i < k; ++i) {
|
||||
@ -1625,6 +1567,7 @@ export class ImportStatement extends Statement {
|
||||
declarations: ImportDeclaration[];
|
||||
path: StringLiteralExpression;
|
||||
normalizedPath: string;
|
||||
internalPath: string;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
sb.push("import {\n");
|
||||
@ -1638,12 +1581,9 @@ export class ImportStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
export class InterfaceDeclaration extends DeclarationStatement {
|
||||
export class InterfaceDeclaration extends ClassDeclaration {
|
||||
|
||||
kind = NodeKind.INTERFACE;
|
||||
typeParameters: TypeParameter[];
|
||||
extendsType: TypeNode | null;
|
||||
members: Statement[];
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
let i: i32, k: i32;
|
||||
@ -1872,12 +1812,10 @@ export class TryStatement extends Statement {
|
||||
}
|
||||
}
|
||||
|
||||
export class VariableDeclaration extends DeclarationStatement {
|
||||
export class VariableDeclaration extends VariableLikeDeclarationStatement {
|
||||
|
||||
kind = NodeKind.VARIABLEDECLARATION;
|
||||
modifiers = null;
|
||||
type: TypeNode | null;
|
||||
initializer: Expression | null;
|
||||
|
||||
serialize(sb: string[]): void {
|
||||
this.identifier.serialize(sb);
|
||||
@ -1940,21 +1878,53 @@ export function hasModifier(kind: ModifierKind, modifiers: Modifier[] | null): b
|
||||
return false;
|
||||
}
|
||||
|
||||
export function getDecoratorByName(name: string, decorators: DecoratorStatement[]): DecoratorStatement | null {
|
||||
for (let i: i32 = 0, k: i32 = decorators.length; i < k; ++i) {
|
||||
const decorator: DecoratorStatement = decorators[i];
|
||||
const expression: Expression = decorator.expression;
|
||||
if (expression.kind == NodeKind.IDENTIFIER && (<IdentifierExpression>expression).name == name)
|
||||
return decorator;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function serialize(node: Node, indent: i32 = 0): string {
|
||||
const sb: string[] = new Array(); // shared builder could grow too much
|
||||
node.serialize(sb);
|
||||
return sb.join("");
|
||||
}
|
||||
|
||||
export function mangleInternalPath(path: string): string {
|
||||
if (PATH_DELIMITER.charCodeAt(0) != CharCode.SLASH)
|
||||
path = path.replace("/", PATH_DELIMITER);
|
||||
if (PARENT_SUBST != "..")
|
||||
path = path.replace("..", PARENT_SUBST);
|
||||
return path;
|
||||
}
|
||||
|
||||
export function mangleInternalName(declaration: DeclarationStatement): string {
|
||||
let name: string = declaration.identifier.name;
|
||||
let modifiers: Modifier[] | null;
|
||||
if (declaration.kind == NodeKind.METHOD && (modifiers = declaration.modifiers)) {
|
||||
for (let i: i32 = 0, k: i32 = modifiers.length; i < k; ++i) {
|
||||
const modifier: Modifier = modifiers[i];
|
||||
if (modifier.modifierKind == ModifierKind.GET) {
|
||||
name = GETTER_PREFIX + name;
|
||||
break;
|
||||
}
|
||||
else if (modifier.modifierKind == ModifierKind.SET) {
|
||||
name = SETTER_PREFIX + name;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!declaration.parent)
|
||||
return name;
|
||||
if (declaration.parent.kind == NodeKind.CLASS)
|
||||
return (<ClassDeclaration>declaration.parent).internalName + (hasModifier(ModifierKind.STATIC, declaration.modifiers) ? "." : "#") + name;
|
||||
return (<ClassDeclaration>declaration.parent).internalName + (hasModifier(ModifierKind.STATIC, declaration.modifiers) ? STATIC_DELIMITER : INSTANCE_DELIMITER) + name;
|
||||
if (declaration.parent.kind == NodeKind.NAMESPACE || declaration.parent.kind == NodeKind.ENUM)
|
||||
return (<DeclarationStatement>declaration.parent).internalName + "." + name;
|
||||
return declaration.range.source.normalizedPath + "/" + name;
|
||||
return (<DeclarationStatement>declaration.parent).internalName + STATIC_DELIMITER + name;
|
||||
return declaration.range.source.internalPath + PATH_DELIMITER + name;
|
||||
}
|
||||
|
||||
function builderEndsWith(sb: string[], code: CharCode): bool {
|
||||
|
Reference in New Issue
Block a user