mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-06-23 19:51:47 +00:00
Merge branch 'master' into runtime
This commit is contained in:
@ -521,7 +521,7 @@ export class Compiler extends DiagnosticEmitter {
|
||||
break;
|
||||
}
|
||||
case ElementKind.ENUMVALUE: {
|
||||
if (!assert(element.parent).is(CommonFlags.CONST) && !this.options.hasFeature(Feature.MUTABLE_GLOBAL)) {
|
||||
if (!(<EnumValue>element).isImmutable && !this.options.hasFeature(Feature.MUTABLE_GLOBAL)) {
|
||||
this.error(
|
||||
DiagnosticCode.Cannot_export_a_mutable_global,
|
||||
(<EnumValue>element).identifierNode.range
|
||||
@ -970,16 +970,14 @@ export class Compiler extends DiagnosticEmitter {
|
||||
WrapMode.NONE
|
||||
);
|
||||
if (getExpressionId(initExpr) != ExpressionId.Const) {
|
||||
if (element.is(CommonFlags.CONST)) {
|
||||
initExpr = module.precomputeExpression(initExpr);
|
||||
if (getExpressionId(initExpr) != ExpressionId.Const) {
|
||||
initExpr = module.precomputeExpression(initExpr);
|
||||
if (getExpressionId(initExpr) != ExpressionId.Const) {
|
||||
if (element.is(CommonFlags.CONST)) {
|
||||
this.error(
|
||||
DiagnosticCode.In_const_enum_declarations_member_initializer_must_be_constant_expression,
|
||||
valueNode.range
|
||||
);
|
||||
initInStart = true;
|
||||
}
|
||||
} else {
|
||||
initInStart = true;
|
||||
}
|
||||
}
|
||||
@ -1021,8 +1019,9 @@ export class Compiler extends DiagnosticEmitter {
|
||||
module.addGlobal(val.internalName, NativeType.I32, false, initExpr);
|
||||
}
|
||||
} else {
|
||||
module.addGlobal(val.internalName, NativeType.I32, true, initExpr);
|
||||
module.addGlobal(val.internalName, NativeType.I32, false, initExpr);
|
||||
}
|
||||
val.isImmutable = true;
|
||||
previousValueIsMut = false;
|
||||
}
|
||||
previousValue = <EnumValue>val;
|
||||
|
@ -1746,13 +1746,8 @@ export class BinaryModule {
|
||||
/** Tests if an expression needs an explicit 'unreachable' when it is the terminating statement. */
|
||||
export function needsExplicitUnreachable(expr: ExpressionRef): bool {
|
||||
// not applicable if pushing a value to the stack
|
||||
switch (_BinaryenExpressionGetType(expr)) {
|
||||
case NativeType.I32:
|
||||
case NativeType.I64:
|
||||
case NativeType.F32:
|
||||
case NativeType.F64:
|
||||
case NativeType.V128: return false;
|
||||
}
|
||||
if (_BinaryenExpressionGetType(expr) != NativeType.Unreachable) return false;
|
||||
|
||||
switch (_BinaryenExpressionGetId(expr)) {
|
||||
case ExpressionId.Unreachable:
|
||||
case ExpressionId.Return: return false;
|
||||
|
@ -164,8 +164,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
this.skipStatement(tn);
|
||||
continue;
|
||||
}
|
||||
if (!decorators) decorators = [];
|
||||
decorators.push(decorator);
|
||||
if (!decorators) decorators = [decorator];
|
||||
else decorators.push(decorator);
|
||||
}
|
||||
|
||||
// check modifiers
|
||||
@ -454,7 +454,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
} else if (token == Token.IDENTIFIER) {
|
||||
let first = Node.createSimpleTypeName(tn.readIdentifier(), tn.range());
|
||||
let current = first;
|
||||
let parameters = new Array<TypeNode>();
|
||||
let parameters: TypeNode[] | null = null;
|
||||
let nullable = false;
|
||||
|
||||
// Identifier ('.' Identifier)+
|
||||
@ -477,7 +477,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
do {
|
||||
let parameter = this.parseType(tn, true, suppressErrors);
|
||||
if (!parameter) return null;
|
||||
parameters.push(<TypeNode>parameter);
|
||||
if (!parameters) parameters = [<TypeNode>parameter];
|
||||
else parameters.push(<TypeNode>parameter);
|
||||
} while (tn.skip(Token.COMMA));
|
||||
if (!tn.skip(Token.GREATERTHAN)) {
|
||||
if (!suppressErrors) {
|
||||
@ -503,8 +504,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
type = Node.createType(first, parameters, nullable, tn.range(startPos, tn.pos));
|
||||
|
||||
type = Node.createType(first, parameters || [], nullable, tn.range(startPos, tn.pos));
|
||||
} else {
|
||||
if (!suppressErrors) {
|
||||
this.error(
|
||||
@ -939,7 +939,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
|
||||
// at '<': TypeParameter (',' TypeParameter)* '>'
|
||||
|
||||
var typeParameters = new Array<TypeParameterNode>();
|
||||
var typeParameters: TypeParameterNode[] | null = null;
|
||||
var seenOptional = false;
|
||||
while (!tn.skip(Token.GREATERTHAN)) {
|
||||
let typeParameter = this.parseTypeParameter(tn);
|
||||
@ -953,7 +953,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
);
|
||||
typeParameter.defaultType = null;
|
||||
}
|
||||
typeParameters.push(<TypeParameterNode>typeParameter);
|
||||
if (!typeParameters) typeParameters = [ typeParameter ];
|
||||
else typeParameters.push(typeParameter);
|
||||
if (!tn.skip(Token.COMMA)) {
|
||||
if (tn.skip(Token.GREATERTHAN)) {
|
||||
break;
|
||||
@ -966,7 +967,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (typeParameters.length === 0) {
|
||||
if (!(typeParameters && typeParameters.length)) {
|
||||
this.error(
|
||||
DiagnosticCode.Type_parameter_list_cannot_be_empty,
|
||||
tn.range()
|
||||
@ -1437,9 +1438,14 @@ export class Parser extends DiagnosticEmitter {
|
||||
tn.range(signatureStart, tn.pos)
|
||||
);
|
||||
|
||||
var body: Statement | null;
|
||||
var body: Statement | null = null;
|
||||
if (arrowKind) {
|
||||
body = this.parseStatement(tn, false);
|
||||
if (tn.skip(Token.OPENBRACE)) {
|
||||
body = this.parseBlockStatement(tn, false);
|
||||
} else {
|
||||
let bodyExpression = this.parseExpression(tn, Precedence.COMMA + 1);
|
||||
if (bodyExpression) body = Node.createExpressionStatement(bodyExpression);
|
||||
}
|
||||
} else {
|
||||
if (!tn.skip(Token.OPENBRACE)) {
|
||||
this.error(
|
||||
@ -1527,8 +1533,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
let type = this.parseType(tn);
|
||||
if (!type) return null;
|
||||
if (!isInterface) {
|
||||
if (!implementsTypes) implementsTypes = [];
|
||||
implementsTypes.push(<TypeNode>type);
|
||||
if (!implementsTypes) implementsTypes = [<TypeNode>type];
|
||||
else implementsTypes.push(<TypeNode>type);
|
||||
}
|
||||
} while (tn.skip(Token.COMMA));
|
||||
}
|
||||
@ -1570,6 +1576,16 @@ export class Parser extends DiagnosticEmitter {
|
||||
do {
|
||||
let member = this.parseClassMember(tn, declaration);
|
||||
if (member) members.push(<DeclarationStatement>member);
|
||||
else {
|
||||
this.skipStatement(tn);
|
||||
if (tn.skip(Token.ENDOFFILE)) {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), "}"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} while (!tn.skip(Token.CLOSEBRACE));
|
||||
}
|
||||
return declaration;
|
||||
@ -1611,6 +1627,16 @@ export class Parser extends DiagnosticEmitter {
|
||||
do {
|
||||
let member = this.parseClassMember(tn, declaration);
|
||||
if (member) members.push(<DeclarationStatement>member);
|
||||
else {
|
||||
this.skipStatement(tn);
|
||||
if (tn.skip(Token.ENDOFFILE)) {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), "}"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
} while (!tn.skip(Token.CLOSEBRACE));
|
||||
}
|
||||
return Node.createClassExpression(declaration);
|
||||
@ -1631,14 +1657,15 @@ export class Parser extends DiagnosticEmitter {
|
||||
var startPos = tn.pos;
|
||||
var isInterface = parent.kind == NodeKind.INTERFACEDECLARATION;
|
||||
|
||||
var decorators = new Array<DecoratorNode>();
|
||||
var decorators: DecoratorNode[] | null = null;
|
||||
if (tn.skip(Token.AT)) {
|
||||
do {
|
||||
let decorator = this.parseDecorator(tn);
|
||||
if (!decorator) break;
|
||||
decorators.push(<DecoratorNode>decorator);
|
||||
if (!decorators) decorators = [<DecoratorNode>decorator];
|
||||
else decorators.push(<DecoratorNode>decorator);
|
||||
} while (tn.skip(Token.AT));
|
||||
if (isInterface) {
|
||||
if (decorators && isInterface) {
|
||||
this.error(
|
||||
DiagnosticCode.Decorators_are_not_valid_here,
|
||||
Range.join(decorators[0].range, decorators[decorators.length - 1].range)
|
||||
@ -2059,11 +2086,11 @@ export class Parser extends DiagnosticEmitter {
|
||||
return null;
|
||||
}
|
||||
|
||||
parseIndexSignatureDeclaration(tn: Tokenizer, decorators: DecoratorNode[]): IndexSignatureDeclaration | null {
|
||||
parseIndexSignatureDeclaration(tn: Tokenizer, decorators: DecoratorNode[] | null): IndexSignatureDeclaration | null {
|
||||
|
||||
// at: '[': 'key' ':' Type ']' ':' Type
|
||||
|
||||
if (decorators.length) {
|
||||
if (decorators && decorators.length) {
|
||||
this.error(
|
||||
DiagnosticCode.Decorators_are_not_valid_here,
|
||||
Range.join(decorators[0].range, decorators[decorators.length - 1].range)
|
||||
@ -2145,6 +2172,16 @@ export class Parser extends DiagnosticEmitter {
|
||||
while (!tn.skip(Token.CLOSEBRACE)) {
|
||||
let member = this.parseTopLevelStatement(tn, ns);
|
||||
if (member) members.push(member);
|
||||
else {
|
||||
this.skipStatement(tn);
|
||||
if (tn.skip(Token.ENDOFFILE)) {
|
||||
this.error(
|
||||
DiagnosticCode._0_expected,
|
||||
tn.range(), "}"
|
||||
);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
tn.skip(Token.SEMICOLON);
|
||||
return ns;
|
||||
@ -2175,9 +2212,9 @@ export class Parser extends DiagnosticEmitter {
|
||||
if (tn.skip(Token.OPENBRACE)) {
|
||||
let members = new Array<ExportMember>();
|
||||
while (!tn.skip(Token.CLOSEBRACE)) {
|
||||
let member = this.parseExportMember(tn);
|
||||
if (!member) return null;
|
||||
members.push(member);
|
||||
let member = this.parseExportMember(tn);
|
||||
if (!member) return null;
|
||||
members.push(member);
|
||||
if (!tn.skip(Token.COMMA)) {
|
||||
if (tn.skip(Token.CLOSEBRACE)) {
|
||||
break;
|
||||
@ -3405,7 +3442,7 @@ export class Parser extends DiagnosticEmitter {
|
||||
|
||||
var state = tn.mark();
|
||||
if (!tn.skip(Token.LESSTHAN)) return null;
|
||||
var typeArguments = new Array<CommonTypeNode>();
|
||||
var typeArguments: CommonTypeNode[] | null = null;
|
||||
do {
|
||||
if (tn.peek() === Token.GREATERTHAN) {
|
||||
break;
|
||||
@ -3415,7 +3452,8 @@ export class Parser extends DiagnosticEmitter {
|
||||
tn.reset(state);
|
||||
return null;
|
||||
}
|
||||
typeArguments.push(type);
|
||||
if (!typeArguments) typeArguments = [ type ];
|
||||
else typeArguments.push(type);
|
||||
} while (tn.skip(Token.COMMA));
|
||||
if (tn.skip(Token.GREATERTHAN) && tn.skip(Token.OPENPAREN)) {
|
||||
return typeArguments;
|
||||
@ -3712,6 +3750,10 @@ export class Parser extends DiagnosticEmitter {
|
||||
tn.readFloat();
|
||||
break;
|
||||
}
|
||||
case Token.OPENBRACE: {
|
||||
this.skipBlock(tn);
|
||||
break;
|
||||
}
|
||||
}
|
||||
} while (true);
|
||||
}
|
||||
|
@ -2355,6 +2355,9 @@ export class EnumValue extends VariableLikeElement {
|
||||
this.setType(Type.i32);
|
||||
}
|
||||
|
||||
/** Whether this enum value is immutable. */
|
||||
isImmutable: bool = false;
|
||||
|
||||
/** Gets the associated value node. */
|
||||
get valueNode(): Expression | null {
|
||||
return (<EnumValueDeclaration>this.declaration).value;
|
||||
|
25
src/types.ts
25
src/types.ts
@ -273,20 +273,20 @@ export class Type {
|
||||
return null;
|
||||
}
|
||||
|
||||
/** Converts this type to its TypeScript representation. */
|
||||
toString(kindOnly: bool = false): string {
|
||||
if (!kindOnly && this.is(TypeFlags.REFERENCE)) {
|
||||
/** Converts this type to a string. */
|
||||
toString(): string {
|
||||
if (this.is(TypeFlags.REFERENCE)) {
|
||||
let classReference = this.classReference;
|
||||
if (classReference) {
|
||||
return this.is(TypeFlags.NULLABLE)
|
||||
? classReference.name + " | null"
|
||||
: classReference.name;
|
||||
? classReference.internalName + " | null"
|
||||
: classReference.internalName;
|
||||
}
|
||||
let signatureReference = this.signatureReference;
|
||||
if (signatureReference) {
|
||||
return this.is(TypeFlags.NULLABLE)
|
||||
? "(" + signatureReference.toString(true) + ") | null"
|
||||
: signatureReference.toString(true);
|
||||
? "(" + signatureReference.toString() + ") | null"
|
||||
: signatureReference.toString();
|
||||
}
|
||||
assert(false);
|
||||
}
|
||||
@ -644,17 +644,16 @@ export class Signature {
|
||||
}
|
||||
|
||||
/** Converts this signature to a string. */
|
||||
toString(includeThis: bool = false): string {
|
||||
toString(): string {
|
||||
var sb = new Array<string>();
|
||||
sb.push("(");
|
||||
var index = 0;
|
||||
var thisType = this.thisType;
|
||||
if (thisType) {
|
||||
if (includeThis) {
|
||||
sb.push("this: ");
|
||||
sb.push(thisType.toString());
|
||||
index = 1;
|
||||
}
|
||||
sb.push("this: ");
|
||||
assert(!thisType.signatureReference);
|
||||
sb.push(thisType.toString());
|
||||
index = 1;
|
||||
}
|
||||
var parameters = this.parameterTypes;
|
||||
var numParameters = parameters.length;
|
||||
|
Reference in New Issue
Block a user