Skip to content

Commit c7885ad

Browse files
committed
feat(1534): add sealed keyword
1 parent 92a1b12 commit c7885ad

Some content is hidden

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

57 files changed

+1122
-519
lines changed

src/compiler/checker.ts

+25-1
Original file line numberDiff line numberDiff line change
@@ -12559,6 +12559,7 @@ namespace ts {
1255912559
checkFlags |= (!(modifiers & ModifierFlags.NonPublicAccessibilityModifier) ? CheckFlags.ContainsPublic : 0) |
1256012560
(modifiers & ModifierFlags.Protected ? CheckFlags.ContainsProtected : 0) |
1256112561
(modifiers & ModifierFlags.Private ? CheckFlags.ContainsPrivate : 0) |
12562+
(modifiers & ModifierFlags.Sealed ? CheckFlags.ContainsSealed : 0) |
1256212563
(modifiers & ModifierFlags.Static ? CheckFlags.ContainsStatic : 0);
1256312564
if (!isPrototypeProperty(prop)) {
1256412565
syntheticFlag = CheckFlags.SyntheticProperty;
@@ -20349,6 +20350,13 @@ namespace ts {
2034920350
return Ternary.False;
2035020351
}
2035120352
}
20353+
else if (targetPropFlags & ModifierFlags.Sealed) {
20354+
if (reportErrors) {
20355+
reportError(Diagnostics.Property_0_is_sealed_in_type_1_that_cannot_be_overridden_in_type_2, symbolToString(targetProp),
20356+
typeToString(target), typeToString(source));
20357+
}
20358+
return Ternary.False;
20359+
}
2035220360
else if (targetPropFlags & ModifierFlags.Protected) {
2035320361
if (!isValidOverrideOf(sourceProp, targetProp)) {
2035420362
if (reportErrors) {
@@ -44313,7 +44321,7 @@ namespace ts {
4431344321
return quickResult;
4431444322
}
4431544323

44316-
let lastStatic: Node | undefined, lastDeclare: Node | undefined, lastAsync: Node | undefined, lastOverride: Node | undefined;
44324+
let lastStatic: Node | undefined, lastDeclare: Node | undefined, lastAsync: Node | undefined, lastOverride: Node | undefined, lastSealed: Node | undefined;
4431744325
let flags = ModifierFlags.None;
4431844326
for (const modifier of node.modifiers!) {
4431944327
if (isDecorator(modifier)) continue;
@@ -44486,6 +44494,19 @@ namespace ts {
4448644494

4448744495
flags |= ModifierFlags.Default;
4448844496
break;
44497+
case SyntaxKind.SealedKeyword:
44498+
if (flags & ModifierFlags.Sealed) {
44499+
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "sealed");
44500+
}
44501+
if (flags & ModifierFlags.Private) {
44502+
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "sealed", "private");
44503+
}
44504+
if (flags & ModifierFlags.Abstract) {
44505+
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_cannot_be_used_with_1_modifier, "sealed", "abstract");
44506+
}
44507+
flags |= ModifierFlags.Sealed;
44508+
lastSealed = modifier;
44509+
break;
4448944510
case SyntaxKind.DeclareKeyword:
4449044511
if (flags & ModifierFlags.Ambient) {
4449144512
return grammarErrorOnNode(modifier, Diagnostics._0_modifier_already_seen, "declare");
@@ -44595,6 +44616,9 @@ namespace ts {
4459544616
if (flags & ModifierFlags.Async) {
4459644617
return grammarErrorOnNode(lastAsync!, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "async");
4459744618
}
44619+
if (flags & ModifierFlags.Sealed) {
44620+
return grammarErrorOnNode(lastSealed!, Diagnostics._0_modifier_cannot_appear_on_a_constructor_declaration, "sealed");
44621+
}
4459844622
return false;
4459944623
}
4460044624
else if ((node.kind === SyntaxKind.ImportDeclaration || node.kind === SyntaxKind.ImportEqualsDeclaration) && flags & ModifierFlags.Ambient) {

src/compiler/diagnosticMessages.json

+4
Original file line numberDiff line numberDiff line change
@@ -3567,6 +3567,10 @@
35673567
"category": "Error",
35683568
"code": 2845
35693569
},
3570+
"Property '{0}' is sealed in type '{1}' that cannot be overridden in type '{2}'.": {
3571+
"category": "Error",
3572+
"code": 2846
3573+
},
35703574

35713575
"Import declaration '{0}' is using private name '{1}'.": {
35723576
"category": "Error",

src/compiler/factory/nodeFactory.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1013,6 +1013,7 @@ namespace ts {
10131013
case SyntaxKind.PublicKeyword:
10141014
case SyntaxKind.PrivateKeyword:
10151015
case SyntaxKind.ProtectedKeyword:
1016+
case SyntaxKind.SealedKeyword:
10161017
case SyntaxKind.ReadonlyKeyword:
10171018
case SyntaxKind.AbstractKeyword:
10181019
case SyntaxKind.DeclareKeyword:
@@ -1101,6 +1102,7 @@ namespace ts {
11011102
if (flags & ModifierFlags.Public) result.push(createModifier(SyntaxKind.PublicKeyword));
11021103
if (flags & ModifierFlags.Private) result.push(createModifier(SyntaxKind.PrivateKeyword));
11031104
if (flags & ModifierFlags.Protected) result.push(createModifier(SyntaxKind.ProtectedKeyword));
1105+
if (flags & ModifierFlags.Sealed) result.push(createModifier(SyntaxKind.SealedKeyword));
11041106
if (flags & ModifierFlags.Abstract) result.push(createModifier(SyntaxKind.AbstractKeyword));
11051107
if (flags & ModifierFlags.Static) result.push(createModifier(SyntaxKind.StaticKeyword));
11061108
if (flags & ModifierFlags.Override) result.push(createModifier(SyntaxKind.OverrideKeyword));

src/compiler/program.ts

+1
Original file line numberDiff line numberDiff line change
@@ -2456,6 +2456,7 @@ namespace ts {
24562456
case SyntaxKind.PublicKeyword:
24572457
case SyntaxKind.PrivateKeyword:
24582458
case SyntaxKind.ProtectedKeyword:
2459+
case SyntaxKind.SealedKeyword:
24592460
case SyntaxKind.ReadonlyKeyword:
24602461
case SyntaxKind.DeclareKeyword:
24612462
case SyntaxKind.AbstractKeyword:

src/compiler/scanner.ts

+1
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ namespace ts {
131131
private: SyntaxKind.PrivateKeyword,
132132
protected: SyntaxKind.ProtectedKeyword,
133133
public: SyntaxKind.PublicKeyword,
134+
sealed: SyntaxKind.SealedKeyword,
134135
override: SyntaxKind.OverrideKeyword,
135136
out: SyntaxKind.OutKeyword,
136137
readonly: SyntaxKind.ReadonlyKeyword,

src/compiler/transformers/ts.ts

+1
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ namespace ts {
395395
case SyntaxKind.PublicKeyword:
396396
case SyntaxKind.PrivateKeyword:
397397
case SyntaxKind.ProtectedKeyword:
398+
case SyntaxKind.SealedKeyword:
398399
case SyntaxKind.AbstractKeyword:
399400
case SyntaxKind.OverrideKeyword:
400401
case SyntaxKind.ConstKeyword:

src/compiler/types.ts

+19-11
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ namespace ts {
156156
ProtectedKeyword,
157157
PublicKeyword,
158158
StaticKeyword,
159+
SealedKeyword,
159160
YieldKeyword,
160161
// Contextual keywords
161162
AbstractKeyword,
@@ -606,6 +607,7 @@ namespace ts {
606607
| SyntaxKind.PrivateKeyword
607608
| SyntaxKind.ProtectedKeyword
608609
| SyntaxKind.PublicKeyword
610+
| SyntaxKind.SealedKeyword
609611
| SyntaxKind.ReadonlyKeyword
610612
| SyntaxKind.OutKeyword
611613
| SyntaxKind.OverrideKeyword
@@ -646,6 +648,7 @@ namespace ts {
646648
| SyntaxKind.PrivateKeyword
647649
| SyntaxKind.ProtectedKeyword
648650
| SyntaxKind.PublicKeyword
651+
| SyntaxKind.SealedKeyword
649652
| SyntaxKind.ReadonlyKeyword
650653
| SyntaxKind.OutKeyword
651654
| SyntaxKind.OverrideKeyword
@@ -832,16 +835,17 @@ namespace ts {
832835
In = 1 << 15, // Contravariance modifier
833836
Out = 1 << 16, // Covariance modifier
834837
Decorator = 1 << 17, // Contains a decorator.
838+
Sealed = 1 << 18, // Property/Method
835839
HasComputedFlags = 1 << 29, // Modifier flags have been computed
836840

837841
AccessibilityModifier = Public | Private | Protected,
838842
// Accessibility modifiers and 'readonly' can be attached to a parameter in a constructor to make it a property.
839843
ParameterPropertyModifier = AccessibilityModifier | Readonly | Override,
840844
NonPublicAccessibilityModifier = Private | Protected,
841845

842-
TypeScriptModifier = Ambient | Public | Private | Protected | Readonly | Abstract | Const | Override | In | Out,
846+
TypeScriptModifier = Ambient | Public | Private | Protected | Sealed | Readonly | Abstract | Const | Override | In | Out,
843847
ExportDefault = Export | Default,
844-
All = Export | Ambient | Public | Private | Protected | Static | Readonly | Abstract | Accessor | Async | Default | Const | Deprecated | Override | In | Out | Decorator,
848+
All = Export | Ambient | Public | Private | Protected | Sealed | Static | Readonly | Abstract | Accessor | Async | Default | Const | Deprecated | Override | In | Out | Decorator,
845849
Modifier = All & ~Decorator
846850
}
847851

@@ -1347,6 +1351,7 @@ namespace ts {
13471351
export type PrivateKeyword = ModifierToken<SyntaxKind.PrivateKeyword>;
13481352
export type ProtectedKeyword = ModifierToken<SyntaxKind.ProtectedKeyword>;
13491353
export type PublicKeyword = ModifierToken<SyntaxKind.PublicKeyword>;
1354+
export type SealedKeyword = ModifierToken<SyntaxKind.SealedKeyword>;
13501355
export type ReadonlyKeyword = ModifierToken<SyntaxKind.ReadonlyKeyword>;
13511356
export type OutKeyword = ModifierToken<SyntaxKind.OutKeyword>;
13521357
export type OverrideKeyword = ModifierToken<SyntaxKind.OverrideKeyword>;
@@ -1368,6 +1373,7 @@ namespace ts {
13681373
| ProtectedKeyword
13691374
| PublicKeyword
13701375
| OutKeyword
1376+
| SealedKeyword
13711377
| OverrideKeyword
13721378
| ReadonlyKeyword
13731379
| StaticKeyword
@@ -5436,15 +5442,17 @@ namespace ts {
54365442
ContainsProtected = 1 << 9, // Synthetic property with protected constituent(s)
54375443
ContainsPrivate = 1 << 10, // Synthetic property with private constituent(s)
54385444
ContainsStatic = 1 << 11, // Synthetic property with static constituent(s)
5439-
Late = 1 << 12, // Late-bound symbol for a computed property with a dynamic name
5440-
ReverseMapped = 1 << 13, // Property of reverse-inferred homomorphic mapped type
5441-
OptionalParameter = 1 << 14, // Optional parameter
5442-
RestParameter = 1 << 15, // Rest parameter
5443-
DeferredType = 1 << 16, // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
5444-
HasNeverType = 1 << 17, // Synthetic property with at least one never type in constituents
5445-
Mapped = 1 << 18, // Property of mapped type
5446-
StripOptional = 1 << 19, // Strip optionality in mapped property
5447-
Unresolved = 1 << 20, // Unresolved type alias symbol
5445+
ContainsSealed = 1 << 12,
5446+
5447+
Late = 1 << 13, // Late-bound symbol for a computed property with a dynamic name
5448+
ReverseMapped = 1 << 14, // Property of reverse-inferred homomorphic mapped type
5449+
OptionalParameter = 1 << 15, // Optional parameter
5450+
RestParameter = 1 << 16, // Rest parameter
5451+
DeferredType = 1 << 17, // Calculation of the type of this symbol is deferred due to processing costs, should be fetched with `getTypeOfSymbolWithDeferredType`
5452+
HasNeverType = 1 << 18, // Synthetic property with at least one never type in constituents
5453+
Mapped = 1 << 19, // Property of mapped type
5454+
StripOptional = 1 << 20, // Strip optionality in mapped property
5455+
Unresolved = 1 << 21, // Unresolved type alias symbol
54485456
Synthetic = SyntheticProperty | SyntheticMethod,
54495457
Discriminant = HasNonUniformType | HasLiteralType,
54505458
Partial = ReadPartial | WritePartial

src/compiler/utilities.ts

+2
Original file line numberDiff line numberDiff line change
@@ -5038,6 +5038,7 @@ namespace ts {
50385038
case SyntaxKind.PublicKeyword: return ModifierFlags.Public;
50395039
case SyntaxKind.ProtectedKeyword: return ModifierFlags.Protected;
50405040
case SyntaxKind.PrivateKeyword: return ModifierFlags.Private;
5041+
case SyntaxKind.SealedKeyword: return ModifierFlags.Sealed;
50415042
case SyntaxKind.AbstractKeyword: return ModifierFlags.Abstract;
50425043
case SyntaxKind.AccessorKeyword: return ModifierFlags.Accessor;
50435044
case SyntaxKind.ExportKeyword: return ModifierFlags.Export;
@@ -5580,6 +5581,7 @@ namespace ts {
55805581
const checkFlags = (s as TransientSymbol).checkFlags;
55815582
const accessModifier = checkFlags & CheckFlags.ContainsPrivate ? ModifierFlags.Private :
55825583
checkFlags & CheckFlags.ContainsPublic ? ModifierFlags.Public :
5584+
checkFlags & CheckFlags.ContainsSealed ? ModifierFlags.Sealed :
55835585
ModifierFlags.Protected;
55845586
const staticModifier = checkFlags & CheckFlags.ContainsStatic ? ModifierFlags.Static : 0;
55855587
return accessModifier | staticModifier;

src/compiler/utilitiesPublic.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1231,6 +1231,7 @@ namespace ts {
12311231
case SyntaxKind.PublicKeyword:
12321232
case SyntaxKind.PrivateKeyword:
12331233
case SyntaxKind.ProtectedKeyword:
1234+
case SyntaxKind.SealedKeyword:
12341235
case SyntaxKind.ReadonlyKeyword:
12351236
case SyntaxKind.StaticKeyword:
12361237
case SyntaxKind.OutKeyword:
@@ -1250,6 +1251,7 @@ namespace ts {
12501251
return isParameterPropertyModifier(idToken) ||
12511252
idToken === SyntaxKind.StaticKeyword ||
12521253
idToken === SyntaxKind.OverrideKeyword ||
1254+
idToken === SyntaxKind.SealedKeyword ||
12531255
idToken === SyntaxKind.AccessorKeyword;
12541256
}
12551257

src/harness/fourslashInterfaceImpl.ts

+2
Original file line numberDiff line numberDiff line change
@@ -1241,6 +1241,7 @@ namespace FourSlashInterface {
12411241
case "private":
12421242
case "protected":
12431243
case "public":
1244+
case "sealed":
12441245
case "abstract":
12451246
case "any":
12461247
case "boolean":
@@ -1281,6 +1282,7 @@ namespace FourSlashInterface {
12811282
"protected",
12821283
"public",
12831284
"readonly",
1285+
"sealed",
12841286
"set",
12851287
"static",
12861288
].map(keywordEntry);

src/services/completions.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -3227,6 +3227,9 @@ namespace ts.Completions {
32273227
case "private":
32283228
classElementModifierFlags = classElementModifierFlags | ModifierFlags.Private;
32293229
break;
3230+
case "sealed":
3231+
classElementModifierFlags = classElementModifierFlags | ModifierFlags.Sealed;
3232+
break;
32303233
case "static":
32313234
classElementModifierFlags = classElementModifierFlags | ModifierFlags.Static;
32323235
break;
@@ -3240,7 +3243,7 @@ namespace ts.Completions {
32403243
}
32413244

32423245
// No member list for private methods
3243-
if (!(classElementModifierFlags & ModifierFlags.Private)) {
3246+
if (!(classElementModifierFlags & (ModifierFlags.Private | ModifierFlags.Sealed))) {
32443247
// List of property symbols of base type that are not private and already implemented
32453248
const baseTypeNodes = isClassLike(decl) && classElementModifierFlags & ModifierFlags.Override ? singleElementArray(getEffectiveBaseTypeNode(decl)) : getAllSuperTypeNodes(decl);
32463249
const baseSymbols = flatMap(baseTypeNodes, baseTypeNode => {
@@ -3490,6 +3493,7 @@ namespace ts.Completions {
34903493
case SyntaxKind.InterfaceKeyword:
34913494
case SyntaxKind.LetKeyword:
34923495
case SyntaxKind.PrivateKeyword:
3496+
case SyntaxKind.SealedKeyword:
34933497
case SyntaxKind.ProtectedKeyword:
34943498
case SyntaxKind.PublicKeyword:
34953499
case SyntaxKind.StaticKeyword:
@@ -3927,6 +3931,7 @@ namespace ts.Completions {
39273931
case SyntaxKind.PrivateKeyword:
39283932
case SyntaxKind.ProtectedKeyword:
39293933
case SyntaxKind.PublicKeyword:
3934+
case SyntaxKind.SealedKeyword:
39303935
case SyntaxKind.ReadonlyKeyword:
39313936
case SyntaxKind.StringKeyword:
39323937
case SyntaxKind.SymbolKeyword:

0 commit comments

Comments
 (0)