diff --git a/src/diagnosticMessages.generated.ts b/src/diagnosticMessages.generated.ts index 430ad489d1..e519dde336 100644 --- a/src/diagnosticMessages.generated.ts +++ b/src/diagnosticMessages.generated.ts @@ -20,7 +20,7 @@ export enum DiagnosticCode { Conversion_from_type_0_to_1_will_require_an_explicit_cast_when_switching_between_32_64_bit = 201, Type_0_cannot_be_changed_to_type_1 = 202, Operation_0_cannot_be_applied_to_type_1 = 203, - Basic_type_0_cannot_be_nullable = 204, + Type_0_cannot_be_nullable = 204, Cannot_export_a_mutable_global = 205, Mutable_value_cannot_be_inlined = 206, Unmanaged_classes_cannot_extend_managed_classes_and_vice_versa = 207, @@ -193,7 +193,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string { case 201: return "Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit."; case 202: return "Type '{0}' cannot be changed to type '{1}'."; case 203: return "Operation '{0}' cannot be applied to type '{1}'."; - case 204: return "Basic type '{0}' cannot be nullable."; + case 204: return "Type '{0}' cannot be nullable."; case 205: return "Cannot export a mutable global."; case 206: return "Mutable value cannot be inlined."; case 207: return "Unmanaged classes cannot extend managed classes and vice-versa."; diff --git a/src/diagnosticMessages.json b/src/diagnosticMessages.json index 42b1b252f0..8a3141ee84 100644 --- a/src/diagnosticMessages.json +++ b/src/diagnosticMessages.json @@ -13,7 +13,7 @@ "Conversion from type '{0}' to '{1}' will require an explicit cast when switching between 32/64-bit.": 201, "Type '{0}' cannot be changed to type '{1}'.": 202, "Operation '{0}' cannot be applied to type '{1}'.": 203, - "Basic type '{0}' cannot be nullable.": 204, + "Type '{0}' cannot be nullable.": 204, "Cannot export a mutable global.": 205, "Mutable value cannot be inlined.": 206, "Unmanaged classes cannot extend managed classes and vice-versa.": 207, diff --git a/src/parser.ts b/src/parser.ts index 210b4f162c..6374660079 100644 --- a/src/parser.ts +++ b/src/parser.ts @@ -155,7 +155,11 @@ export class Parser extends DiagnosticEmitter { var statements = source.statements; while (!tn.skip(Token.ENDOFFILE)) { let statement = this.parseTopLevelStatement(tn, null); - if (statement) statements.push(statement); + if (statement) { + statements.push(statement); + } else { + this.skipStatement(tn); + } } } @@ -538,6 +542,12 @@ export class Parser extends DiagnosticEmitter { Node.createSimpleTypeName("bool", tn.range()), [], false, tn.range(startPos, tn.pos) ); + // 'null' + } else if (token == Token.NULL) { + type = Node.createNamedType( + Node.createSimpleTypeName("null", tn.range()), [], false, tn.range(startPos, tn.pos) + ); + // StringLiteral } else if (token == Token.STRINGLITERAL) { tn.readString(); @@ -550,7 +560,6 @@ export class Parser extends DiagnosticEmitter { let name = this.parseTypeName(tn); if (!name) return null; let parameters: TypeNode[] | null = null; - let nullable = false; // Name if (tn.skip(Token.LESSTHAN)) { @@ -570,31 +579,33 @@ export class Parser extends DiagnosticEmitter { return null; } } - // ... | null - while (tn.skip(Token.BAR)) { - if (tn.skip(Token.NULL)) { - nullable = true; - } else { - if (!suppressErrors) { - this.error( - DiagnosticCode._0_expected, - tn.range(tn.pos), "null" - ); - } - return null; - } - } if (!parameters) parameters = []; - type = Node.createNamedType(name, parameters, nullable, tn.range(startPos, tn.pos)); + type = Node.createNamedType(name, parameters, false, tn.range(startPos, tn.pos)); } else { if (!suppressErrors) { this.error( - DiagnosticCode.Identifier_expected, + DiagnosticCode.Type_expected, tn.range() ); } return null; } + // ... | null + while (tn.skip(Token.BAR)) { + if (tn.skip(Token.NULL)) { + type.isNullable = true; + } else { + let notNullStart = tn.pos; + let notNull = this.parseType(tn, false, true); + if (!suppressErrors) { + this.error( + DiagnosticCode._0_expected, + notNull ? notNull.range : tn.range(notNullStart), "null" + ); + } + return null; + } + } // ... [][] while (tn.skip(Token.OPENBRACKET)) { let bracketStart = tn.tokenPos; diff --git a/src/resolver.ts b/src/resolver.ts index 44fd250293..551e893c23 100644 --- a/src/resolver.ts +++ b/src/resolver.ts @@ -205,7 +205,7 @@ export class Resolver extends DiagnosticEmitter { if (type.is(TypeFlags.REFERENCE)) return type.asNullable(); if (reportMode == ReportMode.REPORT) { this.error( - DiagnosticCode.Basic_type_0_cannot_be_nullable, + DiagnosticCode.Type_0_cannot_be_nullable, node.range, type.toString() ); } @@ -238,7 +238,7 @@ export class Resolver extends DiagnosticEmitter { if (node.isNullable) { if (reportMode == ReportMode.REPORT) { this.error( - DiagnosticCode.Basic_type_0_cannot_be_nullable, + DiagnosticCode.Type_0_cannot_be_nullable, node.range, element.name + "/i32" ); } @@ -283,7 +283,7 @@ export class Resolver extends DiagnosticEmitter { if (!type.is(TypeFlags.REFERENCE)) { if (reportMode == ReportMode.REPORT) { this.error( - DiagnosticCode.Basic_type_0_cannot_be_nullable, + DiagnosticCode.Type_0_cannot_be_nullable, nameNode.range, nameNode.identifier.text ); } @@ -333,7 +333,7 @@ export class Resolver extends DiagnosticEmitter { if (!type.is(TypeFlags.REFERENCE)) { if (reportMode == ReportMode.REPORT) { this.error( - DiagnosticCode.Basic_type_0_cannot_be_nullable, + DiagnosticCode.Type_0_cannot_be_nullable, nameNode.range, nameNode.identifier.text ); } @@ -2716,6 +2716,15 @@ export class Resolver extends DiagnosticEmitter { reportMode ); if (!parameterType) return null; + if (parameterType == Type.void) { + if (reportMode == ReportMode.REPORT) { + this.error( + DiagnosticCode.Type_expected, + typeNode.range + ); + } + return null; + } parameterTypes[i] = parameterType; parameterNames[i] = parameterDeclaration.name.text; } @@ -3078,6 +3087,15 @@ export class Resolver extends DiagnosticEmitter { instance.contextualTypeArguments, reportMode ); + if (fieldType == Type.void) { + if (reportMode == ReportMode.REPORT) { + this.error( + DiagnosticCode.Type_expected, + fieldTypeNode.range + ); + } + break; + } } if (!fieldType) break; // did report above let fieldInstance = new Field(fieldPrototype, instance, fieldType); diff --git a/std/assembly/builtins.ts b/std/assembly/builtins.ts index c7fe19362a..1168a117b8 100644 --- a/std/assembly/builtins.ts +++ b/std/assembly/builtins.ts @@ -1,3 +1,5 @@ +type auto = i32; + // @ts-ignore: decorator @builtin export declare function isInteger(value?: T): bool; @@ -40,11 +42,11 @@ export declare function isNullable(value?: T): bool; // @ts-ignore: decorator @builtin -export declare function isDefined(expression: void): bool; +export declare function isDefined(expression: auto): bool; // @ts-ignore: decorator @builtin -export declare function isConstant(expression: void): bool; +export declare function isConstant(expression: auto): bool; // @ts-ignore: decorator @builtin @@ -124,7 +126,7 @@ export declare function load(ptr: usize, immOffset?: usize, immAlign?: usize) // @ts-ignore: decorator @unsafe @builtin -export declare function store(ptr: usize, value: void, immOffset?: usize, immAlign?: usize): void; +export declare function store(ptr: usize, value: auto, immOffset?: usize, immAlign?: usize): void; // @ts-ignore: decorator @builtin @@ -156,7 +158,7 @@ export declare function unreachable(): void; // @ts-ignore: decorator @builtin -export declare function changetype(value: void): T; +export declare function changetype(value: auto): T; // @ts-ignore: decorator @builtin @@ -168,7 +170,7 @@ export declare function unchecked(expr: T): T; // @ts-ignore: decorator @builtin -export declare function instantiate(...args: void[]): T; +export declare function instantiate(...args: auto[]): T; export namespace atomic { // @ts-ignore: decorator @@ -230,7 +232,7 @@ export const enum AtomicWaitResult { // @ts-ignore: decorator @builtin -export declare function i8(value: void): i8; +export declare function i8(value: auto): i8; export namespace i8 { @@ -245,7 +247,7 @@ export namespace i8 { // @ts-ignore: decorator @builtin -export declare function i16(value: void): i16; +export declare function i16(value: auto): i16; export namespace i16 { @@ -260,7 +262,7 @@ export namespace i16 { // @ts-ignore: decorator @builtin -export declare function i32(value: void): i32; +export declare function i32(value: auto): i32; export namespace i32 { @@ -455,7 +457,7 @@ export namespace i32 { // @ts-ignore: decorator @builtin -export declare function i64(value: void): i64; +export declare function i64(value: auto): i64; export namespace i64 { @@ -701,7 +703,7 @@ export namespace i64 { // @ts-ignore: decorator @builtin -export declare function isize(value: void): isize; +export declare function isize(value: auto): isize; export namespace isize { @@ -720,7 +722,7 @@ export namespace isize { // @ts-ignore: decorator @builtin -export declare function u8(value: void): u8; +export declare function u8(value: auto): u8; export namespace u8 { @@ -735,7 +737,7 @@ export namespace u8 { // @ts-ignore: decorator @builtin -export declare function u16(value: void): u16; +export declare function u16(value: auto): u16; export namespace u16 { @@ -750,7 +752,7 @@ export namespace u16 { // @ts-ignore: decorator @builtin -export declare function u32(value: void): u32; +export declare function u32(value: auto): u32; export namespace u32 { @@ -765,7 +767,7 @@ export namespace u32 { // @ts-ignore: decorator @builtin -export declare function u64(value: void): u64; +export declare function u64(value: auto): u64; export namespace u64 { @@ -780,7 +782,7 @@ export namespace u64 { // @ts-ignore: decorator @builtin -export declare function usize(value: void): usize; +export declare function usize(value: auto): usize; export namespace usize { @@ -797,7 +799,7 @@ export namespace usize { // @ts-ignore: decorator @builtin -export declare function bool(value: void): bool; +export declare function bool(value: auto): bool; export namespace bool { @@ -812,7 +814,7 @@ export namespace bool { // @ts-ignore: decorator @builtin -export declare function f32(value: void): f32; +export declare function f32(value: auto): f32; export namespace f32 { @@ -891,7 +893,7 @@ export namespace f32 { // @ts-ignore: decorator @builtin -export declare function f64(value: void): f64; +export declare function f64(value: auto): f64; export namespace f64 { diff --git a/tests/compiler/basic-nullable.json b/tests/compiler/basic-nullable.json index 0d7a7ffafd..a457dec7bf 100644 --- a/tests/compiler/basic-nullable.json +++ b/tests/compiler/basic-nullable.json @@ -3,7 +3,7 @@ "--runtime none" ], "stderr": [ - "AS204: Basic type 'i32' cannot be nullable.", + "AS204: Type 'i32' cannot be nullable.", "EOF" ] } \ No newline at end of file diff --git a/tests/parser/continue-on-error.ts.fixture.ts b/tests/parser/continue-on-error.ts.fixture.ts index a10d400f0f..1a156b9362 100644 --- a/tests/parser/continue-on-error.ts.fixture.ts +++ b/tests/parser/continue-on-error.ts.fixture.ts @@ -1,7 +1,3 @@ -; -a; -from; -"./other"; do { ; } while (false); diff --git a/tests/parser/regexp.ts.fixture.ts b/tests/parser/regexp.ts.fixture.ts index 43cf5d3225..65941d1d05 100644 --- a/tests/parser/regexp.ts.fixture.ts +++ b/tests/parser/regexp.ts.fixture.ts @@ -2,7 +2,6 @@ /(abc)\//; var re = /(abc)\//ig; var noRe = !/(abc)\//i; -b / ig; /(abc)\//iig; /(abc)\//iX; false && /abc/gX.test(someString) || true;