mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-13 06:51:34 +00:00
Try parsing signatures only if node is callable, see #149; Minor refactoring
This commit is contained in:
22
src/ast.ts
22
src/ast.ts
@ -9,7 +9,7 @@ import {
|
||||
STATIC_DELIMITER,
|
||||
INSTANCE_DELIMITER,
|
||||
LIBRARY_PREFIX
|
||||
} from "./program";
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
Token,
|
||||
@ -110,6 +110,26 @@ export function nodeIsConstantValue(kind: NodeKind): bool {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Checks if a node might be callable. */
|
||||
export function nodeIsCallable(kind: NodeKind): bool {
|
||||
switch (kind) {
|
||||
case NodeKind.IDENTIFIER:
|
||||
case NodeKind.CALL:
|
||||
case NodeKind.ELEMENTACCESS:
|
||||
case NodeKind.PROPERTYACCESS: return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Checks if a node might be callable with generic arguments. */
|
||||
export function nodeIsGenericCallable(kind: NodeKind): bool {
|
||||
switch (kind) {
|
||||
case NodeKind.IDENTIFIER:
|
||||
case NodeKind.PROPERTYACCESS: return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/** Base class of all nodes. */
|
||||
export abstract class Node {
|
||||
|
||||
|
94
src/common.ts
Normal file
94
src/common.ts
Normal file
@ -0,0 +1,94 @@
|
||||
/**
|
||||
* Common constants.
|
||||
* @module common
|
||||
*//***/
|
||||
|
||||
/** Indicates traits of a {@link Node} or {@link Element}. */
|
||||
export enum CommonFlags {
|
||||
/** No flags set. */
|
||||
NONE = 0,
|
||||
|
||||
// Basic modifiers
|
||||
|
||||
/** Has an `import` modifier. */
|
||||
IMPORT = 1 << 0,
|
||||
/** Has an `export` modifier. */
|
||||
EXPORT = 1 << 1,
|
||||
/** Has a `declare` modifier. */
|
||||
DECLARE = 1 << 2,
|
||||
/** Has a `const` modifier. */
|
||||
CONST = 1 << 3,
|
||||
/** Has a `let` modifier. */
|
||||
LET = 1 << 4,
|
||||
/** Has a `static` modifier. */
|
||||
STATIC = 1 << 5,
|
||||
/** Has a `readonly` modifier. */
|
||||
READONLY = 1 << 6,
|
||||
/** Has an `abstract` modifier. */
|
||||
ABSTRACT = 1 << 7,
|
||||
/** Has a `public` modifier. */
|
||||
PUBLIC = 1 << 8,
|
||||
/** Has a `private` modifier. */
|
||||
PRIVATE = 1 << 9,
|
||||
/** Has a `protected` modifier. */
|
||||
PROTECTED = 1 << 10,
|
||||
/** Has a `get` modifier. */
|
||||
GET = 1 << 11,
|
||||
/** Has a `set` modifier. */
|
||||
SET = 1 << 12,
|
||||
|
||||
// Extended modifiers usually derived from basic modifiers
|
||||
|
||||
/** Is ambient, that is either declared or nested in a declared element. */
|
||||
AMBIENT = 1 << 13,
|
||||
/** Is generic. */
|
||||
GENERIC = 1 << 14,
|
||||
/** Is part of a generic context. */
|
||||
GENERIC_CONTEXT = 1 << 15,
|
||||
/** Is an instance member. */
|
||||
INSTANCE = 1 << 16,
|
||||
/** Is a constructor. */
|
||||
CONSTRUCTOR = 1 << 17,
|
||||
/** Is an arrow function. */
|
||||
ARROW = 1 << 18,
|
||||
/** Is a module export. */
|
||||
MODULE_EXPORT = 1 << 19,
|
||||
/** Is a module import. */
|
||||
MODULE_IMPORT = 1 << 20,
|
||||
|
||||
// Compilation states
|
||||
|
||||
/** Is a builtin. */
|
||||
BUILTIN = 1 << 21,
|
||||
/** Is compiled. */
|
||||
COMPILED = 1 << 22,
|
||||
/** Has a constant value and is therefore inlined. */
|
||||
INLINED = 1 << 23,
|
||||
/** Is scoped. */
|
||||
SCOPED = 1 << 24,
|
||||
/** Is a trampoline. */
|
||||
TRAMPOLINE = 1 << 25,
|
||||
/** Is a virtual method. */
|
||||
VIRTUAL = 1 << 26
|
||||
}
|
||||
|
||||
/** Path delimiter inserted between file system levels. */
|
||||
export const PATH_DELIMITER = "/";
|
||||
/** Substitution used to indicate the parent directory. */
|
||||
export const PARENT_SUBST = "..";
|
||||
/** Function name prefix used for getters. */
|
||||
export const GETTER_PREFIX = "get:";
|
||||
/** Function name prefix used for setters. */
|
||||
export const SETTER_PREFIX = "set:";
|
||||
/** Delimiter used between class names and instance members. */
|
||||
export const INSTANCE_DELIMITER = "#";
|
||||
/** Delimiter used between class and namespace names and static members. */
|
||||
export const STATIC_DELIMITER = ".";
|
||||
/** Delimiter used between a function and its inner elements. */
|
||||
export const INNER_DELIMITER = "~";
|
||||
/** Substitution used to indicate a library directory. */
|
||||
export const LIBRARY_SUBST = "~lib";
|
||||
/** Library directory prefix. */
|
||||
export const LIBRARY_PREFIX = LIBRARY_SUBST + PATH_DELIMITER;
|
||||
/** Prefix used to indicate a filespace element. */
|
||||
export const FILESPACE_PREFIX = "file:";
|
@ -36,6 +36,16 @@ import {
|
||||
getGetLocalIndex
|
||||
} from "./module";
|
||||
|
||||
import {
|
||||
CommonFlags,
|
||||
PATH_DELIMITER,
|
||||
INNER_DELIMITER,
|
||||
INSTANCE_DELIMITER,
|
||||
STATIC_DELIMITER,
|
||||
GETTER_PREFIX,
|
||||
SETTER_PREFIX
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
Program,
|
||||
ClassPrototype,
|
||||
@ -54,18 +64,10 @@ import {
|
||||
Property,
|
||||
VariableLikeElement,
|
||||
FlowFlags,
|
||||
CommonFlags,
|
||||
ConstantValueKind,
|
||||
Flow,
|
||||
OperatorKind,
|
||||
DecoratorFlags,
|
||||
|
||||
PATH_DELIMITER,
|
||||
INNER_DELIMITER,
|
||||
INSTANCE_DELIMITER,
|
||||
STATIC_DELIMITER,
|
||||
GETTER_PREFIX,
|
||||
SETTER_PREFIX
|
||||
DecoratorFlags
|
||||
} from "./program";
|
||||
|
||||
import {
|
||||
@ -1487,17 +1489,11 @@ export class Compiler extends DiagnosticEmitter {
|
||||
this.currentFunction.flow = blockFlow;
|
||||
|
||||
var stmts = this.compileStatements(statements);
|
||||
var lastType: NativeType;
|
||||
var stmt = stmts.length == 0
|
||||
? this.module.createNop()
|
||||
: stmts.length == 1
|
||||
? stmts[0]
|
||||
: this.module.createBlock(null, stmts,
|
||||
// if the last expression is a value, annotate the block's return value
|
||||
(lastType = getExpressionType(stmts[stmts.length - 1])) == NativeType.None
|
||||
? NativeType.None
|
||||
: lastType
|
||||
);
|
||||
: this.module.createBlock(null, stmts,getExpressionType(stmts[stmts.length - 1]));
|
||||
|
||||
// Switch back to the parent flow
|
||||
var parentFlow = blockFlow.leaveBranchOrScope();
|
||||
|
@ -3,10 +3,13 @@
|
||||
* @module definitions
|
||||
*//***/
|
||||
|
||||
import {
|
||||
CommonFlags
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
Program,
|
||||
Element,
|
||||
CommonFlags,
|
||||
ElementKind,
|
||||
Global,
|
||||
Enum,
|
||||
|
@ -92,7 +92,7 @@ import {
|
||||
|
||||
import {
|
||||
CommonFlags
|
||||
} from "../program";
|
||||
} from "../common";
|
||||
|
||||
/** An AST builder. */
|
||||
export class ASTBuilder {
|
||||
|
@ -34,8 +34,7 @@ import {
|
||||
} from "./parser";
|
||||
|
||||
import {
|
||||
Program,
|
||||
LIBRARY_PREFIX
|
||||
Program
|
||||
} from "./program";
|
||||
|
||||
/** Parses a source file. If `parser` has been omitted a new one is created. */
|
||||
@ -168,4 +167,4 @@ export function buildTSD(program: Program): string {
|
||||
}
|
||||
|
||||
/** Prefix indicating a library file. */
|
||||
export { LIBRARY_PREFIX };
|
||||
export { LIBRARY_PREFIX } from "./common";
|
||||
|
@ -4,10 +4,13 @@
|
||||
*//***/
|
||||
|
||||
import {
|
||||
Program,
|
||||
CommonFlags,
|
||||
LIBRARY_PREFIX,
|
||||
PATH_DELIMITER
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
Program
|
||||
} from "./program";
|
||||
|
||||
import {
|
||||
@ -77,7 +80,9 @@ import {
|
||||
VoidStatement,
|
||||
WhileStatement,
|
||||
|
||||
mangleInternalPath
|
||||
mangleInternalPath,
|
||||
nodeIsCallable,
|
||||
nodeIsGenericCallable
|
||||
} from "./ast";
|
||||
|
||||
const builtinsFile = LIBRARY_PREFIX + "builtins.ts";
|
||||
@ -3113,16 +3118,18 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (!expr) return null;
|
||||
var startPos = expr.range.start;
|
||||
|
||||
// CallExpression with type arguments
|
||||
var typeArguments: CommonTypeNode[] | null;
|
||||
while (
|
||||
// there might be better ways to distinguish a LESSTHAN from a CALL with type arguments
|
||||
(typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn)) ||
|
||||
tn.skip(Token.OPENPAREN)
|
||||
) {
|
||||
let args = this.parseArguments(tn);
|
||||
if (!args) return null;
|
||||
expr = Node.createCallExpression(expr, typeArguments, args, tn.range(startPos, tn.pos));
|
||||
// CallExpression?
|
||||
if (nodeIsCallable(expr.kind)) {
|
||||
let typeArguments: CommonTypeNode[] | null = null;
|
||||
while (
|
||||
tn.skip(Token.OPENPAREN)
|
||||
||
|
||||
nodeIsGenericCallable(expr.kind) && (typeArguments = this.tryParseTypeArgumentsBeforeArguments(tn)) !== null
|
||||
) {
|
||||
let args = this.parseArguments(tn);
|
||||
if (!args) return null;
|
||||
expr = Node.createCallExpression(expr, typeArguments, args, tn.range(startPos, tn.pos)); // is again callable
|
||||
}
|
||||
}
|
||||
|
||||
var token: Token;
|
||||
|
112
src/program.ts
112
src/program.ts
@ -3,6 +3,17 @@
|
||||
* @module program
|
||||
*//***/
|
||||
|
||||
import {
|
||||
CommonFlags,
|
||||
PATH_DELIMITER,
|
||||
STATIC_DELIMITER,
|
||||
INSTANCE_DELIMITER,
|
||||
LIBRARY_PREFIX,
|
||||
GETTER_PREFIX,
|
||||
SETTER_PREFIX,
|
||||
FILESPACE_PREFIX
|
||||
} from "./common";
|
||||
|
||||
import {
|
||||
Options
|
||||
} from "./compiler";
|
||||
@ -18,7 +29,6 @@ import {
|
||||
TypeKind,
|
||||
TypeFlags,
|
||||
Signature,
|
||||
|
||||
typesToString
|
||||
} from "./types";
|
||||
|
||||
@ -105,27 +115,6 @@ import {
|
||||
CharCode
|
||||
} from "./util";
|
||||
|
||||
/** Path delimiter inserted between file system levels. */
|
||||
export const PATH_DELIMITER = "/";
|
||||
/** Substitution used to indicate the parent directory. */
|
||||
export const PARENT_SUBST = "..";
|
||||
/** Function name prefix used for getters. */
|
||||
export const GETTER_PREFIX = "get:";
|
||||
/** Function name prefix used for setters. */
|
||||
export const SETTER_PREFIX = "set:";
|
||||
/** Delimiter used between class names and instance members. */
|
||||
export const INSTANCE_DELIMITER = "#";
|
||||
/** Delimiter used between class and namespace names and static members. */
|
||||
export const STATIC_DELIMITER = ".";
|
||||
/** Delimiter used between a function and its inner elements. */
|
||||
export const INNER_DELIMITER = "~";
|
||||
/** Substitution used to indicate a library directory. */
|
||||
export const LIBRARY_SUBST = "~lib";
|
||||
/** Library directory prefix. */
|
||||
export const LIBRARY_PREFIX = LIBRARY_SUBST + PATH_DELIMITER;
|
||||
/** Prefix used to indicate a filespace element. */
|
||||
export const FILESPACE_PREFIX = "file:";
|
||||
|
||||
/** Represents a yet unresolved import. */
|
||||
class QueuedImport {
|
||||
localName: string;
|
||||
@ -2415,6 +2404,16 @@ export class Program extends DiagnosticEmitter {
|
||||
);
|
||||
return null;
|
||||
}
|
||||
|
||||
// resolveExpressionType(
|
||||
// expression: Expression,
|
||||
// contextualFunction: Function
|
||||
// ): Type {
|
||||
// var element = this.resolveExpression(expression, contextualFunction);
|
||||
// switch (element.kind) {
|
||||
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
/** Indicates the specific kind of an {@link Element}. */
|
||||
@ -2453,75 +2452,6 @@ export enum ElementKind {
|
||||
FILESPACE,
|
||||
}
|
||||
|
||||
/** Indicates traits of a {@link Node} or {@link Element}. */
|
||||
export enum CommonFlags {
|
||||
/** No flags set. */
|
||||
NONE = 0,
|
||||
|
||||
// Basic modifiers
|
||||
|
||||
/** Has an `import` modifier. */
|
||||
IMPORT = 1 << 0,
|
||||
/** Has an `export` modifier. */
|
||||
EXPORT = 1 << 1,
|
||||
/** Has a `declare` modifier. */
|
||||
DECLARE = 1 << 2,
|
||||
/** Has a `const` modifier. */
|
||||
CONST = 1 << 3,
|
||||
/** Has a `let` modifier. */
|
||||
LET = 1 << 4,
|
||||
/** Has a `static` modifier. */
|
||||
STATIC = 1 << 5,
|
||||
/** Has a `readonly` modifier. */
|
||||
READONLY = 1 << 6,
|
||||
/** Has an `abstract` modifier. */
|
||||
ABSTRACT = 1 << 7,
|
||||
/** Has a `public` modifier. */
|
||||
PUBLIC = 1 << 8,
|
||||
/** Has a `private` modifier. */
|
||||
PRIVATE = 1 << 9,
|
||||
/** Has a `protected` modifier. */
|
||||
PROTECTED = 1 << 10,
|
||||
/** Has a `get` modifier. */
|
||||
GET = 1 << 11,
|
||||
/** Has a `set` modifier. */
|
||||
SET = 1 << 12,
|
||||
|
||||
// Extended modifiers usually derived from basic modifiers
|
||||
|
||||
/** Is ambient, that is either declared or nested in a declared element. */
|
||||
AMBIENT = 1 << 13,
|
||||
/** Is generic. */
|
||||
GENERIC = 1 << 14,
|
||||
/** Is part of a generic context. */
|
||||
GENERIC_CONTEXT = 1 << 15,
|
||||
/** Is an instance member. */
|
||||
INSTANCE = 1 << 16,
|
||||
/** Is a constructor. */
|
||||
CONSTRUCTOR = 1 << 17,
|
||||
/** Is an arrow function. */
|
||||
ARROW = 1 << 18,
|
||||
/** Is a module export. */
|
||||
MODULE_EXPORT = 1 << 19,
|
||||
/** Is a module import. */
|
||||
MODULE_IMPORT = 1 << 20,
|
||||
|
||||
// Compilation states
|
||||
|
||||
/** Is a builtin. */
|
||||
BUILTIN = 1 << 21,
|
||||
/** Is compiled. */
|
||||
COMPILED = 1 << 22,
|
||||
/** Has a constant value and is therefore inlined. */
|
||||
INLINED = 1 << 23,
|
||||
/** Is scoped. */
|
||||
SCOPED = 1 << 24,
|
||||
/** Is a trampoline. */
|
||||
TRAMPOLINE = 1 << 25,
|
||||
/** Is a virtual method. */
|
||||
VIRTUAL = 1 << 26
|
||||
}
|
||||
|
||||
export enum DecoratorFlags {
|
||||
/** No flags set. */
|
||||
NONE = 0,
|
||||
|
Reference in New Issue
Block a user