Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
35 changes: 21 additions & 14 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,24 +2540,16 @@ 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:
if node.Initializer() != nil {
return ContainerFlagsIsControlFlowContainer | ContainerFlagsIsThisContainer
} else {
return ContainerFlagsNone
}
case ast.KindCatchClause, ast.KindForStatement, ast.KindForInStatement, ast.KindForOfStatement, ast.KindCaseBlock:
return ContainerFlagsIsBlockScopedContainer | ContainerFlagsHasLocals
case ast.KindBlock:
Expand Down
29 changes: 21 additions & 8 deletions internal/checker/checker.go
Original file line number Diff line number Diff line change
Expand Up @@ -19849,7 +19849,7 @@ 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)
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,11 +1,13 @@
index.js(7,14): error TS2339: Property 'justProp' does not exist on type 'YaddaBase'.
index.js(9,9): error TS7053: Element implicitly has an 'any' type because expression of type '"literalElementAccess"' can't be used to index type 'YaddaBase'.
Property 'literalElementAccess' does not exist on type 'YaddaBase'.
index.js(14,14): error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
index.js(23,22): error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
index.js(26,22): error TS2339: Property 'justProp' does not exist on type 'YaddaBase'.
index.js(29,22): error TS2339: Property 'literalElementAccess' does not exist on type 'YaddaBase'.


==== index.js (4 errors) ====
==== index.js (6 errors) ====
// https://github.com/microsoft/TypeScript/issues/55884

class YaddaBase {
Expand All @@ -25,6 +27,8 @@ index.js(29,22): error TS2339: Property 'literalElementAccess' does not exist on
}
accessor b = () => {
this.foo = 10
~~~
!!! error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
}
}

Expand All @@ -34,6 +38,8 @@ index.js(29,22): error TS2339: Property 'literalElementAccess' does not exist on
}
get fooTests() {
return super.foo;
~~~
!!! error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
}
get justPropTests() {
return super.justProp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,23 @@
-index.js(23,22): error TS2855: Class field 'foo' defined by the parent class is not accessible in the child class via super.
-index.js(26,22): error TS2855: Class field 'justProp' defined by the parent class is not accessible in the child class via super.
-index.js(29,22): error TS2855: Class field ''literalElementAccess'' defined by the parent class is not accessible in the child class via super.
-
-
-==== index.js (4 errors) ====
+index.js(7,14): error TS2339: Property 'justProp' does not exist on type 'YaddaBase'.
+index.js(9,9): error TS7053: Element implicitly has an 'any' type because expression of type '"literalElementAccess"' can't be used to index type 'YaddaBase'.
+ Property 'literalElementAccess' does not exist on type 'YaddaBase'.
+index.js(14,14): error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
+index.js(23,22): error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
+index.js(26,22): error TS2339: Property 'justProp' does not exist on type 'YaddaBase'.
+index.js(29,22): error TS2339: Property 'literalElementAccess' does not exist on type 'YaddaBase'.


==== index.js (4 errors) ====
@@= skipped -11, +12 lines =@@
+
+
+==== index.js (6 errors) ====
// https://github.com/microsoft/TypeScript/issues/55884

class YaddaBase {
@@= skipped -11, +14 lines =@@
this.roots = "hi";
/** @type number */
this.justProp;
Expand All @@ -27,7 +35,13 @@

this.b()
}
@@= skipped -13, +18 lines =@@
accessor b = () => {
this.foo = 10
+ ~~~
+!!! error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
}
}
Comment thread
jakebailey marked this conversation as resolved.
Outdated

class DerivedYadda extends YaddaBase {
get rootTests() {
return super.roots;
Expand All @@ -36,8 +50,9 @@
}
get fooTests() {
return super.foo;
- ~~~
~~~
-!!! error TS2855: Class field 'foo' defined by the parent class is not accessible in the child class via super.
+!!! error TS2339: Property 'foo' does not exist on type 'YaddaBase'.
}
get justPropTests() {
return super.justProp;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,7 @@ class YaddaBase {
>b : Symbol(YaddaBase.b, Decl(index.js, 11, 5))

this.foo = 10
>this.foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
>this : Symbol(YaddaBase, Decl(index.js, 0, 0))
>foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
}
}

Expand All @@ -51,9 +49,7 @@ class DerivedYadda extends YaddaBase {
>fooTests : Symbol(DerivedYadda.fooTests, Decl(index.js, 20, 5))

return super.foo;
>super.foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
>super : Symbol(YaddaBase, Decl(index.js, 0, 0))
>foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
}
get justPropTests() {
>justPropTests : Symbol(DerivedYadda.justPropTests, Decl(index.js, 23, 5))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,25 @@

this.b()
>this.b : Symbol(YaddaBase.b, Decl(index.js, 11, 5))
@@= skipped -48, +45 lines =@@
@@= skipped -18, +15 lines =@@
>b : Symbol(YaddaBase.b, Decl(index.js, 11, 5))

this.foo = 10
->this.foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
>this : Symbol(YaddaBase, Decl(index.js, 0, 0))
->foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
}
}

@@= skipped -22, +20 lines =@@
>fooTests : Symbol(DerivedYadda.fooTests, Decl(index.js, 20, 5))

return super.foo;
->super.foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
>super : Symbol(YaddaBase, Decl(index.js, 0, 0))
->foo : Symbol(YaddaBase.foo, Decl(index.js, 12, 24))
}
get justPropTests() {
>justPropTests : Symbol(DerivedYadda.justPropTests, Decl(index.js, 23, 5))

return super.justProp;
Expand Down
Loading