mirror of
https://github.com/atom/atom.git
synced 2026-01-24 14:28:14 -05:00
Avoid recursive call to moveToSuccessor, which is blowing the stack
This commit is contained in:
@@ -1113,3 +1113,30 @@ describe "TokenizedBuffer", ->
|
||||
|
||||
expect(iterator.seek(Point(2, 0))).toEqual(["source.js"])
|
||||
iterator.moveToSuccessor() # ensure we don't infinitely loop (regression test)
|
||||
|
||||
it "does not report columns beyond the length of the line", ->
|
||||
waitsForPromise ->
|
||||
atom.packages.activatePackage('language-coffee-script')
|
||||
|
||||
runs ->
|
||||
buffer = new TextBuffer(text: "# hello\n# world")
|
||||
tokenizedBuffer = new TokenizedBuffer({
|
||||
buffer, config: atom.config, grammarRegistry: atom.grammars, packageManager: atom.packages, assert: atom.assert
|
||||
})
|
||||
tokenizedBuffer.setGrammar(atom.grammars.selectGrammar(".coffee"))
|
||||
fullyTokenize(tokenizedBuffer)
|
||||
|
||||
iterator = tokenizedBuffer.buildIterator()
|
||||
iterator.seek(Point(0, 0))
|
||||
iterator.moveToSuccessor()
|
||||
iterator.moveToSuccessor()
|
||||
expect(iterator.getPosition().column).toBe(7)
|
||||
|
||||
iterator.moveToSuccessor()
|
||||
expect(iterator.getPosition().column).toBe(0)
|
||||
|
||||
iterator.seek(Point(0, 7))
|
||||
expect(iterator.getPosition().column).toBe(7)
|
||||
|
||||
iterator.seek(Point(0, 8))
|
||||
expect(iterator.getPosition().column).toBe(7)
|
||||
|
||||
@@ -14,6 +14,7 @@ class TokenizedBufferIterator
|
||||
currentLine = @tokenizedBuffer.tokenizedLineForRow(position.row)
|
||||
containingTags = currentLine.openScopes.map (id) => @grammarRegistry.scopeForId(id)
|
||||
@currentTags = currentLine.tags
|
||||
@currentLineLength = currentLine.text.length
|
||||
currentColumn = 0
|
||||
for tag, index in @currentTags
|
||||
if tag >= 0
|
||||
@@ -32,39 +33,46 @@ class TokenizedBufferIterator
|
||||
@openTags.push(scopeName)
|
||||
|
||||
@tagIndex ?= @currentTags.length
|
||||
@position = Point(position.row, currentColumn)
|
||||
@position = Point(position.row, Math.min(@currentLineLength, currentColumn))
|
||||
containingTags
|
||||
|
||||
moveToSuccessor: ->
|
||||
if @tagIndex is @currentTags.length
|
||||
@position = Point(@position.row + 1, 0)
|
||||
@currentTags = @tokenizedBuffer.tokenizedLineForRow(@position.row)?.tags
|
||||
return false unless @currentTags?
|
||||
@tagIndex = 0
|
||||
else
|
||||
@position = Point(@position.row, @position.column + @currentTags[@tagIndex])
|
||||
@tagIndex++
|
||||
|
||||
@openTags = []
|
||||
@closeTags = []
|
||||
|
||||
loop
|
||||
tag = @currentTags[@tagIndex]
|
||||
if tag >= 0 or @tagIndex is @currentTags.length
|
||||
if @tagIndex is @currentTags.length
|
||||
if @isAtTagBoundary()
|
||||
break
|
||||
else
|
||||
return @moveToSuccessor()
|
||||
return false unless @moveToNextLine()
|
||||
else
|
||||
scopeName = @grammarRegistry.scopeForId(tag)
|
||||
if tag % 2 is 0
|
||||
@closeTags.push(scopeName)
|
||||
tag = @currentTags[@tagIndex]
|
||||
if tag >= 0
|
||||
if @isAtTagBoundary()
|
||||
break
|
||||
else
|
||||
@position = Point(@position.row, Math.min(@currentLineLength, @position.column + @currentTags[@tagIndex]))
|
||||
else
|
||||
@openTags.push(scopeName)
|
||||
@tagIndex++
|
||||
scopeName = @grammarRegistry.scopeForId(tag)
|
||||
if tag % 2 is 0
|
||||
@closeTags.push(scopeName)
|
||||
else
|
||||
@openTags.push(scopeName)
|
||||
@tagIndex++
|
||||
|
||||
true
|
||||
|
||||
# Private
|
||||
moveToNextLine: ->
|
||||
@position = Point(@position.row + 1, 0)
|
||||
tokenizedLine = @tokenizedBuffer.tokenizedLineForRow(@position.row)
|
||||
return false unless tokenizedLine?
|
||||
@currentTags = tokenizedLine.tags
|
||||
@currentLineLength = tokenizedLine.text.length
|
||||
@tagIndex = 0
|
||||
true
|
||||
|
||||
getPosition: ->
|
||||
@position
|
||||
|
||||
|
||||
Reference in New Issue
Block a user