(sourceFile *ast.SourceFile, node *ast.Node)
| 2586 | } |
| 2587 | |
| 2588 | func GetErrorRangeForNode(sourceFile *ast.SourceFile, node *ast.Node) core.TextRange { |
| 2589 | errorNode := node |
| 2590 | switch node.Kind { |
| 2591 | case ast.KindSourceFile: |
| 2592 | pos := SkipTrivia(sourceFile.Text(), 0) |
| 2593 | if pos == len(sourceFile.Text()) { |
| 2594 | return core.NewTextRange(0, 0) |
| 2595 | } |
| 2596 | return GetRangeOfTokenAtPosition(sourceFile, pos) |
| 2597 | // This list is a work in progress. Add missing node kinds to improve their error spans |
| 2598 | case ast.KindFunctionDeclaration, ast.KindMethodDeclaration: |
| 2599 | if node.Flags&ast.NodeFlagsReparsed != 0 { |
| 2600 | errorNode = node |
| 2601 | break |
| 2602 | } |
| 2603 | fallthrough |
| 2604 | case ast.KindVariableDeclaration, ast.KindBindingElement, ast.KindClassDeclaration, ast.KindInterfaceDeclaration, |
| 2605 | ast.KindModuleDeclaration, ast.KindEnumDeclaration, ast.KindEnumMember, ast.KindFunctionExpression, |
| 2606 | ast.KindGetAccessor, ast.KindSetAccessor, ast.KindTypeAliasDeclaration, ast.KindJSTypeAliasDeclaration, ast.KindPropertyDeclaration, |
| 2607 | ast.KindPropertySignature, ast.KindNamespaceImport: |
| 2608 | errorNode = ast.GetNameOfDeclaration(node) |
| 2609 | case ast.KindClassExpression: |
| 2610 | errorNode = node.Name() |
| 2611 | |
| 2612 | case ast.KindArrowFunction: |
| 2613 | return getErrorRangeForArrowFunction(sourceFile, node) |
| 2614 | case ast.KindCaseClause, ast.KindDefaultClause: |
| 2615 | start := SkipTrivia(sourceFile.Text(), node.Pos()) |
| 2616 | end := node.End() |
| 2617 | statements := node.Statements() |
| 2618 | if len(statements) != 0 { |
| 2619 | end = statements[0].Pos() |
| 2620 | } |
| 2621 | return core.NewTextRange(start, end) |
| 2622 | case ast.KindReturnStatement, ast.KindYieldExpression: |
| 2623 | pos := SkipTrivia(sourceFile.Text(), node.Pos()) |
| 2624 | return GetRangeOfTokenAtPosition(sourceFile, pos) |
| 2625 | case ast.KindSatisfiesExpression: |
| 2626 | if jsDocSatisfiesTag := findOriginatingJSDocSatisfiesTag(sourceFile, node); jsDocSatisfiesTag != nil { |
| 2627 | pos := SkipTrivia(sourceFile.Text(), jsDocSatisfiesTag.TagName().Pos()) |
| 2628 | return GetRangeOfTokenAtPosition(sourceFile, pos) |
| 2629 | } |
| 2630 | pos := SkipTrivia(sourceFile.Text(), node.AsSatisfiesExpression().Expression.End()) |
| 2631 | return GetRangeOfTokenAtPosition(sourceFile, pos) |
| 2632 | case ast.KindConstructor: |
| 2633 | if node.Flags&ast.NodeFlagsReparsed != 0 { |
| 2634 | errorNode = node |
| 2635 | break |
| 2636 | } |
| 2637 | scanner := GetScannerForSourceFile(sourceFile, node.Pos()) |
| 2638 | start := scanner.TokenStart() |
| 2639 | for scanner.Token() != ast.KindConstructorKeyword && scanner.Token() != ast.KindStringLiteral && scanner.Token() != ast.KindEndOfFile { |
| 2640 | scanner.Scan() |
| 2641 | } |
| 2642 | return core.NewTextRange(start, scanner.TokenEnd()) |
| 2643 | } |
| 2644 | if errorNode == nil { |
| 2645 | // If we don't have a better node, then just set the error on the first token of |
no test coverage detected