mirror of
https://github.com/fluencelabs/assemblyscript
synced 2025-04-25 23:12:19 +00:00
Support definite assignment assertion x!: i32
(#260)
This commit is contained in:
parent
e58582e9e9
commit
0bb5cb829e
@ -36,44 +36,46 @@ export enum CommonFlags {
|
|||||||
GET = 1 << 11,
|
GET = 1 << 11,
|
||||||
/** Has a `set` modifier. */
|
/** Has a `set` modifier. */
|
||||||
SET = 1 << 12,
|
SET = 1 << 12,
|
||||||
|
/** Has a definite assignment assertion `!` as in `x!: i32;`. */
|
||||||
|
DEFINITE_ASSIGNMENT = 1 << 13,
|
||||||
|
|
||||||
// Extended modifiers usually derived from basic modifiers
|
// Extended modifiers usually derived from basic modifiers
|
||||||
|
|
||||||
/** Is ambient, that is either declared or nested in a declared element. */
|
/** Is ambient, that is either declared or nested in a declared element. */
|
||||||
AMBIENT = 1 << 13,
|
AMBIENT = 1 << 14,
|
||||||
/** Is generic. */
|
/** Is generic. */
|
||||||
GENERIC = 1 << 14,
|
GENERIC = 1 << 15,
|
||||||
/** Is part of a generic context. */
|
/** Is part of a generic context. */
|
||||||
GENERIC_CONTEXT = 1 << 15,
|
GENERIC_CONTEXT = 1 << 16,
|
||||||
/** Is an instance member. */
|
/** Is an instance member. */
|
||||||
INSTANCE = 1 << 16,
|
INSTANCE = 1 << 17,
|
||||||
/** Is a constructor. */
|
/** Is a constructor. */
|
||||||
CONSTRUCTOR = 1 << 17,
|
CONSTRUCTOR = 1 << 18,
|
||||||
/** Is an arrow function. */
|
/** Is an arrow function. */
|
||||||
ARROW = 1 << 18,
|
ARROW = 1 << 19,
|
||||||
/** Is a module export. */
|
/** Is a module export. */
|
||||||
MODULE_EXPORT = 1 << 19,
|
MODULE_EXPORT = 1 << 20,
|
||||||
/** Is a module import. */
|
/** Is a module import. */
|
||||||
MODULE_IMPORT = 1 << 20,
|
MODULE_IMPORT = 1 << 21,
|
||||||
|
|
||||||
// Compilation states
|
// Compilation states
|
||||||
|
|
||||||
/** Is compiled. */
|
/** Is compiled. */
|
||||||
COMPILED = 1 << 21,
|
COMPILED = 1 << 22,
|
||||||
/** Has a constant value and is therefore inlined. */
|
/** Has a constant value and is therefore inlined. */
|
||||||
INLINED = 1 << 22,
|
INLINED = 1 << 23,
|
||||||
/** Is scoped. */
|
/** Is scoped. */
|
||||||
SCOPED = 1 << 23,
|
SCOPED = 1 << 24,
|
||||||
/** Is a trampoline. */
|
/** Is a trampoline. */
|
||||||
TRAMPOLINE = 1 << 24,
|
TRAMPOLINE = 1 << 25,
|
||||||
/** Is a virtual method. */
|
/** Is a virtual method. */
|
||||||
VIRTUAL = 1 << 25,
|
VIRTUAL = 1 << 26,
|
||||||
/** Is the main function. */
|
/** Is the main function. */
|
||||||
MAIN = 1 << 26,
|
MAIN = 1 << 27,
|
||||||
|
|
||||||
// Other
|
// Other
|
||||||
|
|
||||||
QUOTED = 1 << 27
|
QUOTED = 1 << 28
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Path delimiter inserted between file system levels. */
|
/** Path delimiter inserted between file system levels. */
|
||||||
|
@ -29,6 +29,7 @@ export enum DiagnosticCode {
|
|||||||
Constructor_of_class_0_must_not_require_any_arguments = 216,
|
Constructor_of_class_0_must_not_require_any_arguments = 216,
|
||||||
Function_0_cannot_be_inlined_into_itself = 217,
|
Function_0_cannot_be_inlined_into_itself = 217,
|
||||||
Cannot_access_method_0_without_calling_it_as_it_requires_this_to_be_set = 218,
|
Cannot_access_method_0_without_calling_it_as_it_requires_this_to_be_set = 218,
|
||||||
|
Optional_properties_are_not_supported = 219,
|
||||||
Unterminated_string_literal = 1002,
|
Unterminated_string_literal = 1002,
|
||||||
Identifier_expected = 1003,
|
Identifier_expected = 1003,
|
||||||
_0_expected = 1005,
|
_0_expected = 1005,
|
||||||
@ -81,6 +82,7 @@ export enum DiagnosticCode {
|
|||||||
Decorators_are_not_valid_here = 1206,
|
Decorators_are_not_valid_here = 1206,
|
||||||
_abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration = 1242,
|
_abstract_modifier_can_only_appear_on_a_class_method_or_property_declaration = 1242,
|
||||||
Method_0_cannot_have_an_implementation_because_it_is_marked_abstract = 1245,
|
Method_0_cannot_have_an_implementation_because_it_is_marked_abstract = 1245,
|
||||||
|
A_definite_assignment_assertion_is_not_permitted_in_this_context = 1255,
|
||||||
A_class_may_only_extend_another_class = 1311,
|
A_class_may_only_extend_another_class = 1311,
|
||||||
A_parameter_property_cannot_be_declared_using_a_rest_parameter = 1317,
|
A_parameter_property_cannot_be_declared_using_a_rest_parameter = 1317,
|
||||||
Duplicate_identifier_0 = 2300,
|
Duplicate_identifier_0 = 2300,
|
||||||
@ -149,6 +151,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 216: return "Constructor of class '{0}' must not require any arguments.";
|
case 216: return "Constructor of class '{0}' must not require any arguments.";
|
||||||
case 217: return "Function '{0}' cannot be inlined into itself.";
|
case 217: return "Function '{0}' cannot be inlined into itself.";
|
||||||
case 218: return "Cannot access method '{0}' without calling it as it requires 'this' to be set.";
|
case 218: return "Cannot access method '{0}' without calling it as it requires 'this' to be set.";
|
||||||
|
case 219: return "Optional properties are not supported.";
|
||||||
case 1002: return "Unterminated string literal.";
|
case 1002: return "Unterminated string literal.";
|
||||||
case 1003: return "Identifier expected.";
|
case 1003: return "Identifier expected.";
|
||||||
case 1005: return "'{0}' expected.";
|
case 1005: return "'{0}' expected.";
|
||||||
@ -201,6 +204,7 @@ export function diagnosticCodeToString(code: DiagnosticCode): string {
|
|||||||
case 1206: return "Decorators are not valid here.";
|
case 1206: return "Decorators are not valid here.";
|
||||||
case 1242: return "'abstract' modifier can only appear on a class, method, or property declaration.";
|
case 1242: return "'abstract' modifier can only appear on a class, method, or property declaration.";
|
||||||
case 1245: return "Method '{0}' cannot have an implementation because it is marked abstract.";
|
case 1245: return "Method '{0}' cannot have an implementation because it is marked abstract.";
|
||||||
|
case 1255: return "A definite assignment assertion '!' is not permitted in this context.";
|
||||||
case 1311: return "A class may only extend another class.";
|
case 1311: return "A class may only extend another class.";
|
||||||
case 1317: return "A parameter property cannot be declared using a rest parameter.";
|
case 1317: return "A parameter property cannot be declared using a rest parameter.";
|
||||||
case 2300: return "Duplicate identifier '{0}'.";
|
case 2300: return "Duplicate identifier '{0}'.";
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"Constructor of class '{0}' must not require any arguments.": 216,
|
"Constructor of class '{0}' must not require any arguments.": 216,
|
||||||
"Function '{0}' cannot be inlined into itself.": 217,
|
"Function '{0}' cannot be inlined into itself.": 217,
|
||||||
"Cannot access method '{0}' without calling it as it requires 'this' to be set.": 218,
|
"Cannot access method '{0}' without calling it as it requires 'this' to be set.": 218,
|
||||||
|
"Optional properties are not supported.": 219,
|
||||||
|
|
||||||
"Unterminated string literal.": 1002,
|
"Unterminated string literal.": 1002,
|
||||||
"Identifier expected.": 1003,
|
"Identifier expected.": 1003,
|
||||||
@ -74,6 +75,7 @@
|
|||||||
"Decorators are not valid here.": 1206,
|
"Decorators are not valid here.": 1206,
|
||||||
"'abstract' modifier can only appear on a class, method, or property declaration.": 1242,
|
"'abstract' modifier can only appear on a class, method, or property declaration.": 1242,
|
||||||
"Method '{0}' cannot have an implementation because it is marked abstract.": 1245,
|
"Method '{0}' cannot have an implementation because it is marked abstract.": 1245,
|
||||||
|
"A definite assignment assertion '!' is not permitted in this context.": 1255,
|
||||||
"A class may only extend another class.": 1311,
|
"A class may only extend another class.": 1311,
|
||||||
"A parameter property cannot be declared using a rest parameter.": 1317,
|
"A parameter property cannot be declared using a rest parameter.": 1317,
|
||||||
|
|
||||||
|
@ -990,6 +990,9 @@ export class ASTBuilder {
|
|||||||
this.serializeAccessModifiers(node);
|
this.serializeAccessModifiers(node);
|
||||||
this.visitIdentifierExpression(node.name);
|
this.visitIdentifierExpression(node.name);
|
||||||
var sb = this.sb;
|
var sb = this.sb;
|
||||||
|
if (node.flags & CommonFlags.DEFINITE_ASSIGNMENT) {
|
||||||
|
sb.push("!");
|
||||||
|
}
|
||||||
var type = node.type;
|
var type = node.type;
|
||||||
if (type) {
|
if (type) {
|
||||||
sb.push(": ");
|
sb.push(": ");
|
||||||
@ -1376,6 +1379,9 @@ export class ASTBuilder {
|
|||||||
this.visitIdentifierExpression(node.name);
|
this.visitIdentifierExpression(node.name);
|
||||||
var type = node.type;
|
var type = node.type;
|
||||||
var sb = this.sb;
|
var sb = this.sb;
|
||||||
|
if (node.flags & CommonFlags.DEFINITE_ASSIGNMENT) {
|
||||||
|
sb.push("!");
|
||||||
|
}
|
||||||
if (type) {
|
if (type) {
|
||||||
sb.push(": ");
|
sb.push(": ");
|
||||||
this.visitTypeNode(type);
|
this.visitTypeNode(type);
|
||||||
|
@ -769,6 +769,9 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
var identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
var identifier = Node.createIdentifierExpression(tn.readIdentifier(), tn.range());
|
||||||
var flags = parentFlags;
|
var flags = parentFlags;
|
||||||
|
if (tn.skip(Token.EXCLAMATION)) {
|
||||||
|
flags |= CommonFlags.DEFINITE_ASSIGNMENT;
|
||||||
|
}
|
||||||
|
|
||||||
var type: CommonTypeNode | null = null;
|
var type: CommonTypeNode | null = null;
|
||||||
if (tn.skip(Token.COLON)) {
|
if (tn.skip(Token.COLON)) {
|
||||||
@ -800,13 +803,19 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
); // recoverable
|
); // recoverable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
var range = Range.join(identifier.range, tn.range());
|
||||||
|
if ((flags & CommonFlags.DEFINITE_ASSIGNMENT) && initializer) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.A_definite_assignment_assertion_is_not_permitted_in_this_context,
|
||||||
|
range);
|
||||||
|
}
|
||||||
return Node.createVariableDeclaration(
|
return Node.createVariableDeclaration(
|
||||||
identifier,
|
identifier,
|
||||||
type,
|
type,
|
||||||
initializer,
|
initializer,
|
||||||
parentDecorators,
|
parentDecorators,
|
||||||
flags,
|
flags,
|
||||||
Range.join(identifier.range, tn.range())
|
range
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1926,6 +1935,15 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let type: CommonTypeNode | null = null;
|
let type: CommonTypeNode | null = null;
|
||||||
|
if (tn.skip(Token.QUESTION)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.Optional_properties_are_not_supported,
|
||||||
|
tn.range(startPos, tn.pos)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (tn.skip(Token.EXCLAMATION)) {
|
||||||
|
flags |= CommonFlags.DEFINITE_ASSIGNMENT;
|
||||||
|
}
|
||||||
if (tn.skip(Token.COLON)) {
|
if (tn.skip(Token.COLON)) {
|
||||||
type = this.parseType(tn);
|
type = this.parseType(tn);
|
||||||
if (!type) return null;
|
if (!type) return null;
|
||||||
@ -1940,13 +1958,20 @@ export class Parser extends DiagnosticEmitter {
|
|||||||
initializer = this.parseExpression(tn);
|
initializer = this.parseExpression(tn);
|
||||||
if (!initializer) return null;
|
if (!initializer) return null;
|
||||||
}
|
}
|
||||||
|
let range = tn.range(startPos, tn.pos);
|
||||||
|
if ((flags & CommonFlags.DEFINITE_ASSIGNMENT) && ((flags & CommonFlags.STATIC) || isInterface || initializer)) {
|
||||||
|
this.error(
|
||||||
|
DiagnosticCode.A_definite_assignment_assertion_is_not_permitted_in_this_context,
|
||||||
|
range
|
||||||
|
);
|
||||||
|
}
|
||||||
let retField = Node.createFieldDeclaration(
|
let retField = Node.createFieldDeclaration(
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
initializer,
|
initializer,
|
||||||
decorators,
|
decorators,
|
||||||
flags,
|
flags,
|
||||||
tn.range(startPos, tn.pos)
|
range
|
||||||
);
|
);
|
||||||
tn.skip(Token.SEMICOLON);
|
tn.skip(Token.SEMICOLON);
|
||||||
return retField;
|
return retField;
|
||||||
|
9
tests/parser/definite-assignment-assertion.ts
Normal file
9
tests/parser/definite-assignment-assertion.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
class C {
|
||||||
|
x!: i32;
|
||||||
|
x!: i32 = 0;
|
||||||
|
static x!: i32;
|
||||||
|
}
|
||||||
|
function f(): void {
|
||||||
|
let x!: i32;
|
||||||
|
let x!: i32 = 0;
|
||||||
|
}
|
12
tests/parser/definite-assignment-assertion.ts.fixture.ts
Normal file
12
tests/parser/definite-assignment-assertion.ts.fixture.ts
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
class C {
|
||||||
|
x!: i32;
|
||||||
|
x!: i32 = 0;
|
||||||
|
static x!: i32;
|
||||||
|
}
|
||||||
|
function f(): void {
|
||||||
|
let x!: i32;
|
||||||
|
let x!: i32 = 0;
|
||||||
|
}
|
||||||
|
// ERROR 1255: "A definite assignment assertion '!' is not permitted in this context." in definite-assignment-assertion.ts:3:10
|
||||||
|
// ERROR 1255: "A definite assignment assertion '!' is not permitted in this context." in definite-assignment-assertion.ts:4:14
|
||||||
|
// ERROR 1255: "A definite assignment assertion '!' is not permitted in this context." in definite-assignment-assertion.ts:8:6
|
3
tests/parser/optional-property.ts
Normal file
3
tests/parser/optional-property.ts
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
class C {
|
||||||
|
x?: i32;
|
||||||
|
}
|
4
tests/parser/optional-property.ts.fixture.ts
Normal file
4
tests/parser/optional-property.ts.fixture.ts
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
class C {
|
||||||
|
x: i32;
|
||||||
|
}
|
||||||
|
// ERROR 219: "Optional properties are not supported." in optional-property.ts:2:9
|
Loading…
x
Reference in New Issue
Block a user