Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion internal/ast/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -3969,7 +3969,7 @@ func HasContextSensitiveParameters(node *Node) bool {
// an implicit 'this' parameter which is subject to contextual typing.
parameter := core.FirstOrNil(node.Parameters())
if parameter == nil || !IsThisParameter(parameter) {
return true
return node.Flags&NodeFlagsContainsThis != 0
}
}
}
Expand Down
29 changes: 21 additions & 8 deletions internal/binder/binder.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ const (
ContainerFlagsIsInterface ContainerFlags = 1 << 6
ContainerFlagsIsObjectLiteralOrClassExpressionMethodOrAccessor ContainerFlags = 1 << 7
ContainerFlagsIsThisContainer ContainerFlags = 1 << 8
ContainerFlagsPropagatesThisKeyword ContainerFlags = 1 << 9
)

type ExpandoAssignmentInfo struct {
Expand Down Expand Up @@ -615,6 +616,9 @@ func (b *Binder) bind(node *ast.Node) bool {
node.AsIdentifier().FlowNode = b.currentFlow
b.checkContextualIdentifier(node)
case ast.KindThisKeyword, ast.KindSuperKeyword:
if node.Kind == ast.KindThisKeyword {
b.seenThisKeyword = true
}
node.AsKeywordExpression().FlowNode = b.currentFlow
case ast.KindQualifiedName:
if b.currentFlow != nil && ast.IsPartOfTypeQuery(node) {
Expand Down Expand Up @@ -1520,6 +1524,7 @@ func (b *Binder) bindContainer(node *ast.Node, containerFlags ContainerFlags) {
saveExceptionTarget := b.currentExceptionTarget
saveActiveLabelList := b.activeLabelList
saveHasExplicitReturn := b.hasExplicitReturn
saveSeenThisKeyword := b.seenThisKeyword
isImmediatelyInvoked := (containerFlags&ContainerFlagsIsFunctionExpression != 0 &&
!ast.HasSyntacticModifier(node, ast.ModifierFlagsAsync) &&
!isGeneratorFunctionExpression(node) &&
Expand All @@ -1545,9 +1550,10 @@ func (b *Binder) bindContainer(node *ast.Node, containerFlags ContainerFlags) {
b.currentContinueTarget = nil
b.activeLabelList = nil
b.hasExplicitReturn = false
b.seenThisKeyword = false
b.bindChildren(node)
// Reset all reachability check related flags on node (for incremental scenarios)
node.Flags &= ^ast.NodeFlagsReachabilityCheckFlags
// Reset flags (for incremental scenarios)
node.Flags &= ^(ast.NodeFlagsReachabilityCheckFlags | ast.NodeFlagsContainsThis)
if b.currentFlow.Flags&ast.FlowFlagsUnreachable == 0 && containerFlags&ContainerFlagsIsFunctionLike != 0 {
bodyData := node.BodyData()
if bodyData != nil && ast.NodeIsPresent(bodyData.Body) {
Expand All @@ -1558,11 +1564,13 @@ func (b *Binder) bindContainer(node *ast.Node, containerFlags ContainerFlags) {
bodyData.EndFlowNode = b.currentFlow
}
}
if b.seenThisKeyword {
node.Flags |= ast.NodeFlagsContainsThis
}
if node.Kind == ast.KindSourceFile {
node.Flags |= b.emitFlags
node.AsSourceFile().EndFlowNode = b.currentFlow
}

if b.currentReturnTarget != nil {
b.addAntecedent(b.currentReturnTarget, b.currentFlow)
b.currentFlow = b.finishFlowLabel(b.currentReturnTarget)
Expand All @@ -1579,7 +1587,13 @@ func (b *Binder) bindContainer(node *ast.Node, containerFlags ContainerFlags) {
b.currentExceptionTarget = saveExceptionTarget
b.activeLabelList = saveActiveLabelList
b.hasExplicitReturn = saveHasExplicitReturn
if containerFlags&ContainerFlagsPropagatesThisKeyword != 0 {
b.seenThisKeyword = saveSeenThisKeyword || b.seenThisKeyword
} else {
b.seenThisKeyword = saveSeenThisKeyword
}
} else if containerFlags&ContainerFlagsIsInterface != 0 {
saveSeenThisKeyword := b.seenThisKeyword
b.seenThisKeyword = false
b.bindChildren(node)
// ContainsThis cannot overlap with HasExtendedUnicodeEscape on Identifier
Expand All @@ -1588,6 +1602,7 @@ func (b *Binder) bindContainer(node *ast.Node, containerFlags ContainerFlags) {
} else {
node.Flags &= ^ast.NodeFlagsContainsThis
}
b.seenThisKeyword = saveSeenThisKeyword
} else {
b.bindChildren(node)
}
Expand Down Expand Up @@ -2525,16 +2540,14 @@ func GetContainerFlags(node *ast.Node) ContainerFlags {
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsIsObjectLiteralOrClassExpressionMethodOrAccessor | ContainerFlagsIsThisContainer
}
fallthrough
case ast.KindConstructor, ast.KindClassStaticBlockDeclaration:
case ast.KindConstructor, ast.KindFunctionDeclaration, ast.KindClassStaticBlockDeclaration:
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsIsThisContainer
case ast.KindMethodSignature, ast.KindCallSignature, ast.KindFunctionType, ast.KindConstructSignature, ast.KindConstructorType:
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike
case ast.KindFunctionDeclaration:
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsIsThisContainer
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsPropagatesThisKeyword
case ast.KindFunctionExpression:
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsIsFunctionExpression | ContainerFlagsIsThisContainer
case ast.KindArrowFunction:
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsIsFunctionExpression
return ContainerFlagsIsContainer | ContainerFlagsIsControlFlowContainer | ContainerFlagsHasLocals | ContainerFlagsIsFunctionLike | ContainerFlagsIsFunctionExpression | ContainerFlagsPropagatesThisKeyword
case ast.KindModuleBlock:
return ContainerFlagsIsControlFlowContainer
case ast.KindPropertyDeclaration:
Expand Down
31 changes: 22 additions & 9 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19849,10 +19849,10 @@ func mayReturnNever(fn *ast.Node) bool {

func (c *Checker) checkAndAggregateYieldOperandTypes(fn *ast.Node, checkMode CheckMode) (yieldTypes []*Type, nextTypes []*Type) {
isAsync := (getFunctionFlags(fn) & FunctionFlagsAsync) != 0
forEachYieldExpression(fn.Body(), func(yieldExpr *ast.Node) {
forEachYieldExpression(fn.Body(), func(yieldExpr *ast.Node) bool {
yieldExprType := c.undefinedWideningType
if yieldExpr.Expression() != nil {
yieldExprType = c.checkExpressionEx(yieldExpr.Expression(), checkMode)
yieldExprType = c.checkExpressionEx(yieldExpr.Expression(), checkMode & ^CheckModeSkipGenericFunctions)
}
if yieldExpr.Expression() != nil && c.isConstContext(yieldExpr.Expression()) {
yieldExprType = c.getRegularTypeOfLiteralType(yieldExprType)
Expand All @@ -19868,6 +19868,7 @@ func (c *Checker) checkAndAggregateYieldOperandTypes(fn *ast.Node, checkMode Che
if nextType != nil {
nextTypes = core.AppendIfUnique(nextTypes, nextType)
}
return false
})
return yieldTypes, nextTypes
}
Expand Down Expand Up @@ -29953,20 +29954,25 @@ func (c *Checker) instantiateContextualType(contextualType *Type, node *ast.Node
if contextFlags&ContextFlagsSignature != 0 && core.Some(inferenceContext.inferences, hasInferenceCandidatesOrDefault) {
// For contextual signatures we incorporate all inferences made so far, e.g. from return
// types as well as arguments to the left in a function call.
return c.instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper)
t := c.instantiateInstantiableTypes(contextualType, inferenceContext.nonFixingMapper)
if t.flags&TypeFlagsAnyOrUnknown == 0 {
return t
}
}
if inferenceContext.returnMapper != nil {
// For other purposes (e.g. determining whether to produce literal types) we only
// incorporate inferences made from the return type in a function call. We remove
// the 'boolean' type from the contextual type such that contextually typed boolean
// literals actually end up widening to 'boolean' (see #48363).
t := c.instantiateInstantiableTypes(contextualType, inferenceContext.returnMapper)
if t.flags&TypeFlagsUnion != 0 && containsType(t.Types(), c.regularFalseType) && containsType(t.Types(), c.regularTrueType) {
return c.filterType(t, func(t *Type) bool {
return t != c.regularFalseType && t != c.regularTrueType
})
if t.flags&TypeFlagsAnyOrUnknown == 0 {
if t.flags&TypeFlagsUnion != 0 && containsType(t.Types(), c.regularFalseType) && containsType(t.Types(), c.regularTrueType) {
return c.filterType(t, func(t *Type) bool {
return t != c.regularFalseType && t != c.regularTrueType
})
}
return t
}
return t
}
}
}
Expand Down Expand Up @@ -30045,12 +30051,15 @@ func (c *Checker) isContextSensitive(node *ast.Node) bool {
// It is possible to that node.expression is undefined (e.g <div x={} />)
expression := node.Expression()
return expression != nil && c.isContextSensitive(expression)
case ast.KindYieldExpression:
expression := node.Expression()
return expression != nil && c.isContextSensitive(expression)
}
return false
}

func (c *Checker) isContextSensitiveFunctionLikeDeclaration(node *ast.Node) bool {
return ast.HasContextSensitiveParameters(node) || c.hasContextSensitiveReturnExpression(node)
return ast.HasContextSensitiveParameters(node) || c.hasContextSensitiveReturnExpression(node) || c.hasContextSensitiveYieldExpression(node)
}

func (c *Checker) hasContextSensitiveReturnExpression(node *ast.Node) bool {
Expand All @@ -30069,6 +30078,10 @@ func (c *Checker) hasContextSensitiveReturnExpression(node *ast.Node) bool {
})
}

func (c *Checker) hasContextSensitiveYieldExpression(node *ast.Node) bool {
return getFunctionFlags(node)&FunctionFlagsGenerator != 0 && node.Body() != nil && forEachYieldExpression(node.Body(), c.isContextSensitive)
}

func (c *Checker) pushInferenceContext(node *ast.Node, context *InferenceContext) {
c.inferenceContextInfos = append(c.inferenceContextInfos, InferenceContextInfo{node, context})
}
Expand Down
17 changes: 10 additions & 7 deletions internal/checker/utilities.go
Original file line number Diff line number Diff line change
Expand Up @@ -1195,16 +1195,19 @@ func getSuperContainer(node *ast.Node, stopOnFunctions bool) *ast.Node {
}
}

func forEachYieldExpression(body *ast.Node, visitor func(expr *ast.Node)) {
func forEachYieldExpression(body *ast.Node, visitor func(expr *ast.Node) bool) bool {
var traverse func(*ast.Node) bool
traverse = func(node *ast.Node) bool {
switch node.Kind {
case ast.KindYieldExpression:
visitor(node)
if visitor(node) {
return true
}
operand := node.Expression()
if operand != nil {
traverse(operand)
if operand == nil {
return false
}
return traverse(operand)
case ast.KindEnumDeclaration, ast.KindInterfaceDeclaration, ast.KindModuleDeclaration, ast.KindTypeAliasDeclaration:
// These are not allowed inside a generator now, but eventually they may be allowed
// as local types. Regardless, skip them to avoid the work.
Expand All @@ -1213,17 +1216,17 @@ func forEachYieldExpression(body *ast.Node, visitor func(expr *ast.Node)) {
if node.Name() != nil && ast.IsComputedPropertyName(node.Name()) {
// Note that we will not include methods/accessors of a class because they would require
// first descending into the class. This is by design.
traverse(node.Name().Expression())
return traverse(node.Name().Expression())
}
} else if !ast.IsPartOfTypeNode(node) {
// This is the general case, which should include mostly expressions and statements.
// Also includes NodeArrays.
node.ForEachChild(traverse)
return node.ForEachChild(traverse)
}
}
return false
}
traverse(body)
return traverse(body)
}

func getEnclosingContainer(node *ast.Node) *ast.Node {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ declare var connect: Connect;

const myStoreConnect: Connect = function(
>myStoreConnect : Connect
>function( mapStateToProps?: any, mapDispatchToProps?: any, mergeProps?: any, options: unknown = {},) { return connect( mapStateToProps, mapDispatchToProps, mergeProps, options, );} : <TStateProps, TOwnProps>(mapStateToProps?: any, mapDispatchToProps?: any, mergeProps?: any, options?: unknown) => InferableComponentEnhancerWithProps<TStateProps, Omit<P, Extract<keyof TStateProps, keyof P>> & TOwnProps>
>function( mapStateToProps?: any, mapDispatchToProps?: any, mergeProps?: any, options: unknown = {},) { return connect( mapStateToProps, mapDispatchToProps, mergeProps, options, );} : (mapStateToProps?: any, mapDispatchToProps?: any, mergeProps?: any, options?: unknown) => InferableComponentEnhancerWithProps<TStateProps, Omit<P, Extract<keyof TStateProps, keyof P>> & TOwnProps>

mapStateToProps?: any,
>mapStateToProps : any
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
genericCallAtYieldExpressionInGenericCall1.ts(13,25): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator.
genericCallAtYieldExpressionInGenericCall1.ts(26,25): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
genericCallAtYieldExpressionInGenericCall1.ts(42,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '<T>(value: T) => Generator<any, void, unknown>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
Type 'Generator<any, void, unknown>' is not assignable to type 'Generator<never, unknown, unknown>'.
genericCallAtYieldExpressionInGenericCall1.ts(56,8): error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
Type 'Generator<number, void, any>' is not assignable to type 'Generator<never, unknown, unknown>'.
The types returned by 'next(...)' are incompatible between these types.
Type 'IteratorResult<any, void>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<any>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<any>' is not assignable to type 'IteratorYieldResult<never>'.
Type 'any' is not assignable to type 'never'.
genericCallAtYieldExpressionInGenericCall1.ts(57,10): error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
Type 'IteratorResult<number, void>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorResult<never, unknown>'.
Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorYieldResult<never>'.
Type 'number' is not assignable to type 'never'.
genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
Type 'Generator<number, void, any>' is not assignable to type 'Generator<never, unknown, unknown>'.
The types returned by 'next(...)' are incompatible between these types.
Expand All @@ -19,7 +15,7 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t
Type 'number' is not assignable to type 'never'.


==== genericCallAtYieldExpressionInGenericCall1.ts (7 errors) ====
==== genericCallAtYieldExpressionInGenericCall1.ts (3 errors) ====
declare const inner: {
<A>(value: A): {
(): A;
Expand All @@ -33,8 +29,6 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t

outer(function* <T>(value: T) {
const result = yield* inner(value); // ok
~~~~~~~~~~~~
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
});

outer(function* <T>(value: T) {
Expand All @@ -50,8 +44,6 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t
const result = yield* inner2(value); // error
~~~~~~~~~~~~~
!!! error TS2488: Type '() => T' must have a '[Symbol.iterator]()' method that returns an iterator.
~~~~~~~~~~~~~
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
});

declare const inner3: {
Expand All @@ -68,8 +60,6 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t
// number
const result1 = outer2(function* <T>(value: T) {
yield* inner3(value);
~~~~~~~~~~~~~
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
});

// number
Expand All @@ -85,16 +75,14 @@ genericCallAtYieldExpressionInGenericCall1.ts(61,8): error TS2345: Argument of t
// error
outer3(function* <T>(value: T) {
~~~~~~~~
!!! error TS2345: Argument of type '<T>(value: T) => Generator<any, void, unknown>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
!!! error TS2345: Type 'Generator<any, void, unknown>' is not assignable to type 'Generator<never, unknown, unknown>'.
!!! error TS2345: Argument of type '<T>(value: T) => Generator<number, void, any>' is not assignable to parameter of type '(value: unknown) => Generator<never, unknown, unknown>'.
!!! error TS2345: Type 'Generator<number, void, any>' is not assignable to type 'Generator<never, unknown, unknown>'.
!!! error TS2345: The types returned by 'next(...)' are incompatible between these types.
!!! error TS2345: Type 'IteratorResult<any, void>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<any>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<any>' is not assignable to type 'IteratorYieldResult<never>'.
!!! error TS2345: Type 'any' is not assignable to type 'never'.
!!! error TS2345: Type 'IteratorResult<number, void>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorResult<never, unknown>'.
!!! error TS2345: Type 'IteratorYieldResult<number>' is not assignable to type 'IteratorYieldResult<never>'.
!!! error TS2345: Type 'number' is not assignable to type 'never'.
yield* inner3(value);
~~~~~~~~~~~~~
!!! error TS2488: Type 'never' must have a '[Symbol.iterator]()' method that returns an iterator.
});

// error
Expand Down
Loading
Loading