Skip to content

Commit 0e73a78

Browse files
author
Arthur Ozga
committed
Merge pull request #3579 from Microsoft/abstract-classes2
Abstract Classes and methods
2 parents 60db55b + 6d0c7c9 commit 0e73a78

File tree

107 files changed

+2543
-344
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

107 files changed

+2543
-344
lines changed

src/compiler/checker.ts

+291-150
Large diffs are not rendered by default.

src/compiler/core.ts

+15-8
Original file line numberDiff line numberDiff line change
@@ -2,17 +2,19 @@
22

33
/* @internal */
44
namespace ts {
5-
// Ternary values are defined such that
6-
// x & y is False if either x or y is False.
7-
// x & y is Maybe if either x or y is Maybe, but neither x or y is False.
8-
// x & y is True if both x and y are True.
9-
// x | y is False if both x and y are False.
10-
// x | y is Maybe if either x or y is Maybe, but neither x or y is True.
11-
// x | y is True if either x or y is True.
5+
/**
6+
* Ternary values are defined such that
7+
* x & y is False if either x or y is False.
8+
* x & y is Maybe if either x or y is Maybe, but neither x or y is False.
9+
* x & y is True if both x and y are True.
10+
* x | y is False if both x and y are False.
11+
* x | y is Maybe if either x or y is Maybe, but neither x or y is True.
12+
* x | y is True if either x or y is True.
13+
*/
1214
export const enum Ternary {
1315
False = 0,
1416
Maybe = 1,
15-
True = -1
17+
True = -1
1618
}
1719

1820
export function createFileMap<T>(getCanonicalFileName: (fileName: string) => string): FileMap<T> {
@@ -59,6 +61,11 @@ namespace ts {
5961

6062
export interface StringSet extends Map<any> { }
6163

64+
/**
65+
* Iterates through 'array' by index and performs the callback on each element of array until the callback
66+
* returns a truthy value, then returns that value.
67+
* If no such value is found, the callback is applied to each element of array and undefined is returned.
68+
*/
6269
export function forEach<T, U>(array: T[], callback: (element: T, index: number) => U): U {
6370
if (array) {
6471
for (let i = 0, len = array.length; i < len; i++) {

src/compiler/declarationEmitter.ts

+7
Original file line numberDiff line numberDiff line change
@@ -588,6 +588,9 @@ namespace ts {
588588
if (node.flags & NodeFlags.Static) {
589589
write("static ");
590590
}
591+
if (node.flags & NodeFlags.Abstract) {
592+
write("abstract ");
593+
}
591594
}
592595

593596
function writeImportEqualsDeclaration(node: ImportEqualsDeclaration) {
@@ -912,6 +915,10 @@ namespace ts {
912915

913916
emitJsDocComments(node);
914917
emitModuleElementDeclarationFlags(node);
918+
if (node.flags & NodeFlags.Abstract) {
919+
write("abstract ");
920+
}
921+
915922
write("class ");
916923
writeTextOfNode(currentSourceFile, node.name);
917924
let prevEnclosingDeclaration = enclosingDeclaration;

src/compiler/diagnosticInformationMap.generated.ts

+14-3
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,10 @@ namespace ts {
200200
Unable_to_resolve_signature_of_parameter_decorator_when_called_as_an_expression: { code: 1239, category: DiagnosticCategory.Error, key: "Unable to resolve signature of parameter decorator when called as an expression." },
201201
Unable_to_resolve_signature_of_property_decorator_when_called_as_an_expression: { code: 1240, category: DiagnosticCategory.Error, key: "Unable to resolve signature of property decorator when called as an expression." },
202202
Unable_to_resolve_signature_of_method_decorator_when_called_as_an_expression: { code: 1241, category: DiagnosticCategory.Error, key: "Unable to resolve signature of method decorator when called as an expression." },
203+
abstract_modifier_can_only_appear_on_a_class_or_method_declaration: { code: 1242, category: DiagnosticCategory.Error, key: "'abstract' modifier can only appear on a class or method declaration." },
204+
_0_modifier_cannot_be_used_with_1_modifier: { code: 1243, category: DiagnosticCategory.Error, key: "'{0}' modifier cannot be used with '{1}' modifier." },
205+
Abstract_methods_can_only_appear_within_an_abstract_class: { code: 1244, category: DiagnosticCategory.Error, key: "Abstract methods can only appear within an abstract class." },
206+
Method_0_cannot_have_an_implementation_because_it_is_marked_abstract: { code: 1245, category: DiagnosticCategory.Error, key: "Method '{0}' cannot have an implementation because it is marked abstract." },
203207
Duplicate_identifier_0: { code: 2300, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'." },
204208
Initializer_of_instance_member_variable_0_cannot_reference_identifier_1_declared_in_the_constructor: { code: 2301, category: DiagnosticCategory.Error, key: "Initializer of instance member variable '{0}' cannot reference identifier '{1}' declared in the constructor." },
205209
Static_members_cannot_reference_class_type_parameters: { code: 2302, category: DiagnosticCategory.Error, key: "Static members cannot reference class type parameters." },
@@ -235,10 +239,10 @@ namespace ts {
235239
this_cannot_be_referenced_in_a_static_property_initializer: { code: 2334, category: DiagnosticCategory.Error, key: "'this' cannot be referenced in a static property initializer." },
236240
super_can_only_be_referenced_in_a_derived_class: { code: 2335, category: DiagnosticCategory.Error, key: "'super' can only be referenced in a derived class." },
237241
super_cannot_be_referenced_in_constructor_arguments: { code: 2336, category: DiagnosticCategory.Error, key: "'super' cannot be referenced in constructor arguments." },
238-
Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: { code: 2337, category: DiagnosticCategory.Error, key: "Super calls are not permitted outside constructors or in nested functions inside constructors" },
239-
super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: { code: 2338, category: DiagnosticCategory.Error, key: "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class" },
242+
Super_calls_are_not_permitted_outside_constructors_or_in_nested_functions_inside_constructors: { code: 2337, category: DiagnosticCategory.Error, key: "Super calls are not permitted outside constructors or in nested functions inside constructors." },
243+
super_property_access_is_permitted_only_in_a_constructor_member_function_or_member_accessor_of_a_derived_class: { code: 2338, category: DiagnosticCategory.Error, key: "'super' property access is permitted only in a constructor, member function, or member accessor of a derived class." },
240244
Property_0_does_not_exist_on_type_1: { code: 2339, category: DiagnosticCategory.Error, key: "Property '{0}' does not exist on type '{1}'." },
241-
Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: 2340, category: DiagnosticCategory.Error, key: "Only public and protected methods of the base class are accessible via the 'super' keyword" },
245+
Only_public_and_protected_methods_of_the_base_class_are_accessible_via_the_super_keyword: { code: 2340, category: DiagnosticCategory.Error, key: "Only public and protected methods of the base class are accessible via the 'super' keyword." },
242246
Property_0_is_private_and_only_accessible_within_class_1: { code: 2341, category: DiagnosticCategory.Error, key: "Property '{0}' is private and only accessible within class '{1}'." },
243247
An_index_expression_argument_must_be_of_type_string_number_symbol_or_any: { code: 2342, category: DiagnosticCategory.Error, key: "An index expression argument must be of type 'string', 'number', 'symbol, or 'any'." },
244248
Type_0_does_not_satisfy_the_constraint_1: { code: 2344, category: DiagnosticCategory.Error, key: "Type '{0}' does not satisfy the constraint '{1}'." },
@@ -397,6 +401,13 @@ namespace ts {
397401
No_base_constructor_has_the_specified_number_of_type_arguments: { code: 2508, category: DiagnosticCategory.Error, key: "No base constructor has the specified number of type arguments." },
398402
Base_constructor_return_type_0_is_not_a_class_or_interface_type: { code: 2509, category: DiagnosticCategory.Error, key: "Base constructor return type '{0}' is not a class or interface type." },
399403
Base_constructors_must_all_have_the_same_return_type: { code: 2510, category: DiagnosticCategory.Error, key: "Base constructors must all have the same return type." },
404+
Cannot_create_an_instance_of_the_abstract_class_0: { code: 2511, category: DiagnosticCategory.Error, key: "Cannot create an instance of the abstract class '{0}'." },
405+
Overload_signatures_must_all_be_abstract_or_not_abstract: { code: 2512, category: DiagnosticCategory.Error, key: "Overload signatures must all be abstract or not abstract." },
406+
Abstract_method_0_in_class_1_cannot_be_accessed_via_super_expression: { code: 2513, category: DiagnosticCategory.Error, key: "Abstract method '{0}' in class '{1}' cannot be accessed via super expression." },
407+
Classes_containing_abstract_methods_must_be_marked_abstract: { code: 2514, category: DiagnosticCategory.Error, key: "Classes containing abstract methods must be marked abstract." },
408+
Non_abstract_class_0_does_not_implement_inherited_abstract_member_1_from_class_2: { code: 2515, category: DiagnosticCategory.Error, key: "Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'." },
409+
All_declarations_of_an_abstract_method_must_be_consecutive: { code: 2516, category: DiagnosticCategory.Error, key: "All declarations of an abstract method must be consecutive." },
410+
Constructor_objects_of_abstract_type_cannot_be_assigned_to_constructor_objects_of_non_abstract_type: { code: 2517, category: DiagnosticCategory.Error, key: "Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type" },
400411
Duplicate_identifier_0_Compiler_uses_declaration_1_to_support_async_functions: { code: 2520, category: DiagnosticCategory.Error, key: "Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions." },
401412
Expression_resolves_to_variable_declaration_0_that_compiler_uses_to_support_async_functions: { code: 2521, category: DiagnosticCategory.Error, key: "Expression resolves to variable declaration '{0}' that compiler uses to support async functions." },
402413
The_arguments_object_cannot_be_referenced_in_an_async_arrow_function_Consider_using_a_standard_async_function_expression: { code: 2522, category: DiagnosticCategory.Error, key: "The 'arguments' object cannot be referenced in an async arrow function. Consider using a standard async function expression." },

src/compiler/diagnosticMessages.json

+47-8
Original file line numberDiff line numberDiff line change
@@ -765,7 +765,6 @@
765765
"category": "Error",
766766
"code": 1311
767767
},
768-
769768
"The return type of a property decorator function must be either 'void' or 'any'.": {
770769
"category": "Error",
771770
"code": 1236
@@ -790,7 +789,22 @@
790789
"category": "Error",
791790
"code": 1241
792791
},
793-
792+
"'abstract' modifier can only appear on a class or method declaration.": {
793+
"category": "Error",
794+
"code": 1242
795+
},
796+
"'{0}' modifier cannot be used with '{1}' modifier.": {
797+
"category": "Error",
798+
"code": 1243
799+
},
800+
"Abstract methods can only appear within an abstract class.": {
801+
"category": "Error",
802+
"code": 1244
803+
},
804+
"Method '{0}' cannot have an implementation because it is marked abstract.": {
805+
"category": "Error",
806+
"code": 1245
807+
},
794808
"Duplicate identifier '{0}'.": {
795809
"category": "Error",
796810
"code": 2300
@@ -931,19 +945,19 @@
931945
"category": "Error",
932946
"code": 2336
933947
},
934-
"Super calls are not permitted outside constructors or in nested functions inside constructors": {
948+
"Super calls are not permitted outside constructors or in nested functions inside constructors.": {
935949
"category": "Error",
936950
"code": 2337
937951
},
938-
"'super' property access is permitted only in a constructor, member function, or member accessor of a derived class": {
952+
"'super' property access is permitted only in a constructor, member function, or member accessor of a derived class.": {
939953
"category": "Error",
940954
"code": 2338
941955
},
942956
"Property '{0}' does not exist on type '{1}'.": {
943957
"category": "Error",
944958
"code": 2339
945959
},
946-
"Only public and protected methods of the base class are accessible via the 'super' keyword": {
960+
"Only public and protected methods of the base class are accessible via the 'super' keyword.": {
947961
"category": "Error",
948962
"code": 2340
949963
},
@@ -1579,7 +1593,34 @@
15791593
"category": "Error",
15801594
"code": 2510
15811595
},
1582-
1596+
"Cannot create an instance of the abstract class '{0}'.": {
1597+
"category": "Error",
1598+
"code": 2511
1599+
},
1600+
"Overload signatures must all be abstract or not abstract.": {
1601+
"category": "Error",
1602+
"code": 2512
1603+
},
1604+
"Abstract method '{0}' in class '{1}' cannot be accessed via super expression.": {
1605+
"category": "Error",
1606+
"code": 2513
1607+
},
1608+
"Classes containing abstract methods must be marked abstract.": {
1609+
"category": "Error",
1610+
"code": 2514
1611+
},
1612+
"Non-abstract class '{0}' does not implement inherited abstract member '{1}' from class '{2}'.": {
1613+
"category": "Error",
1614+
"code": 2515
1615+
},
1616+
"All declarations of an abstract method must be consecutive.": {
1617+
"category": "Error",
1618+
"code": 2516
1619+
},
1620+
"Constructor objects of abstract type cannot be assigned to constructor objects of non-abstract type": {
1621+
"category": "Error",
1622+
"code":2517
1623+
},
15831624
"Duplicate identifier '{0}'. Compiler uses declaration '{1}' to support async functions.": {
15841625
"category": "Error",
15851626
"code": 2520
@@ -1600,7 +1641,6 @@
16001641
"category": "Error",
16011642
"code": 2524
16021643
},
1603-
16041644
"JSX element attributes type '{0}' must be an object type.": {
16051645
"category": "Error",
16061646
"code": 2600
@@ -1641,7 +1681,6 @@
16411681
"category": "Error",
16421682
"code": 2650
16431683
},
1644-
16451684
"Import declaration '{0}' is using private name '{1}'.": {
16461685
"category": "Error",
16471686
"code": 4000

src/compiler/parser.ts

+2
Original file line numberDiff line numberDiff line change
@@ -4141,6 +4141,7 @@ namespace ts {
41414141
case SyntaxKind.PrivateKeyword:
41424142
case SyntaxKind.ProtectedKeyword:
41434143
case SyntaxKind.StaticKeyword:
4144+
case SyntaxKind.AbstractKeyword:
41444145
nextToken();
41454146
continue;
41464147
default:
@@ -4278,6 +4279,7 @@ namespace ts {
42784279
case SyntaxKind.PrivateKeyword:
42794280
case SyntaxKind.ProtectedKeyword:
42804281
case SyntaxKind.PublicKeyword:
4282+
case SyntaxKind.AbstractKeyword:
42814283
case SyntaxKind.StaticKeyword:
42824284
if (isStartOfDeclaration()) {
42834285
return parseDeclaration();

src/compiler/scanner.ts

+1
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ namespace ts {
4545
}
4646

4747
let textToToken: Map<SyntaxKind> = {
48+
"abstract": SyntaxKind.AbstractKeyword,
4849
"any": SyntaxKind.AnyKeyword,
4950
"as": SyntaxKind.AsKeyword,
5051
"boolean": SyntaxKind.BooleanKeyword,

src/compiler/types.ts

+14-12
Original file line numberDiff line numberDiff line change
@@ -140,6 +140,7 @@ namespace ts {
140140
StaticKeyword,
141141
YieldKeyword,
142142
// Contextual keywords
143+
AbstractKeyword,
143144
AsKeyword,
144145
AnyKeyword,
145146
AsyncKeyword,
@@ -359,18 +360,19 @@ namespace ts {
359360
Private = 0x00000020, // Property/Method
360361
Protected = 0x00000040, // Property/Method
361362
Static = 0x00000080, // Property/Method
362-
Default = 0x00000100, // Function/Class (export default declaration)
363-
MultiLine = 0x00000200, // Multi-line array or object literal
364-
Synthetic = 0x00000400, // Synthetic node (for full fidelity)
365-
DeclarationFile = 0x00000800, // Node is a .d.ts file
366-
Let = 0x00001000, // Variable declaration
367-
Const = 0x00002000, // Variable declaration
368-
OctalLiteral = 0x00004000, // Octal numeric literal
369-
Namespace = 0x00008000, // Namespace declaration
370-
ExportContext = 0x00010000, // Export context (initialized by binding)
371-
Async = 0x00020000, // Property/Method/Function
372-
373-
Modifier = Export | Ambient | Public | Private | Protected | Static | Default | Async,
363+
Abstract = 0x00000100, // Class/Method/ConstructSignature
364+
Async = 0x00000200, // Property/Method/Function
365+
Default = 0x00000400, // Function/Class (export default declaration)
366+
MultiLine = 0x00000800, // Multi-line array or object literal
367+
Synthetic = 0x00001000, // Synthetic node (for full fidelity)
368+
DeclarationFile = 0x00002000, // Node is a .d.ts file
369+
Let = 0x00004000, // Variable declaration
370+
Const = 0x00008000, // Variable declaration
371+
OctalLiteral = 0x00010000, // Octal numeric literal
372+
Namespace = 0x00020000, // Namespace declaration
373+
ExportContext = 0x00040000, // Export context (initialized by binding)
374+
375+
Modifier = Export | Ambient | Public | Private | Protected | Static | Abstract | Default | Async,
374376
AccessibilityModifier = Public | Private | Protected,
375377
BlockScoped = Let | Const
376378
}

src/compiler/utilities.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -1391,15 +1391,16 @@ namespace ts {
13911391

13921392
export function isModifier(token: SyntaxKind): boolean {
13931393
switch (token) {
1394+
case SyntaxKind.AbstractKeyword:
1395+
case SyntaxKind.AsyncKeyword:
1396+
case SyntaxKind.ConstKeyword:
1397+
case SyntaxKind.DeclareKeyword:
1398+
case SyntaxKind.DefaultKeyword:
1399+
case SyntaxKind.ExportKeyword:
13941400
case SyntaxKind.PublicKeyword:
13951401
case SyntaxKind.PrivateKeyword:
13961402
case SyntaxKind.ProtectedKeyword:
13971403
case SyntaxKind.StaticKeyword:
1398-
case SyntaxKind.ExportKeyword:
1399-
case SyntaxKind.DeclareKeyword:
1400-
case SyntaxKind.ConstKeyword:
1401-
case SyntaxKind.DefaultKeyword:
1402-
case SyntaxKind.AsyncKeyword:
14031404
return true;
14041405
}
14051406
return false;
@@ -1900,6 +1901,7 @@ namespace ts {
19001901
case SyntaxKind.PublicKeyword: return NodeFlags.Public;
19011902
case SyntaxKind.ProtectedKeyword: return NodeFlags.Protected;
19021903
case SyntaxKind.PrivateKeyword: return NodeFlags.Private;
1904+
case SyntaxKind.AbstractKeyword: return NodeFlags.Abstract;
19031905
case SyntaxKind.ExportKeyword: return NodeFlags.Export;
19041906
case SyntaxKind.DeclareKeyword: return NodeFlags.Ambient;
19051907
case SyntaxKind.ConstKeyword: return NodeFlags.Const;

0 commit comments

Comments
 (0)