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
26 changes: 13 additions & 13 deletions internal/ast/ast.go
Original file line number Diff line number Diff line change
Expand Up @@ -10724,10 +10724,10 @@ type SourceFile struct {
ClassifiableNames collections.Set[string]
PatternAmbientModules []*PatternAmbientModule

// Fields set by LineMap
// Fields set by ECMALineMap

lineMapMu sync.RWMutex
lineMap []core.TextPos
ecmaLineMapMu sync.RWMutex
ecmaLineMap []core.TextPos
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we give []core.TextPos a name like ECMALineMap or does a change like that cause problems elsewhere?


// Fields set by language service

Expand Down Expand Up @@ -10862,17 +10862,17 @@ func (f *NodeFactory) UpdateSourceFile(node *SourceFile, statements *StatementLi
return node.AsNode()
}

func (node *SourceFile) LineMap() []core.TextPos {
node.lineMapMu.RLock()
lineMap := node.lineMap
node.lineMapMu.RUnlock()
func (node *SourceFile) ECMALineMap() []core.TextPos {
node.ecmaLineMapMu.RLock()
lineMap := node.ecmaLineMap
node.ecmaLineMapMu.RUnlock()
if lineMap == nil {
node.lineMapMu.Lock()
defer node.lineMapMu.Unlock()
lineMap = node.lineMap
node.ecmaLineMapMu.Lock()
defer node.ecmaLineMapMu.Unlock()
lineMap = node.ecmaLineMap
if lineMap == nil {
lineMap = core.ComputeLineStarts(node.Text())
node.lineMap = lineMap
lineMap = core.ComputeECMALineStarts(node.Text())
node.ecmaLineMap = lineMap
}
}
return lineMap
Expand Down Expand Up @@ -11054,7 +11054,7 @@ func getDeclarationName(declaration *Node) string {

type SourceFileLike interface {
Text() string
LineMap() []core.TextPos
ECMALineMap() []core.TextPos
}

type CommentRange struct {
Expand Down
2 changes: 1 addition & 1 deletion internal/astnav/tokens_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ func tsGetTouchingPropertyName(t testing.TB, fileText string, positions []int) [
}

func writeRangeDiff(output *strings.Builder, file *ast.SourceFile, diff tokenDiff, rng core.TextRange, position int) {
lines := file.LineMap()
lines := file.ECMALineMap()

tsTokenPos := position
goTokenPos := position
Expand Down
4 changes: 2 additions & 2 deletions internal/checker/grammarchecks.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,8 +814,8 @@ func (c *Checker) checkGrammarArrowFunction(node *ast.Node, file *ast.SourceFile
}

equalsGreaterThanToken := arrowFunc.EqualsGreaterThanToken
startLine, _ := scanner.GetLineAndCharacterOfPosition(file, equalsGreaterThanToken.Pos())
endLine, _ := scanner.GetLineAndCharacterOfPosition(file, equalsGreaterThanToken.End())
startLine, _ := scanner.GetECMALineAndCharacterOfPosition(file, equalsGreaterThanToken.Pos())
endLine, _ := scanner.GetECMALineAndCharacterOfPosition(file, equalsGreaterThanToken.End())
return startLine != endLine && c.grammarErrorOnNode(equalsGreaterThanToken, diagnostics.Line_terminator_not_permitted_before_arrow)
}

Expand Down
6 changes: 3 additions & 3 deletions internal/compiler/program.go
Original file line number Diff line number Diff line change
Expand Up @@ -1074,10 +1074,10 @@ func (p *Program) getDiagnosticsWithPrecedingDirectives(sourceFile *ast.SourceFi
// Build map of directives by line number
directivesByLine := make(map[int]ast.CommentDirective)
for _, directive := range sourceFile.CommentDirectives {
line, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, directive.Loc.Pos())
line, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, directive.Loc.Pos())
directivesByLine[line] = directive
}
lineStarts := scanner.GetLineStarts(sourceFile)
lineStarts := scanner.GetECMALineStarts(sourceFile)
filtered := make([]*ast.Diagnostic, 0, len(diags))
for _, diagnostic := range diags {
ignoreDiagnostic := false
Expand Down Expand Up @@ -1225,7 +1225,7 @@ func (p *Program) getDiagnosticsHelper(ctx context.Context, sourceFile *ast.Sour
func (p *Program) LineCount() int {
var count int
for _, file := range p.files {
count += len(file.LineMap())
count += len(file.ECMALineMap())
}
return count
}
Expand Down
6 changes: 3 additions & 3 deletions internal/core/core.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,12 +362,12 @@ func Coalesce[T *U, U any](a T, b T) T {
}
}

func ComputeLineStarts(text string) []TextPos {
func ComputeECMALineStarts(text string) []TextPos {
result := make([]TextPos, 0, strings.Count(text, "\n")+1)
return slices.AppendSeq(result, ComputeLineStartsSeq(text))
return slices.AppendSeq(result, ComputeECMALineStartsSeq(text))
}

func ComputeLineStartsSeq(text string) iter.Seq[TextPos] {
func ComputeECMALineStartsSeq(text string) iter.Seq[TextPos] {
return func(yield func(TextPos) bool) {
textLen := TextPos(len(text))
var pos TextPos
Expand Down
16 changes: 8 additions & 8 deletions internal/diagnosticwriter/diagnosticwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -84,13 +84,13 @@ func FormatDiagnosticWithColorAndContext(output io.Writer, diagnostic *ast.Diagn
}

func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, length int, squiggleColor string, indent string, formatOpts *FormattingOptions) {
firstLine, firstLineChar := scanner.GetLineAndCharacterOfPosition(sourceFile, start)
lastLine, lastLineChar := scanner.GetLineAndCharacterOfPosition(sourceFile, start+length)
firstLine, firstLineChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start)
lastLine, lastLineChar := scanner.GetECMALineAndCharacterOfPosition(sourceFile, start+length)
if length == 0 {
lastLineChar++ // When length is zero, squiggle the character right after the start position.
}

lastLineOfFile, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, len(sourceFile.Text()))
lastLineOfFile, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, len(sourceFile.Text()))

hasMoreThanFiveLines := lastLine-firstLine >= 4
gutterWidth := len(strconv.Itoa(lastLine + 1))
Expand All @@ -113,10 +113,10 @@ func writeCodeSnippet(writer io.Writer, sourceFile *ast.SourceFile, start int, l
i = lastLine - 1
}

lineStart := scanner.GetPositionOfLineAndCharacter(sourceFile, i, 0)
lineStart := scanner.GetECMAPositionOfLineAndCharacter(sourceFile, i, 0)
var lineEnd int
if i < lastLineOfFile {
lineEnd = scanner.GetPositionOfLineAndCharacter(sourceFile, i+1, 0)
lineEnd = scanner.GetECMAPositionOfLineAndCharacter(sourceFile, i+1, 0)
} else {
lineEnd = sourceFile.Loc.End()
}
Expand Down Expand Up @@ -216,7 +216,7 @@ func writeWithStyleAndReset(output io.Writer, text string, formatStyle string) {
}

func WriteLocation(output io.Writer, file *ast.SourceFile, pos int, formatOpts *FormattingOptions, writeWithStyleAndReset FormattedWriter) {
firstLine, firstChar := scanner.GetLineAndCharacterOfPosition(file, pos)
firstLine, firstChar := scanner.GetECMALineAndCharacterOfPosition(file, pos)
var relativeFileName string
if formatOpts != nil {
relativeFileName = tspath.ConvertToRelativePath(file.FileName(), formatOpts.ComparePathsOptions)
Expand Down Expand Up @@ -357,7 +357,7 @@ func prettyPathForFileError(file *ast.SourceFile, fileErrors []*ast.Diagnostic,
if file == nil || len(fileErrors) == 0 {
return ""
}
line, _ := scanner.GetLineAndCharacterOfPosition(file, fileErrors[0].Loc().Pos())
line, _ := scanner.GetECMALineAndCharacterOfPosition(file, fileErrors[0].Loc().Pos())
fileName := file.FileName()
if tspath.PathIsAbsolute(fileName) && tspath.PathIsAbsolute(formatOpts.CurrentDirectory) {
fileName = tspath.ConvertToRelativePath(file.FileName(), formatOpts.ComparePathsOptions)
Expand All @@ -378,7 +378,7 @@ func WriteFormatDiagnostics(output io.Writer, diagnostics []*ast.Diagnostic, for

func WriteFormatDiagnostic(output io.Writer, diagnostic *ast.Diagnostic, formatOpts *FormattingOptions) {
if diagnostic.File() != nil {
line, character := scanner.GetLineAndCharacterOfPosition(diagnostic.File(), diagnostic.Loc().Pos())
line, character := scanner.GetECMALineAndCharacterOfPosition(diagnostic.File(), diagnostic.Loc().Pos())
fileName := diagnostic.File().FileName()
relativeFileName := tspath.ConvertToRelativePath(fileName, formatOpts.ComparePathsOptions)
fmt.Fprintf(output, "%s(%d,%d): ", relativeFileName, line+1, character+1)
Expand Down
6 changes: 3 additions & 3 deletions internal/format/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -146,18 +146,18 @@ func FormatOnSemicolon(ctx context.Context, sourceFile *ast.SourceFile, position
}

func FormatOnEnter(ctx context.Context, sourceFile *ast.SourceFile, position int) []core.TextChange {
line, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, position)
line, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, position)
if line == 0 {
return nil
}
// get start position for the previous line
startPos := int(scanner.GetLineStarts(sourceFile)[line-1])
startPos := int(scanner.GetECMALineStarts(sourceFile)[line-1])
// After the enter key, the cursor is now at a new line. The new line may or may not contain non-whitespace characters.
// If the new line has only whitespaces, we won't want to format this line, because that would remove the indentation as
// trailing whitespaces. So the end of the formatting span should be the later one between:
// 1. the end of the previous line
// 2. the last non-whitespace character in the current line
endOfFormatSpan := scanner.GetEndLinePosition(sourceFile, line)
endOfFormatSpan := scanner.GetECMAEndLinePosition(sourceFile, line)
for endOfFormatSpan > startPos {
ch, s := utf8.DecodeRuneInString(sourceFile.Text()[endOfFormatSpan:])
if s == 0 || stringutil.IsWhiteSpaceSingleLine(ch) { // on multibyte character keep backing up
Expand Down
26 changes: 13 additions & 13 deletions internal/format/indent.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import (
)

func GetIndentationForNode(n *ast.Node, ignoreActualIndentationRange *core.TextRange, sourceFile *ast.SourceFile, options *FormatCodeSettings) int {
startline, startpos := scanner.GetLineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(n, sourceFile, false))
startline, startpos := scanner.GetECMALineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(n, sourceFile, false))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The formatter using these instead of the client encoding is definitely spooky

return getIndentationForNodeWorker(n, startline, startpos, ignoreActualIndentationRange /*indentationDelta*/, 0, sourceFile /*isNextChild*/, false, options)
}

Expand Down Expand Up @@ -100,7 +100,7 @@ func getIndentationForNodeWorker(
parent = current.Parent

if useTrueStart {
currentStartLine, currentStartCharacter = scanner.GetLineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(current, sourceFile, false))
currentStartLine, currentStartCharacter = scanner.GetECMALineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(current, sourceFile, false))
} else {
currentStartLine = containingListOrParentStartLine
currentStartCharacter = containingListOrParentStartCharacter
Expand Down Expand Up @@ -131,7 +131,7 @@ func isArgumentAndStartLineOverlapsExpressionBeingCalled(parent *ast.Node, child
return false
}
expressionOfCallExpressionEnd := parent.Expression().End()
expressionOfCallExpressionEndLine, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd)
expressionOfCallExpressionEndLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, expressionOfCallExpressionEnd)
return expressionOfCallExpressionEndLine == childStartLine
}

Expand Down Expand Up @@ -166,7 +166,7 @@ func getActualIndentationForListStartLine(list *ast.NodeList, sourceFile *ast.So
if list == nil {
return -1
}
line, char := scanner.GetLineAndCharacterOfPosition(sourceFile, list.Loc.Pos())
line, char := scanner.GetECMALineAndCharacterOfPosition(sourceFile, list.Loc.Pos())
return findColumnForFirstNonWhitespaceCharacterInLine(line, char, sourceFile, options)
}

Expand All @@ -185,7 +185,7 @@ func deriveActualIndentationFromList(list *ast.NodeList, index int, sourceFile *
continue
}
// skip list items that ends on the same line with the current list element
prevEndLine, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, list.Nodes[i].End())
prevEndLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, list.Nodes[i].End())
if prevEndLine != line {
return findColumnForFirstNonWhitespaceCharacterInLine(line, char, sourceFile, options)
}
Expand All @@ -196,7 +196,7 @@ func deriveActualIndentationFromList(list *ast.NodeList, index int, sourceFile *
}

func findColumnForFirstNonWhitespaceCharacterInLine(line int, char int, sourceFile *ast.SourceFile, options *FormatCodeSettings) int {
lineStart := scanner.GetPositionOfLineAndCharacter(sourceFile, line, 0)
lineStart := scanner.GetECMAPositionOfLineAndCharacter(sourceFile, line, 0)
return FindFirstNonWhitespaceColumn(lineStart, lineStart+char, sourceFile, options)
}

Expand Down Expand Up @@ -247,7 +247,7 @@ func childStartsOnTheSameLineWithElseInIfStatement(parent *ast.Node, child *ast.
}

func getStartLineAndCharacterForNode(n *ast.Node, sourceFile *ast.SourceFile) (line int, character int) {
return scanner.GetLineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(n, sourceFile, false))
return scanner.GetECMALineAndCharacterOfPosition(sourceFile, scanner.GetTokenPosOfNode(n, sourceFile, false))
}

func GetContainingList(node *ast.Node, sourceFile *ast.SourceFile) *ast.NodeList {
Expand Down Expand Up @@ -356,7 +356,7 @@ func getContainingListOrParentStart(parent *ast.Node, child *ast.Node, sourceFil
} else {
startPos = scanner.GetTokenPosOfNode(parent, sourceFile, false)
}
return scanner.GetLineAndCharacterOfPosition(sourceFile, startPos)
return scanner.GetECMALineAndCharacterOfPosition(sourceFile, startPos)
}

func isControlFlowEndingStatement(kind ast.Kind, parentKind ast.Kind) bool {
Expand Down Expand Up @@ -439,8 +439,8 @@ func NodeWillIndentChild(settings *FormatCodeSettings, parent *ast.Node, child *
return rangeIsOnOneLine(child.Loc, sourceFile)
}
if parent.Kind == ast.KindBinaryExpression && sourceFile != nil && childKind == ast.KindJsxElement {
parentStartLine, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, scanner.SkipTrivia(sourceFile.Text(), parent.Pos()))
childStartLine, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, scanner.SkipTrivia(sourceFile.Text(), child.Pos()))
parentStartLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, scanner.SkipTrivia(sourceFile.Text(), parent.Pos()))
childStartLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, scanner.SkipTrivia(sourceFile.Text(), child.Pos()))
return parentStartLine != childStartLine
}
if parent.Kind != ast.KindBinaryExpression {
Expand Down Expand Up @@ -516,7 +516,7 @@ func NodeWillIndentChild(settings *FormatCodeSettings, parent *ast.Node, child *
// branch beginning on the line that the whenTrue branch ends.
func childIsUnindentedBranchOfConditionalExpression(parent *ast.Node, child *ast.Node, childStartLine int, sourceFile *ast.SourceFile) bool {
if parent.Kind == ast.KindConditionalExpression && (child == parent.AsConditionalExpression().WhenTrue || child == parent.AsConditionalExpression().WhenFalse) {
conditionEndLine, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, parent.AsConditionalExpression().Condition.End())
conditionEndLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, parent.AsConditionalExpression().Condition.End())
if child == parent.AsConditionalExpression().WhenTrue {
return childStartLine == conditionEndLine
} else {
Expand All @@ -528,7 +528,7 @@ func childIsUnindentedBranchOfConditionalExpression(parent *ast.Node, child *ast
// 0 L2: indented two stops, one because whenTrue was indented
// ); and one because of the parentheses spanning multiple lines
trueStartLine, _ := getStartLineAndCharacterForNode(parent.AsConditionalExpression().WhenTrue, sourceFile)
trueEndLine, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, parent.AsConditionalExpression().WhenTrue.End())
trueEndLine, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, parent.AsConditionalExpression().WhenTrue.End())
return conditionEndLine == trueStartLine && trueEndLine == childStartLine
}
}
Expand All @@ -550,7 +550,7 @@ func argumentStartsOnSameLineAsPreviousArgument(parent *ast.Node, child *ast.Nod
}

previousNode := parent.Arguments()[currentIndex-1]
lineOfPreviousNode, _ := scanner.GetLineAndCharacterOfPosition(sourceFile, previousNode.End())
lineOfPreviousNode, _ := scanner.GetECMALineAndCharacterOfPosition(sourceFile, previousNode.End())
if childStartLine == lineOfPreviousNode {
return true
}
Expand Down
4 changes: 2 additions & 2 deletions internal/format/rulecontext.go
Original file line number Diff line number Diff line change
Expand Up @@ -584,8 +584,8 @@ func isSemicolonDeletionContext(context *formattingContext) bool {
nextTokenStart = scanner.GetTokenPosOfNode(nextRealToken, context.SourceFile, false)
}

startLine, _ := scanner.GetLineAndCharacterOfPosition(context.SourceFile, context.currentTokenSpan.Loc.Pos())
endLine, _ := scanner.GetLineAndCharacterOfPosition(context.SourceFile, nextTokenStart)
startLine, _ := scanner.GetECMALineAndCharacterOfPosition(context.SourceFile, context.currentTokenSpan.Loc.Pos())
endLine, _ := scanner.GetECMALineAndCharacterOfPosition(context.SourceFile, nextTokenStart)
if startLine == endLine {
return nextTokenKind == ast.KindCloseBraceToken || nextTokenKind == ast.KindEndOfFile
}
Expand Down
Loading