@@ -12405,17 +12405,32 @@ func (c *Checker) checkNullishCoalesceOperands(left *ast.Node, right *ast.Node)
12405
12405
if ast.IsBinaryExpression(right) && ast.IsLogicalBinaryOperator(right.AsBinaryExpression().OperatorToken.Kind) {
12406
12406
c.grammarErrorOnNode(right, diagnostics.X_0_and_1_operations_cannot_be_mixed_without_parentheses, scanner.TokenToString(right.AsBinaryExpression().OperatorToken.Kind), scanner.TokenToString(ast.KindQuestionQuestionToken))
12407
12407
}
12408
+ c.checkNullishCoalesceOperandLeft(left)
12409
+ c.checkNullishCoalesceOperandRight(right)
12410
+ }
12411
+
12412
+ func (c *Checker) checkNullishCoalesceOperandLeft(left *ast.Node) {
12408
12413
leftTarget := ast.SkipOuterExpressions(left, ast.OEKAll)
12409
12414
nullishSemantics := c.getSyntacticNullishnessSemantics(leftTarget)
12410
12415
if nullishSemantics != PredicateSemanticsSometimes {
12411
- if left.Parent.Parent.Kind == ast.KindBinaryExpression {
12412
- c.error(leftTarget, diagnostics.This_binary_expression_is_never_nullish_Are_you_missing_parentheses )
12416
+ if nullishSemantics == PredicateSemanticsAlways {
12417
+ c.error(leftTarget, diagnostics.This_expression_is_always_nullish )
12413
12418
} else {
12414
- if nullishSemantics == PredicateSemanticsAlways {
12415
- c.error(leftTarget, diagnostics.This_expression_is_always_nullish)
12416
- } else {
12417
- c.error(leftTarget, diagnostics.Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish)
12418
- }
12419
+ c.error(leftTarget, diagnostics.Right_operand_of_is_unreachable_because_the_left_operand_is_never_nullish)
12420
+ }
12421
+ }
12422
+ }
12423
+
12424
+ func (c *Checker) checkNullishCoalesceOperandRight(right *ast.Node) {
12425
+ binaryExpression := right.Parent
12426
+ if binaryExpression.Parent != nil && ast.IsBinaryExpression(binaryExpression.Parent) && binaryExpression.Parent.AsBinaryExpression().OperatorToken.Kind == ast.KindQuestionQuestionToken {
12427
+ rightTarget := ast.SkipOuterExpressions(right, ast.OEKAll)
12428
+ nullishSemantics := c.getSyntacticNullishnessSemantics(rightTarget)
12429
+ switch nullishSemantics {
12430
+ case PredicateSemanticsAlways:
12431
+ c.error(rightTarget, diagnostics.This_expression_is_always_nullish)
12432
+ case PredicateSemanticsNever:
12433
+ c.error(rightTarget, diagnostics.This_expression_is_never_nullish)
12419
12434
}
12420
12435
}
12421
12436
}
@@ -15393,9 +15408,7 @@ func (c *Checker) addDeclarationToLateBoundSymbol(symbol *ast.Symbol, member *as
15393
15408
symbol.Declarations = append(symbol.Declarations, member)
15394
15409
}
15395
15410
if symbolFlags&ast.SymbolFlagsValue != 0 {
15396
- if symbol.ValueDeclaration == nil || symbol.ValueDeclaration.Kind != member.Kind {
15397
- symbol.ValueDeclaration = member
15398
- }
15411
+ binder.SetValueDeclaration(symbol, member)
15399
15412
}
15400
15413
}
15401
15414
@@ -15700,14 +15713,14 @@ func (c *Checker) getWriteTypeOfSymbolWithDeferredType(symbol *ast.Symbol) *Type
15700
15713
// properties deriving from set accessors will either pre-compute or defer the union or
15701
15714
// intersection of the writeTypes of their constituents.
15702
15715
func (c *Checker) getWriteTypeOfSymbol(symbol *ast.Symbol) *Type {
15703
- if symbol.Flags&ast.SymbolFlagsProperty != 0 {
15704
- if symbol.CheckFlags&ast.CheckFlagsSyntheticProperty != 0 {
15705
- if symbol.CheckFlags&ast.CheckFlagsDeferredType != 0 {
15706
- return c.getWriteTypeOfSymbolWithDeferredType(symbol)
15707
- }
15708
- links := c.valueSymbolLinks.Get(symbol)
15709
- return core.OrElse(links.writeType, links.resolvedType)
15716
+ if symbol.CheckFlags&ast.CheckFlagsSyntheticProperty != 0 {
15717
+ if symbol.CheckFlags&ast.CheckFlagsDeferredType != 0 {
15718
+ return c.getWriteTypeOfSymbolWithDeferredType(symbol)
15710
15719
}
15720
+ links := c.valueSymbolLinks.Get(symbol)
15721
+ return core.OrElse(links.writeType, links.resolvedType)
15722
+ }
15723
+ if symbol.Flags&ast.SymbolFlagsProperty != 0 {
15711
15724
return c.removeMissingType(c.getTypeOfSymbol(symbol), symbol.Flags&ast.SymbolFlagsOptional != 0)
15712
15725
}
15713
15726
if symbol.Flags&ast.SymbolFlagsAccessor != 0 {
@@ -20598,6 +20611,7 @@ func (c *Checker) getUnionOrIntersectionProperty(t *Type, name string, skipObjec
20598
20611
}
20599
20612
20600
20613
func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name string, skipObjectFunctionPropertyAugment bool) *ast.Symbol {
20614
+ propFlags := ast.SymbolFlagsNone
20601
20615
var singleProp *ast.Symbol
20602
20616
var propSet collections.OrderedSet[*ast.Symbol]
20603
20617
var indexTypes []*Type
@@ -20627,6 +20641,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20627
20641
}
20628
20642
if singleProp == nil {
20629
20643
singleProp = prop
20644
+ propFlags = core.OrElse(prop.Flags&ast.SymbolFlagsAccessor, ast.SymbolFlagsProperty)
20630
20645
} else if prop != singleProp {
20631
20646
isInstantiation := c.getTargetSymbol(prop) == c.getTargetSymbol(singleProp)
20632
20647
// If the symbols are instances of one another with identical types - consider the symbols
@@ -20643,6 +20658,13 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20643
20658
}
20644
20659
propSet.Add(prop)
20645
20660
}
20661
+ // classes created by mixins are represented as intersections
20662
+ // and overriding a property in a derived class redefines it completely at runtime
20663
+ // so a get accessor can't be merged with a set accessor in a base class,
20664
+ // for that reason the accessor flags are only used when they are the same in all constituents
20665
+ if propFlags&ast.SymbolFlagsAccessor != 0 && (prop.Flags&ast.SymbolFlagsAccessor != (propFlags & ast.SymbolFlagsAccessor)) {
20666
+ propFlags = (propFlags &^ ast.SymbolFlagsAccessor) | ast.SymbolFlagsProperty
20667
+ }
20646
20668
}
20647
20669
if isUnion && c.isReadonlySymbol(prop) {
20648
20670
checkFlags |= ast.CheckFlagsReadonly
@@ -20670,6 +20692,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20670
20692
indexInfo = c.getApplicableIndexInfoForName(t, name)
20671
20693
}
20672
20694
if indexInfo != nil {
20695
+ propFlags = propFlags&^ast.SymbolFlagsAccessor | ast.SymbolFlagsProperty
20673
20696
checkFlags |= ast.CheckFlagsWritePartial | (core.IfElse(indexInfo.isReadonly, ast.CheckFlagsReadonly, 0))
20674
20697
if isTupleType(t) {
20675
20698
indexType := c.getRestTypeOfTupleType(t)
@@ -20762,7 +20785,7 @@ func (c *Checker) createUnionOrIntersectionProperty(containingType *Type, name s
20762
20785
propTypes = append(propTypes, t)
20763
20786
}
20764
20787
propTypes = append(propTypes, indexTypes...)
20765
- result := c.newSymbolEx(ast.SymbolFlagsProperty |optionalFlag, name, checkFlags|syntheticFlag)
20788
+ result := c.newSymbolEx(propFlags |optionalFlag, name, checkFlags|syntheticFlag)
20766
20789
result.Declarations = declarations
20767
20790
if !hasNonUniformValueDeclaration && firstValueDeclaration != nil {
20768
20791
result.ValueDeclaration = firstValueDeclaration
@@ -23059,6 +23082,8 @@ func (c *Checker) computeEnumMemberValues(node *ast.Node) {
23059
23082
func (c *Checker) computeEnumMemberValue(member *ast.Node, autoValue jsnum.Number, previous *ast.Node) evaluator.Result {
23060
23083
if ast.IsComputedNonLiteralName(member.Name()) {
23061
23084
c.error(member.Name(), diagnostics.Computed_property_names_are_not_allowed_in_enums)
23085
+ } else if ast.IsBigIntLiteral(member.Name()) {
23086
+ c.error(member.Name(), diagnostics.An_enum_member_cannot_have_a_numeric_name)
23062
23087
} else {
23063
23088
text := ast.GetTextOfPropertyName(member.Name())
23064
23089
if isNumericLiteralName(text) && !isInfinityOrNaNString(text) {
0 commit comments