Simplify syntaxTreeScopeDescriptorForPosition

This commit is contained in:
Linus Eriksson 2018-10-18 18:13:00 +02:00
parent ad41476cbe
commit 5299bb0f97

View File

@ -430,42 +430,27 @@ class TreeSitterLanguageMode {
}
syntaxTreeScopeDescriptorForPosition (point) {
if (!this.tree) return this.rootScopeDescriptor
const nodes = []
point = Point.fromObject(point)
const iterators = []
this._forEachTreeWithRange(new Range(point, point), tree => {
const rootStartIndex = tree.rootNode.startIndex
let node = tree.rootNode.descendantForPosition(point)
// Don't include anonymous token types like '(' because they prevent scope chains
// from being parsed as CSS selectors by the `slick` parser. Other css selector
// parsers like `postcss-selector-parser` do allow arbitrary quoted strings in
// selectors.
if (!node.isNamed) node = node.parent
iterators.push({node, rootStartIndex})
while (node) {
nodes.push(node)
node = node.parent
}
})
iterators.sort(compareScopeDescriptorIterators)
const scopes = []
// The nodes are mostly already sorted from smallest to largest,
// but for files with multiple syntax trees (e.g. ERB), each tree's
// nodes are separate. Sort the nodes from largest to smallest.
nodes.reverse()
nodes.sort((a, b) =>
a.startIndex - b.startIndex || b.endIndex - a.endIndex
)
for (;;) {
const {length} = iterators
if (!length) break
const iterator = iterators[length - 1]
scopes.push(iterator.node.type)
iterator.node = iterator.node.parent
if (iterator.node) {
let i = length - 1
while (i > 0 && compareScopeDescriptorIterators(iterator, iterators[i - 1]) < 0) i--
if (i < length - 1) iterators.splice(i, 0, iterators.pop())
} else {
iterators.pop()
}
}
scopes.push(this.grammar.scopeName)
return new ScopeDescriptor({scopes: scopes.reverse()})
const nodeTypes = nodes.map(node => node.type)
nodeTypes.unshift(this.grammar.scopeName)
return new ScopeDescriptor({scopes: nodeTypes})
}
scopeDescriptorForPosition (point) {
@ -1141,13 +1126,6 @@ function nodeIsSmaller (left, right) {
return left.endIndex - left.startIndex < right.endIndex - right.startIndex
}
function compareScopeDescriptorIterators (a, b) {
return (
a.node.startIndex - b.node.startIndex ||
a.rootStartIndex - b.rootStartIndex
)
}
function last (array) {
return array[array.length - 1]
}