Skip to content

Commit a001103

Browse files
authored
Add class-level declare to parser (AssemblyScript#2160)
1 parent 049a6a6 commit a001103

8 files changed

+74
-4
lines changed

src/diagnosticMessages.generated.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@ export enum DiagnosticCode {
6565
A_rest_parameter_must_be_last_in_a_parameter_list = 1014,
6666
Parameter_cannot_have_question_mark_and_initializer = 1015,
6767
A_required_parameter_cannot_follow_an_optional_parameter = 1016,
68+
_0_modifier_cannot_appear_on_class_elements_of_this_kind = 1031,
6869
Statements_are_not_allowed_in_ambient_contexts = 1036,
6970
Initializers_are_not_allowed_in_ambient_contexts = 1039,
7071
_0_modifier_cannot_be_used_here = 1042,
@@ -249,6 +250,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
249250
case 1014: return "A rest parameter must be last in a parameter list.";
250251
case 1015: return "Parameter cannot have question mark and initializer.";
251252
case 1016: return "A required parameter cannot follow an optional parameter.";
253+
case 1031: return "'{0}' modifier cannot appear on class elements of this kind.";
252254
case 1036: return "Statements are not allowed in ambient contexts.";
253255
case 1039: return "Initializers are not allowed in ambient contexts.";
254256
case 1042: return "'{0}' modifier cannot be used here.";

src/diagnosticMessages.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,7 @@
6262
"A rest parameter must be last in a parameter list.": 1014,
6363
"Parameter cannot have question mark and initializer.": 1015,
6464
"A required parameter cannot follow an optional parameter.": 1016,
65+
"'{0}' modifier cannot appear on class elements of this kind.": 1031,
6566
"Statements are not allowed in ambient contexts.": 1036,
6667
"Initializers are not allowed in ambient contexts.": 1039,
6768
"'{0}' modifier cannot be used here.": 1042,

src/extra/ast.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,6 +1677,9 @@ export class ASTBuilder {
16771677

16781678
serializeAccessModifiers(node: DeclarationStatement): void {
16791679
var sb = this.sb;
1680+
if (node.is(CommonFlags.DECLARE)) {
1681+
sb.push("declare ");
1682+
}
16801683
if (node.is(CommonFlags.PUBLIC)) {
16811684
sb.push("public ");
16821685
} else if (node.is(CommonFlags.PRIVATE)) {

src/parser.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1839,6 +1839,7 @@ export class Parser extends DiagnosticEmitter {
18391839
): Node | null {
18401840

18411841
// before:
1842+
// 'declare'?
18421843
// ('public' | 'private' | 'protected')?
18431844
// ('static' | 'abstract')?
18441845
// 'readonly'?
@@ -1870,6 +1871,32 @@ export class Parser extends DiagnosticEmitter {
18701871
// implemented methods are virtual
18711872
if (isInterface) flags |= CommonFlags.VIRTUAL;
18721873

1874+
var declareStart = 0;
1875+
var declareEnd = 0;
1876+
var contextIsAmbient = parent.is(CommonFlags.AMBIENT);
1877+
if (tn.skip(Token.DECLARE)) {
1878+
if (isInterface) {
1879+
this.error(
1880+
DiagnosticCode._0_modifier_cannot_be_used_here,
1881+
tn.range(), "declare"
1882+
);
1883+
} else {
1884+
if (contextIsAmbient) {
1885+
this.error(
1886+
DiagnosticCode.A_declare_modifier_cannot_be_used_in_an_already_ambient_context,
1887+
tn.range()
1888+
); // recoverable
1889+
} else {
1890+
flags |= CommonFlags.DECLARE | CommonFlags.AMBIENT;
1891+
declareStart = tn.tokenPos;
1892+
declareEnd = tn.pos;
1893+
}
1894+
}
1895+
if (!startPos) startPos = tn.tokenPos;
1896+
} else if (contextIsAmbient) {
1897+
flags |= CommonFlags.AMBIENT;
1898+
}
1899+
18731900
var accessStart = 0;
18741901
var accessEnd = 0;
18751902
if (tn.skip(Token.PUBLIC)) {
@@ -2108,6 +2135,13 @@ export class Parser extends DiagnosticEmitter {
21082135

21092136
// method: '(' Parameters (':' Type)? '{' Statement* '}' ';'?
21102137
if (tn.skip(Token.OPENPAREN)) {
2138+
if (flags & CommonFlags.DECLARE) {
2139+
this.error(
2140+
DiagnosticCode._0_modifier_cannot_appear_on_class_elements_of_this_kind,
2141+
tn.range(declareStart, declareEnd), "declare"
2142+
); // recoverable
2143+
}
2144+
21112145
let signatureStart = tn.tokenPos;
21122146
let parameters = this.parseParameters(tn, isConstructor);
21132147
if (!parameters) return null;
@@ -2249,6 +2283,13 @@ export class Parser extends DiagnosticEmitter {
22492283

22502284
// field: (':' Type)? ('=' Expression)? ';'?
22512285
} else {
2286+
if (flags & CommonFlags.DECLARE) {
2287+
this.error(
2288+
DiagnosticCode.Not_implemented_0,
2289+
tn.range(declareStart, declareEnd), "Ambient fields"
2290+
); // recoverable
2291+
}
2292+
22522293
if (flags & CommonFlags.ABSTRACT) {
22532294
this.error(
22542295
DiagnosticCode._0_modifier_cannot_be_used_here,
@@ -2291,6 +2332,12 @@ export class Parser extends DiagnosticEmitter {
22912332
}
22922333
let initializer: Expression | null = null;
22932334
if (tn.skip(Token.EQUALS)) {
2335+
if (flags & CommonFlags.AMBIENT) {
2336+
this.error(
2337+
DiagnosticCode.Initializers_are_not_allowed_in_ambient_contexts,
2338+
tn.range()
2339+
); // recoverable
2340+
}
22942341
initializer = this.parseExpression(tn);
22952342
if (!initializer) return null;
22962343
}

tests/parser/also-identifier.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
class Foo {
22
as: i32;
3-
declare: i32;
3+
//declare: i32;
44
delete: i32;
55
from: i32;
66
for: i32;
@@ -19,7 +19,7 @@ class Foo {
1919

2020
var as: i32;
2121
var constructor: i32;
22-
var declare: i32;
22+
//var declare: i32;
2323
var from: i32;
2424
var get: i32;
2525
var is: i32;

tests/parser/also-identifier.ts.fixture.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
class Foo {
22
as: i32;
3-
declare: i32;
43
delete: i32;
54
from: i32;
65
for: i32;
@@ -18,7 +17,6 @@ class Foo {
1817
}
1918
var as: i32;
2019
var constructor: i32;
21-
var declare: i32;
2220
var from: i32;
2321
var get: i32;
2422
var is: i32;

tests/parser/class.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,4 +26,15 @@ export class Invalid<T> {
2626
// 1049: A 'set' accessor must have exactly one parameter.
2727
// 1095: A 'set' accessor cannot have a return type annotation.
2828
set instanceSetter<T>(): i32 {}
29+
30+
// 100: Not implemented: Ambient fields
31+
declare declareField: i32;
32+
33+
// 100: Not implemented: Ambient fields
34+
// 1039: Initializers are not allowed in ambient contexts.
35+
declare declareInitializer: i32 = 0;
36+
37+
// 1031: 'declare' modifier cannot appear on class elements of this kind.
38+
// 1183: An implementation cannot be declared in ambient contexts.
39+
declare declareMethod(): i32 {}
2940
}

tests/parser/class.ts.fixture.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,9 @@ export class Invalid<T> {
1414
instanceFunction() {}
1515
get instanceGetter<T>(a: i32) {}
1616
set instanceSetter<T>() {}
17+
declare declareField: i32;
18+
declare declareInitializer: i32 = 0;
19+
declare declareMethod(): i32 {}
1720
}
1821
// ERROR 1092: "Type parameters cannot appear on a constructor declaration." in class.ts(15,14+3)
1922
// ERROR 1110: "Type expected." in class.ts(18,21+0)
@@ -23,3 +26,8 @@ export class Invalid<T> {
2326
// ERROR 1094: "An accessor cannot have type parameters." in class.ts(28,21+3)
2427
// ERROR 1049: "A 'set' accessor must have exactly one parameter." in class.ts(28,7+14)
2528
// ERROR 1095: "A 'set' accessor cannot have a return type annotation." in class.ts(28,26+1)
29+
// ERROR 100: "Not implemented: Ambient fields" in class.ts(31,3+7)
30+
// ERROR 100: "Not implemented: Ambient fields" in class.ts(35,3+7)
31+
// ERROR 1039: "Initializers are not allowed in ambient contexts." in class.ts(35,35+1)
32+
// ERROR 1031: "'declare' modifier cannot appear on class elements of this kind." in class.ts(39,3+7)
33+
// ERROR 1183: "An implementation cannot be declared in ambient contexts." in class.ts(39,32+1)

0 commit comments

Comments
 (0)