@@ -10592,7 +10592,7 @@ func (c *Checker) checkIdentifier(node *ast.Node, checkMode CheckMode) *Type {
10592
10592
return c.errorType
10593
10593
}
10594
10594
if symbol == c.argumentsSymbol {
10595
- if c.isInPropertyInitializerOrClassStaticBlock(node) {
10595
+ if c.isInPropertyInitializerOrClassStaticBlock(node, true /*ignoreArrowFunctions*/ ) {
10596
10596
c.error(node, diagnostics.X_arguments_cannot_be_referenced_in_property_initializers_or_class_static_initialization_blocks)
10597
10597
return c.errorType
10598
10598
}
@@ -11224,7 +11224,7 @@ func (c *Checker) checkPropertyNotUsedBeforeDeclaration(prop *ast.Symbol, node *
11224
11224
}
11225
11225
var diagnostic *ast.Diagnostic
11226
11226
declarationName := right.Text()
11227
- if c.isInPropertyInitializerOrClassStaticBlock(node) &&
11227
+ if c.isInPropertyInitializerOrClassStaticBlock(node, false /*ignoreArrowFunctions*/ ) &&
11228
11228
!c.isOptionalPropertyDeclaration(valueDeclaration) &&
11229
11229
!(ast.IsAccessExpression(node) && ast.IsAccessExpression(node.Expression())) &&
11230
11230
!c.isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) &&
@@ -12415,17 +12415,32 @@ func (c *Checker) checkNullishCoalesceOperands(left *ast.Node, right *ast.Node)
12415
12415
if ast.IsBinaryExpression(right) && ast.IsLogicalBinaryOperator(right.AsBinaryExpression().OperatorToken.Kind) {
12416
12416
c.grammarErrorOnNode(right, diagnostics.X_0_and_1_operations_cannot_be_mixed_without_parentheses, scanner.TokenToString(right.AsBinaryExpression().OperatorToken.Kind), scanner.TokenToString(ast.KindQuestionQuestionToken))
12417
12417
}
12418
+ c.checkNullishCoalesceOperandLeft(left)
12419
+ c.checkNullishCoalesceOperandRight(right)
12420
+ }
12421
+
12422
+ func (c *Checker) checkNullishCoalesceOperandLeft(left *ast.Node) {
12418
12423
leftTarget := ast.SkipOuterExpressions(left, ast.OEKAll)
12419
12424
nullishSemantics := c.getSyntacticNullishnessSemantics(leftTarget)
12420
12425
if nullishSemantics != PredicateSemanticsSometimes {
12421
- if left.Parent.Parent.Kind == ast.KindBinaryExpression {
12422
- c.error(leftTarget, diagnostics.This_binary_expression_is_never_nullish_Are_you_missing_parentheses )
12426
+ if nullishSemantics == PredicateSemanticsAlways {
12427
+ c.error(leftTarget, diagnostics.This_expression_is_always_nullish )
12423
12428
} else {
12424
- if nullishSemantics == PredicateSemanticsAlways {
12425
- c.error(leftTarget, diagnostics.This_expression_is_always_nullish)
12426
- } else {
12427
- c.error(leftTarget, diagnostics.Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish)
12428
- }
12429
+ c.error(leftTarget, diagnostics.Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish)
12430
+ }
12431
+ }
12432
+ }
12433
+
12434
+ func (c *Checker) checkNullishCoalesceOperandRight(right *ast.Node) {
12435
+ binaryExpression := right.Parent
12436
+ if binaryExpression.Parent != nil && ast.IsBinaryExpression(binaryExpression.Parent) && binaryExpression.Parent.AsBinaryExpression().OperatorToken.Kind == ast.KindQuestionQuestionToken {
12437
+ rightTarget := ast.SkipOuterExpressions(right, ast.OEKAll)
12438
+ nullishSemantics := c.getSyntacticNullishnessSemantics(rightTarget)
12439
+ switch nullishSemantics {
12440
+ case PredicateSemanticsAlways:
12441
+ c.error(rightTarget, diagnostics.This_expression_is_always_nullish)
12442
+ case PredicateSemanticsNever:
12443
+ c.error(rightTarget, diagnostics.This_expression_is_never_nullish)
12429
12444
}
12430
12445
}
12431
12446
}
@@ -13145,25 +13160,19 @@ func (c *Checker) checkShorthandPropertyAssignment(node *ast.Node, inDestructuri
13145
13160
return expressionType
13146
13161
}
13147
13162
13148
- func (c *Checker) isInPropertyInitializerOrClassStaticBlock(node *ast.Node) bool {
13163
+ func (c *Checker) isInPropertyInitializerOrClassStaticBlock(node *ast.Node, ignoreArrowFunctions bool ) bool {
13149
13164
return ast.FindAncestorOrQuit(node, func(node *ast.Node) ast.FindAncestorResult {
13150
13165
switch node.Kind {
13151
- case ast.KindPropertyDeclaration:
13166
+ case ast.KindPropertyDeclaration, ast.KindClassStaticBlockDeclaration :
13152
13167
return ast.FindAncestorTrue
13153
- case ast.KindPropertyAssignment, ast.KindMethodDeclaration, ast.KindGetAccessor, ast.KindSetAccessor, ast.KindSpreadAssignment,
13154
- ast.KindComputedPropertyName, ast.KindTemplateSpan, ast.KindJsxExpression, ast.KindJsxAttribute, ast.KindJsxAttributes,
13155
- ast.KindJsxSpreadAttribute, ast.KindJsxOpeningElement, ast.KindExpressionWithTypeArguments, ast.KindHeritageClause:
13156
- return ast.FindAncestorFalse
13157
- case ast.KindArrowFunction, ast.KindExpressionStatement:
13158
- if ast.IsBlock(node.Parent) && ast.IsClassStaticBlockDeclaration(node.Parent.Parent) {
13159
- return ast.FindAncestorTrue
13160
- }
13168
+ case ast.KindTypeQuery, ast.KindJsxClosingElement:
13161
13169
return ast.FindAncestorQuit
13170
+ case ast.KindArrowFunction:
13171
+ return core.IfElse(ignoreArrowFunctions, ast.FindAncestorFalse, ast.FindAncestorQuit)
13172
+ case ast.KindBlock:
13173
+ return core.IfElse(ast.IsFunctionLikeDeclaration(node.Parent) && node.Parent.Kind != ast.KindArrowFunction, ast.FindAncestorQuit, ast.FindAncestorFalse)
13162
13174
default:
13163
- if ast.IsExpressionNode(node) {
13164
- return ast.FindAncestorFalse
13165
- }
13166
- return ast.FindAncestorQuit
13175
+ return ast.FindAncestorFalse
13167
13176
}
13168
13177
}) != nil
13169
13178
}
@@ -15409,9 +15418,7 @@ func (c *Checker) addDeclarationToLateBoundSymbol(symbol *ast.Symbol, member *as
15409
15418
symbol.Declarations = append(symbol.Declarations, member)
15410
15419
}
15411
15420
if symbolFlags&ast.SymbolFlagsValue != 0 {
15412
- if symbol.ValueDeclaration == nil || symbol.ValueDeclaration.Kind != member.Kind {
15413
- symbol.ValueDeclaration = member
15414
- }
15421
+ binder.SetValueDeclaration(symbol, member)
15415
15422
}
15416
15423
}
15417
15424
@@ -15716,14 +15723,14 @@ func (c *Checker) getWriteTypeOfSymbolWithDeferredType(symbol *ast.Symbol) *Type
15716
15723
// properties deriving from set accessors will either pre-compute or defer the union or
15717
15724
// intersection of the writeTypes of their constituents.
15718
15725
func (c *Checker) getWriteTypeOfSymbol(symbol *ast.Symbol) *Type {
15719
- if symbol.Flags&ast.SymbolFlagsProperty != 0 {
15720
- if symbol.CheckFlags&ast.CheckFlagsSyntheticProperty != 0 {
15721
- if symbol.CheckFlags&ast.CheckFlagsDeferredType != 0 {
15722
- return c.getWriteTypeOfSymbolWithDeferredType(symbol)
15723
- }
15724
- links := c.valueSymbolLinks.Get(symbol)
15725
- return core.OrElse(links.writeType, links.resolvedType)
15726
+ if symbol.CheckFlags&ast.CheckFlagsSyntheticProperty != 0 {
15727
+ if symbol.CheckFlags&ast.CheckFlagsDeferredType != 0 {
15728
+ return c.getWriteTypeOfSymbolWithDeferredType(symbol)
15726
15729
}
15730
+ links := c.valueSymbolLinks.Get(symbol)
15731
+ return core.OrElse(links.writeType, links.resolvedType)
15732
+ }
15733
+ if symbol.Flags&ast.SymbolFlagsProperty != 0 {
15727
15734
return c.removeMissingType(c.getTypeOfSymbol(symbol), symbol.Flags&ast.SymbolFlagsOptional != 0)
15728
15735
}
15729
15736
if symbol.Flags&ast.SymbolFlagsAccessor != 0 {
@@ -20614,6 +20621,7 @@ func (c *Checker) getUnionOrIntersectionProperty(t *Type, name string, skipObjec
20614
20621
}
20615
20622
20616
20623
func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name string, skipObjectFunctionPropertyAugment bool) *ast.Symbol {
20624
+ propFlags := ast.SymbolFlagsNone
20617
20625
var singleProp *ast.Symbol
20618
20626
var propSet collections.OrderedSet[*ast.Symbol]
20619
20627
var indexTypes []*Type
@@ -20643,6 +20651,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20643
20651
}
20644
20652
if singleProp == nil {
20645
20653
singleProp = prop
20654
+ propFlags = core.OrElse(prop.Flags&ast.SymbolFlagsAccessor, ast.SymbolFlagsProperty)
20646
20655
} else if prop != singleProp {
20647
20656
isInstantiation := c.getTargetSymbol(prop) == c.getTargetSymbol(singleProp)
20648
20657
// If the symbols are instances of one another with identical types - consider the symbols
@@ -20659,6 +20668,13 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20659
20668
}
20660
20669
propSet.Add(prop)
20661
20670
}
20671
+ // classes created by mixins are represented as intersections
20672
+ // and overriding a property in a derived class redefines it completely at runtime
20673
+ // so a get accessor can't be merged with a set accessor in a base class,
20674
+ // for that reason the accessor flags are only used when they are the same in all constituents
20675
+ if propFlags&ast.SymbolFlagsAccessor != 0 && (prop.Flags&ast.SymbolFlagsAccessor != (propFlags & ast.SymbolFlagsAccessor)) {
20676
+ propFlags = (propFlags &^ ast.SymbolFlagsAccessor) | ast.SymbolFlagsProperty
20677
+ }
20662
20678
}
20663
20679
if isUnion && c.isReadonlySymbol(prop) {
20664
20680
checkFlags |= ast.CheckFlagsReadonly
@@ -20686,6 +20702,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20686
20702
indexInfo = c.getApplicableIndexInfoForName(t, name)
20687
20703
}
20688
20704
if indexInfo != nil {
20705
+ propFlags = propFlags&^ast.SymbolFlagsAccessor | ast.SymbolFlagsProperty
20689
20706
checkFlags |= ast.CheckFlagsWritePartial | (core.IfElse(indexInfo.isReadonly, ast.CheckFlagsReadonly, 0))
20690
20707
if isTupleType(t) {
20691
20708
indexType := c.getRestTypeOfTupleType(t)
@@ -20778,7 +20795,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20778
20795
propTypes = append(propTypes, t)
20779
20796
}
20780
20797
propTypes = append(propTypes, indexTypes...)
20781
- result := c.newSymbolEx(ast.SymbolFlagsProperty |optionalFlag, name, checkFlags|syntheticFlag)
20798
+ result := c.newSymbolEx(propFlags |optionalFlag, name, checkFlags|syntheticFlag)
20782
20799
result.Declarations = declarations
20783
20800
if !hasNonUniformValueDeclaration && firstValueDeclaration != nil {
20784
20801
result.ValueDeclaration = firstValueDeclaration
@@ -23075,6 +23092,8 @@ func (c *Checker) computeEnumMemberValues(node *ast.Node) {
23075
23092
func (c *Checker) computeEnumMemberValue(member *ast.Node, autoValue jsnum.Number, previous *ast.Node) evaluator.Result {
23076
23093
if ast.IsComputedNonLiteralName(member.Name()) {
23077
23094
c.error(member.Name(), diagnostics.Computed_property_names_are_not_allowed_in_enums)
23095
+ } else if ast.IsBigIntLiteral(member.Name()) {
23096
+ c.error(member.Name(), diagnostics.An_enum_member_cannot_have_a_numeric_name)
23078
23097
} else {
23079
23098
text := ast.GetTextOfPropertyName(member.Name())
23080
23099
if isNumericLiteralName(text) && !isInfinityOrNaNString(text) {
0 commit comments