mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-26 07:22:21 +00:00
Fix some array function parsing and serialization issues
Quite similar to #256 and also uses its test, but also fixes the serializer and doesn't try to parse an untyped 'x => x'.
This commit is contained in:
parent
59e2a63b83
commit
63d4579118
4
dist/assemblyscript.js
vendored
4
dist/assemblyscript.js
vendored
File diff suppressed because one or more lines are too long
2
dist/assemblyscript.js.map
vendored
2
dist/assemblyscript.js.map
vendored
File diff suppressed because one or more lines are too long
@ -117,7 +117,8 @@ export function nodeIsCallable(kind: NodeKind): bool {
|
|||||||
case NodeKind.IDENTIFIER:
|
case NodeKind.IDENTIFIER:
|
||||||
case NodeKind.CALL:
|
case NodeKind.CALL:
|
||||||
case NodeKind.ELEMENTACCESS:
|
case NodeKind.ELEMENTACCESS:
|
||||||
case NodeKind.PROPERTYACCESS: return true;
|
case NodeKind.PROPERTYACCESS:
|
||||||
|
case NodeKind.PARENTHESIZED: return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
@ -353,7 +353,8 @@ export class ASTBuilder {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
var typeNode = <TypeNode>node;
|
var typeNode = <TypeNode>node;
|
||||||
this.visitIdentifierExpression(<IdentifierExpression>typeNode.name);
|
assert(typeNode.name.text.length);
|
||||||
|
this.visitIdentifierExpression(typeNode.name);
|
||||||
var typeArguments = typeNode.typeArguments;
|
var typeArguments = typeNode.typeArguments;
|
||||||
if (typeArguments) {
|
if (typeArguments) {
|
||||||
let numTypeArguments = typeArguments.length;
|
let numTypeArguments = typeArguments.length;
|
||||||
@ -1081,22 +1082,24 @@ export class ASTBuilder {
|
|||||||
var returnType = signature.returnType;
|
var returnType = signature.returnType;
|
||||||
if (node.is(CommonFlags.ARROW)) {
|
if (node.is(CommonFlags.ARROW)) {
|
||||||
if (body) {
|
if (body) {
|
||||||
if (returnType) {
|
if (isTypeOmitted(returnType)) {
|
||||||
|
sb.push(")");
|
||||||
|
} else {
|
||||||
sb.push("): ");
|
sb.push("): ");
|
||||||
this.visitTypeNode(returnType);
|
this.visitTypeNode(returnType);
|
||||||
}
|
}
|
||||||
sb.push(" => ");
|
sb.push(" => ");
|
||||||
this.visitNode(body);
|
this.visitNode(body);
|
||||||
} else {
|
} else {
|
||||||
if (returnType) {
|
assert(!isTypeOmitted(returnType));
|
||||||
sb.push(" => ");
|
sb.push(" => ");
|
||||||
this.visitTypeNode(returnType);
|
this.visitTypeNode(returnType);
|
||||||
} else {
|
|
||||||
sb.push(" => void");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if (returnType && !node.isAny(CommonFlags.CONSTRUCTOR | CommonFlags.SET)) {
|
if (
|
||||||
|
!isTypeOmitted(returnType) &&
|
||||||
|
!node.isAny(CommonFlags.CONSTRUCTOR | CommonFlags.SET)
|
||||||
|
) {
|
||||||
sb.push("): ");
|
sb.push("): ");
|
||||||
this.visitTypeNode(returnType);
|
this.visitTypeNode(returnType);
|
||||||
} else {
|
} else {
|
||||||
@ -1454,13 +1457,12 @@ export class ASTBuilder {
|
|||||||
var type = node.type;
|
var type = node.type;
|
||||||
var initializer = node.initializer;
|
var initializer = node.initializer;
|
||||||
if (type) {
|
if (type) {
|
||||||
if (kind == ParameterKind.OPTIONAL && !initializer) {
|
if (kind == ParameterKind.OPTIONAL) sb.push("?");
|
||||||
sb.push("?: ");
|
if (!isTypeOmitted(type)) {
|
||||||
} else {
|
|
||||||
sb.push(": ");
|
sb.push(": ");
|
||||||
}
|
|
||||||
this.visitTypeNode(type);
|
this.visitTypeNode(type);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
if (initializer) {
|
if (initializer) {
|
||||||
sb.push(" = ");
|
sb.push(" = ");
|
||||||
this.visitNode(initializer);
|
this.visitNode(initializer);
|
||||||
@ -1503,3 +1505,7 @@ export class ASTBuilder {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function isTypeOmitted(type: CommonTypeNode): bool {
|
||||||
|
return type.kind == NodeKind.TYPE && !changetype<TypeNode>(type).name.text.length;
|
||||||
|
}
|
||||||
|
@ -2993,7 +2993,10 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
|
|
||||||
// if we got here, check for arrow
|
// if we got here, check for arrow
|
||||||
case Token.CLOSEPAREN: {
|
case Token.CLOSEPAREN: {
|
||||||
if (!tn.skip(Token.EQUALS_GREATERTHAN)) {
|
if (
|
||||||
|
!tn.skip(Token.COLON) &&
|
||||||
|
!tn.skip(Token.EQUALS_GREATERTHAN)
|
||||||
|
) {
|
||||||
again = false;
|
again = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -3004,8 +3007,19 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
tn.reset(state);
|
tn.reset(state);
|
||||||
return this.parseFunctionExpression(tn);
|
return this.parseFunctionExpression(tn);
|
||||||
}
|
}
|
||||||
// can be both
|
// optional parameter or parenthesized
|
||||||
case Token.QUESTION: // optional parameter or ternary
|
case Token.QUESTION: {
|
||||||
|
if (
|
||||||
|
tn.skip(Token.COLON) || // optional parameter with type
|
||||||
|
tn.skip(Token.COMMA) || // optional parameter without type
|
||||||
|
tn.skip(Token.CLOSEPAREN) // last optional parameter without type
|
||||||
|
) {
|
||||||
|
tn.reset(state);
|
||||||
|
return this.parseFunctionExpression(tn);
|
||||||
|
}
|
||||||
|
again = false; // parenthesized
|
||||||
|
break;
|
||||||
|
}
|
||||||
case Token.COMMA: {
|
case Token.COMMA: {
|
||||||
break; // continue
|
break; // continue
|
||||||
}
|
}
|
||||||
|
10
tests/parser/arrow-functions.ts
Normal file
10
tests/parser/arrow-functions.ts
Normal file
@ -0,0 +1,10 @@
|
|||||||
|
// array function
|
||||||
|
(x): i32 => x;
|
||||||
|
(x: i32) => x;
|
||||||
|
(x?) => x;
|
||||||
|
(x?, y?) => x;
|
||||||
|
(x?: i32) => x;
|
||||||
|
|
||||||
|
// not an array function
|
||||||
|
(b ? x : y);
|
||||||
|
(b ? f : g)();
|
11
tests/parser/arrow-functions.ts.fixture.ts
Normal file
11
tests/parser/arrow-functions.ts.fixture.ts
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
(x): i32 => x;
|
||||||
|
(x: i32) => x;
|
||||||
|
(x?) => x;
|
||||||
|
(x?, y?) => x;
|
||||||
|
(x?: i32) => x;
|
||||||
|
(b ? x : y);
|
||||||
|
(b ? f : g)();
|
||||||
|
// ERROR 1110: "Type expected." in arrow-functions.ts:3:8
|
||||||
|
// ERROR 1110: "Type expected." in arrow-functions.ts:4:4
|
||||||
|
// ERROR 1110: "Type expected." in arrow-functions.ts:5:8
|
||||||
|
// ERROR 1110: "Type expected." in arrow-functions.ts:6:9
|
@ -9,8 +9,8 @@ export class Valid<T> {
|
|||||||
}
|
}
|
||||||
export class Invalid<T> {
|
export class Invalid<T> {
|
||||||
constructor<T>() {}
|
constructor<T>() {}
|
||||||
instanceFunction(): {}
|
instanceFunction() {}
|
||||||
get instanceGetter<T>(a: i32): {}
|
get instanceGetter<T>(a: i32) {}
|
||||||
set instanceSetter<T>() {}
|
set instanceSetter<T>() {}
|
||||||
}
|
}
|
||||||
// ERROR 1092: "Type parameters cannot appear on a constructor declaration." in class.ts:13:13
|
// ERROR 1092: "Type parameters cannot appear on a constructor declaration." in class.ts:13:13
|
||||||
|
@ -4,5 +4,5 @@ class MyClass {
|
|||||||
constructor(a: i32, b: i32) {}
|
constructor(a: i32, b: i32) {}
|
||||||
}
|
}
|
||||||
class MyClassImplicit {
|
class MyClassImplicit {
|
||||||
constructor(public a: i32, private readonly b: i32 = 2, c: i32 = 3) {}
|
constructor(public a: i32, private readonly b?: i32 = 2, c?: i32 = 3) {}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
function simple(): void {}
|
function simple(): void {}
|
||||||
function typeparams<T, V extends T>(a: V | null = null): void {}
|
function typeparams<T, V extends T>(a?: V | null = null): void {}
|
||||||
@decorator()
|
@decorator()
|
||||||
function withdecorator(): void {}
|
function withdecorator(): void {}
|
||||||
function withthis(this: i32): i32 {
|
function withthis(this: i32): i32 {
|
||||||
|
@ -2,7 +2,7 @@ function restValid(a: i32, ...b: Array<i32>): void {}
|
|||||||
function optionalValid(a: i32, b?: i32): void {}
|
function optionalValid(a: i32, b?: i32): void {}
|
||||||
function restParameterMustBeLast(...a: Array<i32>, b: i32): void {}
|
function restParameterMustBeLast(...a: Array<i32>, b: i32): void {}
|
||||||
function optionalCannotPrecedeRequired(a?: i32, b: i32): void {}
|
function optionalCannotPrecedeRequired(a?: i32, b: i32): void {}
|
||||||
function optionalWithInitializerCannotPrecedeRequired(a: i32 = 1, b: i32): void {}
|
function optionalWithInitializerCannotPrecedeRequired(a?: i32 = 1, b: i32): void {}
|
||||||
// ERROR 1014: "A rest parameter must be last in a parameter list." in parameter-order.ts:5:36
|
// ERROR 1014: "A rest parameter must be last in a parameter list." in parameter-order.ts:5:36
|
||||||
// ERROR 1016: "A required parameter cannot follow an optional parameter." in parameter-order.ts:8:48
|
// ERROR 1016: "A required parameter cannot follow an optional parameter." in parameter-order.ts:8:48
|
||||||
// ERROR 1016: "A required parameter cannot follow an optional parameter." in parameter-order.ts:11:66
|
// ERROR 1016: "A required parameter cannot follow an optional parameter." in parameter-order.ts:11:66
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
@binding(BindingCall.NEW, [BindingType.STRING], BindingType.OBJECT_HANDLE)
|
@binding(BindingCall.NEW, [BindingType.STRING], BindingType.OBJECT_HANDLE)
|
||||||
export class ExternalString {
|
export class ExternalString {
|
||||||
@binding(BindingCall.FUNCTION, [BindingType.U32, BindingType.U32], BindingType.OBJECT_HANDLE)
|
@binding(BindingCall.FUNCTION, [BindingType.U32, BindingType.U32], BindingType.OBJECT_HANDLE)
|
||||||
static fromCharCode(char: u16, schar: u16 = <u16>-1): String {
|
static fromCharCode(char: u16, schar?: u16 = <u16>-1): String {
|
||||||
return unreachable();
|
return unreachable();
|
||||||
}
|
}
|
||||||
@binding(BindingCall.FUNCTION, [BindingType.U32], BindingType.OBJECT_HANDLE)
|
@binding(BindingCall.FUNCTION, [BindingType.U32], BindingType.OBJECT_HANDLE)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user