Skip to content

Commit 63d4579

Browse files
committed
Fix some array function parsing and serialization issues
Quite similar to AssemblyScript#256 and also uses its test, but also fixes the serializer and doesn't try to parse an untyped 'x => x'.
1 parent 59e2a63 commit 63d4579

12 files changed

+68
-26
lines changed

dist/assemblyscript.js

Lines changed: 2 additions & 2 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

dist/assemblyscript.js.map

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/ast.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,8 @@ export function nodeIsCallable(kind: NodeKind): bool {
117117
case NodeKind.IDENTIFIER:
118118
case NodeKind.CALL:
119119
case NodeKind.ELEMENTACCESS:
120-
case NodeKind.PROPERTYACCESS: return true;
120+
case NodeKind.PROPERTYACCESS:
121+
case NodeKind.PARENTHESIZED: return true;
121122
}
122123
return false;
123124
}

src/extra/ast.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -353,7 +353,8 @@ export class ASTBuilder {
353353
return;
354354
}
355355
var typeNode = <TypeNode>node;
356-
this.visitIdentifierExpression(<IdentifierExpression>typeNode.name);
356+
assert(typeNode.name.text.length);
357+
this.visitIdentifierExpression(typeNode.name);
357358
var typeArguments = typeNode.typeArguments;
358359
if (typeArguments) {
359360
let numTypeArguments = typeArguments.length;
@@ -1081,22 +1082,24 @@ export class ASTBuilder {
10811082
var returnType = signature.returnType;
10821083
if (node.is(CommonFlags.ARROW)) {
10831084
if (body) {
1084-
if (returnType) {
1085+
if (isTypeOmitted(returnType)) {
1086+
sb.push(")");
1087+
} else {
10851088
sb.push("): ");
10861089
this.visitTypeNode(returnType);
10871090
}
10881091
sb.push(" => ");
10891092
this.visitNode(body);
10901093
} else {
1091-
if (returnType) {
1092-
sb.push(" => ");
1093-
this.visitTypeNode(returnType);
1094-
} else {
1095-
sb.push(" => void");
1096-
}
1094+
assert(!isTypeOmitted(returnType));
1095+
sb.push(" => ");
1096+
this.visitTypeNode(returnType);
10971097
}
10981098
} else {
1099-
if (returnType && !node.isAny(CommonFlags.CONSTRUCTOR | CommonFlags.SET)) {
1099+
if (
1100+
!isTypeOmitted(returnType) &&
1101+
!node.isAny(CommonFlags.CONSTRUCTOR | CommonFlags.SET)
1102+
) {
11001103
sb.push("): ");
11011104
this.visitTypeNode(returnType);
11021105
} else {
@@ -1454,12 +1457,11 @@ export class ASTBuilder {
14541457
var type = node.type;
14551458
var initializer = node.initializer;
14561459
if (type) {
1457-
if (kind == ParameterKind.OPTIONAL && !initializer) {
1458-
sb.push("?: ");
1459-
} else {
1460+
if (kind == ParameterKind.OPTIONAL) sb.push("?");
1461+
if (!isTypeOmitted(type)) {
14601462
sb.push(": ");
1463+
this.visitTypeNode(type);
14611464
}
1462-
this.visitTypeNode(type);
14631465
}
14641466
if (initializer) {
14651467
sb.push(" = ");
@@ -1503,3 +1505,7 @@ export class ASTBuilder {
15031505
return ret;
15041506
}
15051507
}
1508+
1509+
function isTypeOmitted(type: CommonTypeNode): bool {
1510+
return type.kind == NodeKind.TYPE && !changetype<TypeNode>(type).name.text.length;
1511+
}

src/parser.ts

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2993,7 +2993,10 @@ export class Parser extends DiagnosticEmitter {
29932993

29942994
// if we got here, check for arrow
29952995
case Token.CLOSEPAREN: {
2996-
if (!tn.skip(Token.EQUALS_GREATERTHAN)) {
2996+
if (
2997+
!tn.skip(Token.COLON) &&
2998+
!tn.skip(Token.EQUALS_GREATERTHAN)
2999+
) {
29973000
again = false;
29983001
break;
29993002
}
@@ -3004,8 +3007,19 @@ export class Parser extends DiagnosticEmitter {
30043007
tn.reset(state);
30053008
return this.parseFunctionExpression(tn);
30063009
}
3007-
// can be both
3008-
case Token.QUESTION: // optional parameter or ternary
3010+
// optional parameter or parenthesized
3011+
case Token.QUESTION: {
3012+
if (
3013+
tn.skip(Token.COLON) || // optional parameter with type
3014+
tn.skip(Token.COMMA) || // optional parameter without type
3015+
tn.skip(Token.CLOSEPAREN) // last optional parameter without type
3016+
) {
3017+
tn.reset(state);
3018+
return this.parseFunctionExpression(tn);
3019+
}
3020+
again = false; // parenthesized
3021+
break;
3022+
}
30093023
case Token.COMMA: {
30103024
break; // continue
30113025
}

tests/parser/arrow-functions.ts

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// array function
2+
(x): i32 => x;
3+
(x: i32) => x;
4+
(x?) => x;
5+
(x?, y?) => x;
6+
(x?: i32) => x;
7+
8+
// not an array function
9+
(b ? x : y);
10+
(b ? f : g)();
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
(x): i32 => x;
2+
(x: i32) => x;
3+
(x?) => x;
4+
(x?, y?) => x;
5+
(x?: i32) => x;
6+
(b ? x : y);
7+
(b ? f : g)();
8+
// ERROR 1110: "Type expected." in arrow-functions.ts:3:8
9+
// ERROR 1110: "Type expected." in arrow-functions.ts:4:4
10+
// ERROR 1110: "Type expected." in arrow-functions.ts:5:8
11+
// ERROR 1110: "Type expected." in arrow-functions.ts:6:9

tests/parser/class.ts.fixture.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,8 @@ export class Valid<T> {
99
}
1010
export class Invalid<T> {
1111
constructor<T>() {}
12-
instanceFunction(): {}
13-
get instanceGetter<T>(a: i32): {}
12+
instanceFunction() {}
13+
get instanceGetter<T>(a: i32) {}
1414
set instanceSetter<T>() {}
1515
}
1616
// ERROR 1092: "Type parameters cannot appear on a constructor declaration." in class.ts:13:13

tests/parser/constructor.ts.fixture.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@ class MyClass {
44
constructor(a: i32, b: i32) {}
55
}
66
class MyClassImplicit {
7-
constructor(public a: i32, private readonly b: i32 = 2, c: i32 = 3) {}
7+
constructor(public a: i32, private readonly b?: i32 = 2, c?: i32 = 3) {}
88
}

tests/parser/function.ts.fixture.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
function simple(): void {}
2-
function typeparams<T, V extends T>(a: V | null = null): void {}
2+
function typeparams<T, V extends T>(a?: V | null = null): void {}
33
@decorator()
44
function withdecorator(): void {}
55
function withthis(this: i32): i32 {

0 commit comments

Comments
 (0)