From 5299bb0f97e32bbe9f8c76d709bc9c19c46a328b Mon Sep 17 00:00:00 2001 From: Linus Eriksson Date: Thu, 18 Oct 2018 18:13:00 +0200 Subject: [PATCH] Simplify syntaxTreeScopeDescriptorForPosition --- src/tree-sitter-language-mode.js | 52 +++++++++----------------------- 1 file changed, 15 insertions(+), 37 deletions(-) diff --git a/src/tree-sitter-language-mode.js b/src/tree-sitter-language-mode.js index 5422a0714..fc87f16ac 100644 --- a/src/tree-sitter-language-mode.js +++ b/src/tree-sitter-language-mode.js @@ -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] }