diff --git a/internal/ast/utilities.go b/internal/ast/utilities.go index e8262ce04f..34c24210bb 100644 --- a/internal/ast/utilities.go +++ b/internal/ast/utilities.go @@ -494,9 +494,9 @@ func isFunctionLikeDeclarationKind(kind Kind) bool { } // Determines if a node is function-like (but is not a signature declaration) +// ensure node != nil before calling this func IsFunctionLikeDeclaration(node *Node) bool { - // TODO(rbuckton): Move `node != nil` test to call sites - return node != nil && isFunctionLikeDeclarationKind(node.Kind) + return isFunctionLikeDeclarationKind(node.Kind) } func isFunctionLikeKind(kind Kind) bool { @@ -514,9 +514,9 @@ func isFunctionLikeKind(kind Kind) bool { } // Determines if a node is function- or signature-like. +// Ensure node != nil before calling this func IsFunctionLike(node *Node) bool { - // TODO(rbuckton): Move `node != nil` test to call sites - return node != nil && isFunctionLikeKind(node.Kind) + return isFunctionLikeKind(node.Kind) } func IsFunctionLikeOrClassStaticBlockDeclaration(node *Node) bool { @@ -1064,7 +1064,7 @@ func CanHaveDecorators(node *Node) bool { } func IsFunctionOrModuleBlock(node *Node) bool { - return IsSourceFile(node) || IsModuleBlock(node) || IsBlock(node) && IsFunctionLike(node.Parent) + return IsSourceFile(node) || IsModuleBlock(node) || IsBlock(node) && node.Parent != nil && IsFunctionLike(node.Parent) } func IsFunctionExpressionOrArrowFunction(node *Node) bool { diff --git a/internal/binder/binder.go b/internal/binder/binder.go index 55e6fff575..ea1779933d 100644 --- a/internal/binder/binder.go +++ b/internal/binder/binder.go @@ -2513,7 +2513,7 @@ func GetContainerFlags(node *ast.Node) ContainerFlags { case ast.KindCatchClause, ast.KindForStatement, ast.KindForInStatement, ast.KindForOfStatement, ast.KindCaseBlock: return ContainerFlagsIsBlockScopedContainer | ContainerFlagsHasLocals case ast.KindBlock: - if ast.IsFunctionLike(node.Parent) || ast.IsClassStaticBlockDeclaration(node.Parent) { + if node.Parent != nil && (ast.IsFunctionLike(node.Parent) || ast.IsClassStaticBlockDeclaration(node.Parent)) { return ContainerFlagsNone } else { return ContainerFlagsIsBlockScopedContainer | ContainerFlagsHasLocals diff --git a/internal/checker/checker.go b/internal/checker/checker.go index 045fb6c9c5..094e911d29 100644 --- a/internal/checker/checker.go +++ b/internal/checker/checker.go @@ -5534,7 +5534,7 @@ func (c *Checker) checkVarDeclaredNamesNotShadowed(node *ast.Node) { } // names of block-scoped and function scoped variables can collide only // if block scoped variable is defined in the function\module\source file scope (because of variable hoisting) - namesShareScope := container != nil && (ast.IsBlock(container) && ast.IsFunctionLike(container.Parent) || + namesShareScope := container != nil && (ast.IsBlock(container) && container.Parent != nil && ast.IsFunctionLike(container.Parent) || ast.IsModuleBlock(container) || ast.IsModuleDeclaration(container) || ast.IsSourceFile(container)) // here we know that function scoped variable is "shadowed" by block scoped one // a var declaration can't hoist past a lexical declaration and it results in a SyntaxError at runtime @@ -7365,7 +7365,7 @@ func (c *Checker) checkSuperExpression(node *ast.Node) *Type { func (c *Checker) isInConstructorArgumentInitializer(node *ast.Node, constructorDecl *ast.Node) bool { return ast.FindAncestorOrQuit(node, func(n *ast.Node) ast.FindAncestorResult { - if ast.IsFunctionLikeDeclaration(n) { + if n != nil && ast.IsFunctionLikeDeclaration(n) { return ast.FindAncestorQuit } if ast.IsParameter(n) && n.Parent == constructorDecl { @@ -10862,7 +10862,7 @@ func (c *Checker) isUncalledFunctionReference(node *ast.Node, symbol *ast.Symbol return isCallOrNewExpression(parent) && ast.IsIdentifier(node) && c.hasMatchingArgument(parent, node) } return core.Every(symbol.Declarations, func(d *ast.Node) bool { - return !ast.IsFunctionLike(d) || c.isDeprecatedDeclaration(d) + return d == nil || !ast.IsFunctionLike(d) || c.isDeprecatedDeclaration(d) }) } return true @@ -11128,7 +11128,7 @@ func (c *Checker) isNodeUsedDuringClassInitialization(node *ast.Node) bool { return ast.FindAncestorOrQuit(node, func(element *ast.Node) ast.FindAncestorResult { if ast.IsConstructorDeclaration(element) && ast.NodeIsPresent(element.Body()) || ast.IsPropertyDeclaration(element) { return ast.FindAncestorTrue - } else if ast.IsClassLike(element) || ast.IsFunctionLikeDeclaration(element) { + } else if ast.IsClassLike(element) || (element != nil && ast.IsFunctionLikeDeclaration(element)) { return ast.FindAncestorQuit } return ast.FindAncestorFalse @@ -11305,7 +11305,7 @@ func (c *Checker) tryGetThisTypeAt(node *ast.Node) *Type { } func (c *Checker) tryGetThisTypeAtEx(node *ast.Node, includeGlobalThis bool, container *ast.Node) *Type { - if ast.IsFunctionLike(container) && (!c.isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container) != nil) { + if container != nil && ast.IsFunctionLike(container) && (!c.isInParameterInitializerBeforeContainingFunction(node) || getThisParameter(container) != nil) { thisType := c.getThisTypeOfDeclaration(container) // Note: a parameter initializer should refer to class-this unless function-this is explicitly annotated. // If this is a function in a JS file, it might be a class method. @@ -17983,7 +17983,7 @@ func (c *Checker) getSignaturesOfSymbol(symbol *ast.Symbol) []*Signature { } var result []*Signature for i, decl := range symbol.Declarations { - if !ast.IsFunctionLike(decl) { + if decl == nil || !ast.IsFunctionLike(decl) { continue } // Don't include signature if node is the implementation of an overloaded function. A node is considered @@ -18582,7 +18582,7 @@ func (c *Checker) createGeneratorType(yieldType *Type, returnType *Type, nextTyp func (c *Checker) reportErrorsFromWidening(declaration *ast.Node, t *Type, wideningKind WideningKind) { if c.noImplicitAny && t.objectFlags&ObjectFlagsContainsWideningType != 0 { - if wideningKind == WideningKindNormal || ast.IsFunctionLikeDeclaration(declaration) && c.shouldReportErrorsFromWideningWithContextualSignature(declaration, wideningKind) { + if wideningKind == WideningKindNormal || declaration != nil && ast.IsFunctionLikeDeclaration(declaration) && c.shouldReportErrorsFromWideningWithContextualSignature(declaration, wideningKind) { // Report implicit any error within type if possible, otherwise report error on declaration if !c.reportWideningErrorsInType(t) { c.reportImplicitAny(declaration, t, wideningKind) @@ -28988,7 +28988,7 @@ func (c *Checker) getSymbolAtLocation(node *ast.Node, ignoreErrors bool) *ast.Sy fallthrough case ast.KindThisKeyword: container := c.getThisContainer(node, false /*includeArrowFunctions*/, false /*includeClassComputedPropertyName*/) - if ast.IsFunctionLike(container) { + if container != nil && ast.IsFunctionLike(container) { sig := c.getSignatureFromDeclaration(container) if sig.thisParameter != nil { return sig.thisParameter diff --git a/internal/checker/flow.go b/internal/checker/flow.go index e875a0a2a8..1961fdb51e 100644 --- a/internal/checker/flow.go +++ b/internal/checker/flow.go @@ -2166,7 +2166,7 @@ func (c *Checker) hasTypePredicateOrNeverReturnType(sig *Signature) bool { func (c *Checker) getExplicitThisType(node *ast.Node) *Type { container := ast.GetThisContainer(node, false /*includeArrowFunctions*/, false /*includeClassComputedPropertyName*/) - if ast.IsFunctionLike(container) { + if container != nil && ast.IsFunctionLike(container) { signature := c.getSignatureFromDeclaration(container) if signature.thisParameter != nil { return c.getExplicitTypeOfSymbol(signature.thisParameter, nil) diff --git a/internal/checker/grammarchecks.go b/internal/checker/grammarchecks.go index 15a5e4e7bb..6903174740 100644 --- a/internal/checker/grammarchecks.go +++ b/internal/checker/grammarchecks.go @@ -294,7 +294,7 @@ func (c *Checker) checkGrammarModifiers(node *ast.Node /*Union[HasModifiers, Has parent := node.Parent if node.Kind == ast.KindTypeParameter { - if !(ast.IsFunctionLikeDeclaration(parent) || ast.IsClassLike(parent) || + if !((parent != nil && ast.IsFunctionLikeDeclaration(parent)) || ast.IsClassLike(parent) || ast.IsFunctionTypeNode(parent) || ast.IsConstructorTypeNode(parent) || ast.IsCallSignatureDeclaration(parent) || ast.IsConstructSignatureDeclaration(parent) || ast.IsMethodSignatureDeclaration(parent)) { @@ -2061,7 +2061,7 @@ func (c *Checker) checkGrammarStatementInAmbientContext(node *ast.Node) bool { if node.Flags&ast.NodeFlagsAmbient != 0 { // Find containing block which is either Block, ModuleBlock, SourceFile links := c.nodeLinks.Get(node) - if !links.hasReportedStatementInAmbientContext && (ast.IsFunctionLike(node.Parent) || ast.IsAccessor(node.Parent)) { + if !links.hasReportedStatementInAmbientContext && (node.Parent != nil && ast.IsFunctionLike(node.Parent) || ast.IsAccessor(node.Parent)) { links.hasReportedStatementInAmbientContext = c.grammarErrorOnFirstToken(node, diagnostics.An_implementation_cannot_be_declared_in_ambient_contexts) return links.hasReportedStatementInAmbientContext }