@@ -346,6 +346,7 @@ namespace ts {
346
346
const compilerOptions = host.getCompilerOptions();
347
347
const languageVersion = getEmitScriptTarget(compilerOptions);
348
348
const moduleKind = getEmitModuleKind(compilerOptions);
349
+ const useDefineForClassFields = getUseDefineForClassFields(compilerOptions);
349
350
const allowSyntheticDefaultImports = getAllowSyntheticDefaultImports(compilerOptions);
350
351
const strictNullChecks = getStrictOptionValue(compilerOptions, "strictNullChecks");
351
352
const strictFunctionTypes = getStrictOptionValue(compilerOptions, "strictFunctionTypes");
@@ -1501,7 +1502,7 @@ namespace ts {
1501
1502
}
1502
1503
else if (isParameterPropertyDeclaration(declaration, declaration.parent)) {
1503
1504
// foo = this.bar is illegal in esnext+useDefineForClassFields when bar is a parameter property
1504
- return !(compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions. useDefineForClassFields
1505
+ return !(compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields
1505
1506
&& getContainingClass(declaration) === getContainingClass(usage)
1506
1507
&& isUsedInFunctionOrInstanceProperty(usage, declaration));
1507
1508
}
@@ -1532,7 +1533,7 @@ namespace ts {
1532
1533
return true;
1533
1534
}
1534
1535
if (isUsedInFunctionOrInstanceProperty(usage, declaration)) {
1535
- if (compilerOptions.target === ScriptTarget.ESNext && !!compilerOptions. useDefineForClassFields
1536
+ if (compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields
1536
1537
&& getContainingClass(declaration)
1537
1538
&& (isPropertyDeclaration(declaration) || isParameterPropertyDeclaration(declaration, declaration.parent))) {
1538
1539
return !isPropertyImmediatelyReferencedWithinDeclaration(declaration, usage, /*stopAtAnyPropertyDeclaration*/ true);
@@ -1680,7 +1681,7 @@ namespace ts {
1680
1681
case SyntaxKind.PropertyDeclaration:
1681
1682
// static properties in classes introduce temporary variables
1682
1683
if (hasStaticModifier(node)) {
1683
- return target < ScriptTarget.ESNext || !compilerOptions. useDefineForClassFields;
1684
+ return target < ScriptTarget.ESNext || !useDefineForClassFields;
1684
1685
}
1685
1686
return requiresScopeChangeWorker((node as PropertyDeclaration).name);
1686
1687
default:
@@ -2098,7 +2099,7 @@ namespace ts {
2098
2099
2099
2100
// Perform extra checks only if error reporting was requested
2100
2101
if (nameNotFoundMessage) {
2101
- if (propertyWithInvalidInitializer && !(compilerOptions.target === ScriptTarget.ESNext && compilerOptions. useDefineForClassFields)) {
2102
+ if (propertyWithInvalidInitializer && !(compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields)) {
2102
2103
// We have a match, but the reference occurred within a property initializer and the identifier also binds
2103
2104
// to a local variable in the constructor where the code will be emitted. Note that this is actually allowed
2104
2105
// with ESNext+useDefineForClassFields because the scope semantics are different.
@@ -24260,7 +24261,7 @@ namespace ts {
24260
24261
break;
24261
24262
case SyntaxKind.PropertyDeclaration:
24262
24263
case SyntaxKind.PropertySignature:
24263
- if (hasSyntacticModifier(container, ModifierFlags.Static) && !(compilerOptions.target === ScriptTarget.ESNext && compilerOptions. useDefineForClassFields)) {
24264
+ if (hasSyntacticModifier(container, ModifierFlags.Static) && !(compilerOptions.target === ScriptTarget.ESNext && useDefineForClassFields)) {
24264
24265
error(node, Diagnostics.this_cannot_be_referenced_in_a_static_property_initializer);
24265
24266
// do not return here so in case if lexical this is captured - it will be reflected in flags on NodeLinks
24266
24267
}
@@ -27057,6 +27058,30 @@ namespace ts {
27057
27058
if (assignmentKind && lexicallyScopedSymbol && lexicallyScopedSymbol.valueDeclaration && isMethodDeclaration(lexicallyScopedSymbol.valueDeclaration)) {
27058
27059
grammarErrorOnNode(right, Diagnostics.Cannot_assign_to_private_method_0_Private_methods_are_not_writable, idText(right));
27059
27060
}
27061
+
27062
+ if (lexicallyScopedSymbol?.valueDeclaration && (compilerOptions.target === ScriptTarget.ESNext && !useDefineForClassFields)) {
27063
+ const lexicalClass = getContainingClass(lexicallyScopedSymbol.valueDeclaration);
27064
+ const parentStaticFieldInitializer = findAncestor(node, (n) => {
27065
+ if (n === lexicalClass) return "quit";
27066
+ if (isPropertyDeclaration(n.parent) && hasStaticModifier(n.parent) && n.parent.initializer === n && n.parent.parent === lexicalClass) {
27067
+ return true;
27068
+ }
27069
+ return false;
27070
+ });
27071
+ if (parentStaticFieldInitializer) {
27072
+ const parentStaticFieldInitializerSymbol = getSymbolOfNode(parentStaticFieldInitializer.parent);
27073
+ Debug.assert(parentStaticFieldInitializerSymbol, "Initializer without declaration symbol");
27074
+ const diagnostic = error(node,
27075
+ Diagnostics.Property_0_may_not_be_used_in_a_static_property_s_initializer_in_the_same_class_when_target_is_esnext_and_useDefineForClassFields_is_false,
27076
+ symbolName(lexicallyScopedSymbol));
27077
+ addRelatedInfo(diagnostic,
27078
+ createDiagnosticForNode(parentStaticFieldInitializer.parent,
27079
+ Diagnostics.Initializer_for_property_0,
27080
+ symbolName(parentStaticFieldInitializerSymbol))
27081
+ );
27082
+ }
27083
+ }
27084
+
27060
27085
if (isAnyLike) {
27061
27086
if (lexicallyScopedSymbol) {
27062
27087
return apparentType;
@@ -33134,7 +33159,7 @@ namespace ts {
33134
33159
// - The constructor declares parameter properties
33135
33160
// or the containing class declares instance member variables with initializers.
33136
33161
const superCallShouldBeFirst =
33137
- (compilerOptions.target !== ScriptTarget.ESNext || !compilerOptions. useDefineForClassFields) &&
33162
+ (compilerOptions.target !== ScriptTarget.ESNext || !useDefineForClassFields) &&
33138
33163
(some((<ClassDeclaration>node.parent).members, isInstancePropertyWithInitializerOrPrivateIdentifierProperty) ||
33139
33164
some(node.parameters, p => hasSyntacticModifier(p, ModifierFlags.ParameterPropertyModifier)));
33140
33165
@@ -37142,7 +37167,7 @@ namespace ts {
37142
37167
Diagnostics._0_is_defined_as_a_property_in_class_1_but_is_overridden_here_in_2_as_an_accessor;
37143
37168
error(getNameOfDeclaration(derived.valueDeclaration) || derived.valueDeclaration, errorMessage, symbolToString(base), typeToString(baseType), typeToString(type));
37144
37169
}
37145
- else if (compilerOptions. useDefineForClassFields) {
37170
+ else if (useDefineForClassFields) {
37146
37171
const uninitialized = derived.declarations?.find(d => d.kind === SyntaxKind.PropertyDeclaration && !(d as PropertyDeclaration).initializer);
37147
37172
if (uninitialized
37148
37173
&& !(derived.flags & SymbolFlags.Transient)
0 commit comments