Merge branch 'master' into runtime

This commit is contained in:
dcode
2019-03-27 16:10:59 +01:00
69 changed files with 15243 additions and 10507 deletions

View File

@ -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;

View File

@ -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;

View File

@ -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);
}

View File

@ -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;

View File

@ -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;