Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 451dd4d

Browse files
authored
Print better errors for unusual void, null and undefined types (#1303)
1 parent 47e42b5 commit 451dd4d

File tree

8 files changed

+75
-49
lines changed

8 files changed

+75
-49
lines changed

‎src/diagnosticMessages.generated.ts‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ export enum DiagnosticCode {
2020
Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit = 201,
2121
Type_0_cannot_be_changed_to_type_1 = 202,
2222
Operation_0_cannot_be_applied_to_type_1 = 203,
23-
Basic_type_0_cannot_be_nullable = 204,
23+
Type_0_cannot_be_nullable = 204,
2424
Cannot_export_a_mutable_global = 205,
2525
Mutable_value_cannot_be_inlined = 206,
2626
Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207,
@@ -193,7 +193,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
193193
case 201: return "Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.";
194194
case 202: return "Type '{0}' cannot be changed to type '{1}'.";
195195
case 203: return "Operation '{0}' cannot be applied to type '{1}'.";
196-
case 204: return "Basic type '{0}' cannot be nullable.";
196+
case 204: return "Type '{0}' cannot be nullable.";
197197
case 205: return "Cannot export a mutable global.";
198198
case 206: return "Mutable value cannot be inlined.";
199199
case 207: return "Unmanaged classes cannot extend managed classes and vice-versa.";

‎src/diagnosticMessages.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
"Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.": 201,
1414
"Type '{0}' cannot be changed to type '{1}'.": 202,
1515
"Operation '{0}' cannot be applied to type '{1}'.": 203,
16-
"Basic type '{0}' cannot be nullable.": 204,
16+
"Type '{0}' cannot be nullable.": 204,
1717
"Cannot export a mutable global.": 205,
1818
"Mutable value cannot be inlined.": 206,
1919
"Unmanaged classes cannot extend managed classes and vice-versa.": 207,

‎src/parser.ts‎

Lines changed: 29 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,11 @@ export class Parser extends DiagnosticEmitter {
155155
var statements = source.statements;
156156
while (!tn.skip(Token.ENDOFFILE)) {
157157
let statement = this.parseTopLevelStatement(tn, null);
158-
if (statement) statements.push(statement);
158+
if (statement) {
159+
statements.push(statement);
160+
} else {
161+
this.skipStatement(tn);
162+
}
159163
}
160164
}
161165

@@ -538,6 +542,12 @@ export class Parser extends DiagnosticEmitter {
538542
Node.createSimpleTypeName("bool", tn.range()), [], false, tn.range(startPos, tn.pos)
539543
);
540544

545+
// 'null'
546+
} else if (token == Token.NULL) {
547+
type = Node.createNamedType(
548+
Node.createSimpleTypeName("null", tn.range()), [], false, tn.range(startPos, tn.pos)
549+
);
550+
541551
// StringLiteral
542552
} else if (token == Token.STRINGLITERAL) {
543553
tn.readString();
@@ -550,7 +560,6 @@ export class Parser extends DiagnosticEmitter {
550560
let name = this.parseTypeName(tn);
551561
if (!name) return null;
552562
let parameters: TypeNode[] | null = null;
553-
let nullable = false;
554563

555564
// Name<T>
556565
if (tn.skip(Token.LESSTHAN)) {
@@ -570,31 +579,33 @@ export class Parser extends DiagnosticEmitter {
570579
return null;
571580
}
572581
}
573-
// ... | null
574-
while (tn.skip(Token.BAR)) {
575-
if (tn.skip(Token.NULL)) {
576-
nullable = true;
577-
} else {
578-
if (!suppressErrors) {
579-
this.error(
580-
DiagnosticCode._0_expected,
581-
tn.range(tn.pos), "null"
582-
);
583-
}
584-
return null;
585-
}
586-
}
587582
if (!parameters) parameters = [];
588-
type = Node.createNamedType(name, parameters, nullable, tn.range(startPos, tn.pos));
583+
type = Node.createNamedType(name, parameters, false, tn.range(startPos, tn.pos));
589584
} else {
590585
if (!suppressErrors) {
591586
this.error(
592-
DiagnosticCode.Identifier_expected,
587+
DiagnosticCode.Type_expected,
593588
tn.range()
594589
);
595590
}
596591
return null;
597592
}
593+
// ... | null
594+
while (tn.skip(Token.BAR)) {
595+
if (tn.skip(Token.NULL)) {
596+
type.isNullable = true;
597+
} else {
598+
let notNullStart = tn.pos;
599+
let notNull = this.parseType(tn, false, true);
600+
if (!suppressErrors) {
601+
this.error(
602+
DiagnosticCode._0_expected,
603+
notNull ? notNull.range : tn.range(notNullStart), "null"
604+
);
605+
}
606+
return null;
607+
}
608+
}
598609
// ... [][]
599610
while (tn.skip(Token.OPENBRACKET)) {
600611
let bracketStart = tn.tokenPos;

‎src/resolver.ts‎

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ export class Resolver extends DiagnosticEmitter {
205205
if (type.is(TypeFlags.REFERENCE)) return type.asNullable();
206206
if (reportMode == ReportMode.REPORT) {
207207
this.error(
208-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
208+
DiagnosticCode.Type_0_cannot_be_nullable,
209209
node.range, type.toString()
210210
);
211211
}
@@ -238,7 +238,7 @@ export class Resolver extends DiagnosticEmitter {
238238
if (node.isNullable) {
239239
if (reportMode == ReportMode.REPORT) {
240240
this.error(
241-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
241+
DiagnosticCode.Type_0_cannot_be_nullable,
242242
node.range, element.name + "/i32"
243243
);
244244
}
@@ -283,7 +283,7 @@ export class Resolver extends DiagnosticEmitter {
283283
if (!type.is(TypeFlags.REFERENCE)) {
284284
if (reportMode == ReportMode.REPORT) {
285285
this.error(
286-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
286+
DiagnosticCode.Type_0_cannot_be_nullable,
287287
nameNode.range, nameNode.identifier.text
288288
);
289289
}
@@ -333,7 +333,7 @@ export class Resolver extends DiagnosticEmitter {
333333
if (!type.is(TypeFlags.REFERENCE)) {
334334
if (reportMode == ReportMode.REPORT) {
335335
this.error(
336-
DiagnosticCode.Basic_type_0_cannot_be_nullable,
336+
DiagnosticCode.Type_0_cannot_be_nullable,
337337
nameNode.range, nameNode.identifier.text
338338
);
339339
}
@@ -2716,6 +2716,15 @@ export class Resolver extends DiagnosticEmitter {
27162716
reportMode
27172717
);
27182718
if (!parameterType) return null;
2719+
if (parameterType == Type.void) {
2720+
if (reportMode == ReportMode.REPORT) {
2721+
this.error(
2722+
DiagnosticCode.Type_expected,
2723+
typeNode.range
2724+
);
2725+
}
2726+
return null;
2727+
}
27192728
parameterTypes[i] = parameterType;
27202729
parameterNames[i] = parameterDeclaration.name.text;
27212730
}
@@ -3078,6 +3087,15 @@ export class Resolver extends DiagnosticEmitter {
30783087
instance.contextualTypeArguments,
30793088
reportMode
30803089
);
3090+
if (fieldType == Type.void) {
3091+
if (reportMode == ReportMode.REPORT) {
3092+
this.error(
3093+
DiagnosticCode.Type_expected,
3094+
fieldTypeNode.range
3095+
);
3096+
}
3097+
break;
3098+
}
30813099
}
30823100
if (!fieldType) break; // did report above
30833101
let fieldInstance = new Field(fieldPrototype, instance, fieldType);

‎std/assembly/builtins.ts‎

Lines changed: 20 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
type auto = i32;
2+
13
// @ts-ignore: decorator
24
@builtin
35
export declare function isInteger<T>(value?: T): bool;
@@ -40,11 +42,11 @@ export declare function isNullable<T>(value?: T): bool;
4042

4143
// @ts-ignore: decorator
4244
@builtin
43-
export declare function isDefined(expression: void): bool;
45+
export declare function isDefined(expression: auto): bool;
4446

4547
// @ts-ignore: decorator
4648
@builtin
47-
export declare function isConstant(expression: void): bool;
49+
export declare function isConstant(expression: auto): bool;
4850

4951
// @ts-ignore: decorator
5052
@builtin
@@ -124,7 +126,7 @@ export declare function load<T>(ptr: usize, immOffset?: usize, immAlign?: usize)
124126

125127
// @ts-ignore: decorator
126128
@unsafe @builtin
127-
export declare function store<T>(ptr: usize, value: void, immOffset?: usize, immAlign?: usize): void;
129+
export declare function store<T>(ptr: usize, value: auto, immOffset?: usize, immAlign?: usize): void;
128130

129131
// @ts-ignore: decorator
130132
@builtin
@@ -156,7 +158,7 @@ export declare function unreachable(): void;
156158

157159
// @ts-ignore: decorator
158160
@builtin
159-
export declare function changetype<T>(value: void): T;
161+
export declare function changetype<T>(value: auto): T;
160162

161163
// @ts-ignore: decorator
162164
@builtin
@@ -168,7 +170,7 @@ export declare function unchecked<T>(expr: T): T;
168170

169171
// @ts-ignore: decorator
170172
@builtin
171-
export declare function instantiate<T>(...args: void[]): T;
173+
export declare function instantiate<T>(...args: auto[]): T;
172174

173175
export namespace atomic {
174176
// @ts-ignore: decorator
@@ -230,7 +232,7 @@ export const enum AtomicWaitResult {
230232

231233
// @ts-ignore: decorator
232234
@builtin
233-
export declare function i8(value: void): i8;
235+
export declare function i8(value: auto): i8;
234236

235237
export namespace i8 {
236238

@@ -245,7 +247,7 @@ export namespace i8 {
245247

246248
// @ts-ignore: decorator
247249
@builtin
248-
export declare function i16(value: void): i16;
250+
export declare function i16(value: auto): i16;
249251

250252
export namespace i16 {
251253

@@ -260,7 +262,7 @@ export namespace i16 {
260262

261263
// @ts-ignore: decorator
262264
@builtin
263-
export declare function i32(value: void): i32;
265+
export declare function i32(value: auto): i32;
264266

265267
export namespace i32 {
266268

@@ -455,7 +457,7 @@ export namespace i32 {
455457

456458
// @ts-ignore: decorator
457459
@builtin
458-
export declare function i64(value: void): i64;
460+
export declare function i64(value: auto): i64;
459461

460462
export namespace i64 {
461463

@@ -701,7 +703,7 @@ export namespace i64 {
701703

702704
// @ts-ignore: decorator
703705
@builtin
704-
export declare function isize(value: void): isize;
706+
export declare function isize(value: auto): isize;
705707

706708
export namespace isize {
707709

@@ -720,7 +722,7 @@ export namespace isize {
720722

721723
// @ts-ignore: decorator
722724
@builtin
723-
export declare function u8(value: void): u8;
725+
export declare function u8(value: auto): u8;
724726

725727
export namespace u8 {
726728

@@ -735,7 +737,7 @@ export namespace u8 {
735737

736738
// @ts-ignore: decorator
737739
@builtin
738-
export declare function u16(value: void): u16;
740+
export declare function u16(value: auto): u16;
739741

740742
export namespace u16 {
741743

@@ -750,7 +752,7 @@ export namespace u16 {
750752

751753
// @ts-ignore: decorator
752754
@builtin
753-
export declare function u32(value: void): u32;
755+
export declare function u32(value: auto): u32;
754756

755757
export namespace u32 {
756758

@@ -765,7 +767,7 @@ export namespace u32 {
765767

766768
// @ts-ignore: decorator
767769
@builtin
768-
export declare function u64(value: void): u64;
770+
export declare function u64(value: auto): u64;
769771

770772
export namespace u64 {
771773

@@ -780,7 +782,7 @@ export namespace u64 {
780782

781783
// @ts-ignore: decorator
782784
@builtin
783-
export declare function usize(value: void): usize;
785+
export declare function usize(value: auto): usize;
784786

785787
export namespace usize {
786788

@@ -797,7 +799,7 @@ export namespace usize {
797799

798800
// @ts-ignore: decorator
799801
@builtin
800-
export declare function bool(value: void): bool;
802+
export declare function bool(value: auto): bool;
801803

802804
export namespace bool {
803805

@@ -812,7 +814,7 @@ export namespace bool {
812814

813815
// @ts-ignore: decorator
814816
@builtin
815-
export declare function f32(value: void): f32;
817+
export declare function f32(value: auto): f32;
816818

817819
export namespace f32 {
818820

@@ -891,7 +893,7 @@ export namespace f32 {
891893

892894
// @ts-ignore: decorator
893895
@builtin
894-
export declare function f64(value: void): f64;
896+
export declare function f64(value: auto): f64;
895897

896898
export namespace f64 {
897899

‎tests/compiler/basic-nullable.json‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"--runtime none"
44
],
55
"stderr": [
6-
"AS204: Basic type 'i32' cannot be nullable.",
6+
"AS204: Type 'i32' cannot be nullable.",
77
"EOF"
88
]
99
}

‎tests/parser/continue-on-error.ts.fixture.ts‎

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
;
2-
a;
3-
from;
4-
"./other";
51
do {
62
;
73
} while (false);

‎tests/parser/regexp.ts.fixture.ts‎

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22
/(abc)\//;
33
var re = /(abc)\//ig;
44
var noRe = !/(abc)\//i;
5-
b / ig;
65
/(abc)\//iig;
76
/(abc)\//iX;
87
false && /abc/gX.test(someString) || true;

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /