Skip to content

Commit a001103

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

File tree

8 files changed

+74
-4
lines changed

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)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy