@@ -5462,7 +5462,7 @@ func (c *Checker) checkVariableLikeDeclaration(node *ast.Node) {
5462
5462
if ast.IsVariableDeclaration(node) || ast.IsBindingElement(node) {
5463
5463
c.checkVarDeclaredNamesNotShadowed(node)
5464
5464
}
5465
- // !!! c.checkCollisionsForDeclarationName(node, node.Name)
5465
+ c.checkCollisionsForDeclarationName(node, node.Name() )
5466
5466
}
5467
5467
}
5468
5468
@@ -6540,7 +6540,7 @@ func (c *Checker) reportUnusedBindingElements(node *ast.Node) {
6540
6540
func (c *Checker) reportUnusedVariableDeclarations(declarations []*ast.Node) {
6541
6541
for _, declaration := range declarations {
6542
6542
name := declaration.Name()
6543
- if name != nil {
6543
+ if name != nil && !ast.IsParameterPropertyDeclaration(declaration, declaration.Parent) && !ast.IsThisParameter(declaration) {
6544
6544
if ast.IsBindingPattern(name) {
6545
6545
c.reportUnusedBindingElements(name)
6546
6546
} else if c.isUnreferencedVariableDeclaration(declaration) {
@@ -9686,7 +9686,14 @@ func (c *Checker) assignBindingElementTypes(pattern *ast.Node, parentType *Type)
9686
9686
}
9687
9687
9688
9688
func (c *Checker) checkCollisionsForDeclarationName(node *ast.Node, name *ast.Node) {
9689
- // !!!
9689
+ switch {
9690
+ case name == nil:
9691
+ return
9692
+ case ast.IsClassLike(node):
9693
+ c.checkTypeNameIsReserved(name, diagnostics.Class_name_cannot_be_0)
9694
+ case ast.IsEnumDeclaration(node):
9695
+ c.checkTypeNameIsReserved(name, diagnostics.Enum_name_cannot_be_0)
9696
+ }
9690
9697
}
9691
9698
9692
9699
func (c *Checker) checkTypeOfExpression(node *ast.Node) *Type {
@@ -10739,7 +10746,47 @@ func (c *Checker) isUncalledFunctionReference(node *ast.Node, symbol *ast.Symbol
10739
10746
}
10740
10747
10741
10748
func (c *Checker) checkPropertyNotUsedBeforeDeclaration(prop *ast.Symbol, node *ast.Node, right *ast.Node) {
10742
- // !!!
10749
+ valueDeclaration := prop.ValueDeclaration
10750
+ if valueDeclaration == nil || ast.GetSourceFileOfNode(node).IsDeclarationFile {
10751
+ return
10752
+ }
10753
+ var diagnostic *ast.Diagnostic
10754
+ declarationName := right.Text()
10755
+ if c.isInPropertyInitializerOrClassStaticBlock(node) &&
10756
+ !c.isOptionalPropertyDeclaration(valueDeclaration) &&
10757
+ !(ast.IsAccessExpression(node) && ast.IsAccessExpression(node.Expression())) &&
10758
+ !c.isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) &&
10759
+ !(ast.IsMethodDeclaration(valueDeclaration) && c.getCombinedModifierFlagsCached(valueDeclaration)&ast.ModifierFlagsStatic != 0) &&
10760
+ (c.compilerOptions.UseDefineForClassFields.IsTrue() || !c.isPropertyDeclaredInAncestorClass(prop)) {
10761
+ diagnostic = c.error(right, diagnostics.Property_0_is_used_before_its_initialization, declarationName)
10762
+ } else if ast.IsClassDeclaration(valueDeclaration) && ast.IsTypeReferenceNode(node.Parent) && valueDeclaration.Flags&ast.NodeFlagsAmbient == 0 && !c.isBlockScopedNameDeclaredBeforeUse(valueDeclaration, right) {
10763
+ diagnostic = c.error(right, diagnostics.Class_0_used_before_its_declaration, declarationName)
10764
+ }
10765
+ if diagnostic != nil {
10766
+ diagnostic.AddRelatedInfo(NewDiagnosticForNode(valueDeclaration, diagnostics.X_0_is_declared_here, declarationName))
10767
+ }
10768
+ }
10769
+
10770
+ func (c *Checker) isOptionalPropertyDeclaration(node *ast.Node) bool {
10771
+ return ast.IsPropertyDeclaration(node) && !ast.HasAccessorModifier(node) && ast.IsQuestionToken(node.AsPropertyDeclaration().PostfixToken)
10772
+ }
10773
+
10774
+ func (c *Checker) isPropertyDeclaredInAncestorClass(prop *ast.Symbol) bool {
10775
+ if prop.Parent.Flags&ast.SymbolFlagsClass == 0 {
10776
+ return false
10777
+ }
10778
+ classType := c.getDeclaredTypeOfSymbol(prop.Parent)
10779
+ for {
10780
+ baseTypes := c.getBaseTypes(classType)
10781
+ if len(baseTypes) == 0 {
10782
+ return false
10783
+ }
10784
+ classType = baseTypes[0]
10785
+ superProperty := c.getPropertyOfType(classType, prop.Name)
10786
+ if superProperty != nil && superProperty.ValueDeclaration != nil {
10787
+ return true
10788
+ }
10789
+ }
10743
10790
}
10744
10791
10745
10792
/**
@@ -26834,7 +26881,7 @@ func (c *Checker) getContextualTypeForBindingElement(declaration *ast.Node, cont
26834
26881
parent := declaration.Parent.Parent
26835
26882
parentType := c.getContextualTypeForVariableLikeDeclaration(parent, contextFlags)
26836
26883
if parentType == nil {
26837
- if ast.IsBindingElement(parent) && parent.Initializer() != nil {
26884
+ if ! ast.IsBindingElement(parent) && parent.Initializer() != nil {
26838
26885
parentType = c.checkDeclarationInitializer(parent, core.IfElse(hasDotDotDotToken(declaration), CheckModeRestBindingElement, CheckModeNormal), nil)
26839
26886
}
26840
26887
}
@@ -27057,7 +27104,7 @@ func (c *Checker) getContextualTypeForBinaryOperand(node *ast.Node, contextFlags
27057
27104
// In an assignment expression, the right operand is contextually typed by the type of the left operand.
27058
27105
// If the binary operator has a symbol, this is an assignment declaration and there is no contextual type.
27059
27106
if node == binary.Right && binary.Symbol == nil {
27060
- return c.getTypeOfExpression (binary.Left)
27107
+ return c.getContextualTypeFromAssignmentTarget (binary.Left)
27061
27108
}
27062
27109
case ast.KindBarBarToken, ast.KindQuestionQuestionToken:
27063
27110
// When an || expression has a contextual type, the operands are contextually typed by that type, except
@@ -27078,6 +27125,33 @@ func (c *Checker) getContextualTypeForBinaryOperand(node *ast.Node, contextFlags
27078
27125
return nil
27079
27126
}
27080
27127
27128
+ func (c *Checker) getContextualTypeFromAssignmentTarget(node *ast.Node) *Type {
27129
+ if ast.IsAccessExpression(node) && node.Expression().Kind == ast.KindThisKeyword {
27130
+ var symbol *ast.Symbol
27131
+ if ast.IsPropertyAccessExpression(node) {
27132
+ name := node.Name()
27133
+ thisType := c.getTypeOfExpression(node.Expression())
27134
+ if ast.IsPrivateIdentifier(name) {
27135
+ symbol = c.getPropertyOfType(thisType, binder.GetSymbolNameForPrivateIdentifier(thisType.symbol, name.Text()))
27136
+ } else {
27137
+ symbol = c.getPropertyOfType(thisType, name.Text())
27138
+ }
27139
+ } else {
27140
+ propType := c.checkExpressionCached(node.AsElementAccessExpression().ArgumentExpression)
27141
+ if isTypeUsableAsPropertyName(propType) {
27142
+ symbol = c.getPropertyOfType(c.getTypeOfExpression(node.Expression()), getPropertyNameFromType(propType))
27143
+ }
27144
+ }
27145
+ if symbol != nil {
27146
+ d := symbol.ValueDeclaration
27147
+ if d != nil && (ast.IsPropertyDeclaration(d) || ast.IsPropertySignatureDeclaration(d)) && d.Type() == nil && d.Initializer() == nil {
27148
+ return nil
27149
+ }
27150
+ }
27151
+ }
27152
+ return c.getTypeOfExpression(node)
27153
+ }
27154
+
27081
27155
func (c *Checker) getContextualTypeForObjectLiteralElement(element *ast.Node, contextFlags ContextFlags) *Type {
27082
27156
objectLiteral := element.Parent
27083
27157
t := c.getApparentTypeOfContextualType(objectLiteral, contextFlags)
@@ -27544,16 +27618,19 @@ func (c *Checker) getESDecoratorCallSignature(decorator *ast.Node) *Signature {
27544
27618
// runtime-generated getter and setter that are added to the class/prototype. The `target` of a
27545
27619
// regular field decorator is always `undefined` as it isn't installed until it is initialized.
27546
27620
var targetType *Type
27621
+ if ast.HasAccessorModifier(node) {
27622
+ targetType = c.newClassAccessorDecoratorTargetType(thisType, valueType)
27623
+ } else {
27624
+ targetType = c.undefinedType
27625
+ }
27547
27626
// We wrap the "output type" depending on the declaration. For auto-accessors, we wrap the
27548
27627
// "output type" in a `ClassAccessorDecoratorResult<This, In, Out>` type, which allows for
27549
27628
// mutation of the runtime-generated getter and setter, as well as the injection of an
27550
27629
// initializer mutator. For regular fields, we wrap the "output type" in an initializer mutator.
27551
27630
var returnType *Type
27552
27631
if ast.HasAccessorModifier(node) {
27553
- targetType = c.newClassAccessorDecoratorTargetType(thisType, valueType)
27554
- returnType = targetType
27632
+ returnType = c.newClassAccessorDecoratorResultType(thisType, valueType)
27555
27633
} else {
27556
- targetType = c.undefinedType
27557
27634
returnType = c.newClassFieldDecoratorInitializerMutatorType(thisType, valueType)
27558
27635
}
27559
27636
contextType := c.newClassMemberDecoratorContextTypeForNode(node, thisType, valueType)
0 commit comments