mirror of
https://github.com/atom/atom.git
synced 2026-01-25 06:48:28 -05:00
Merge pull request #18438 from atom/mb-optimize-populate-injections
Optimize populating Tree-sitter syntax tree injections
This commit is contained in:
@@ -421,7 +421,11 @@ class GrammarRegistry {
|
||||
addInjectionPoint (grammarId, injectionPoint) {
|
||||
const grammar = this.treeSitterGrammarsById[grammarId]
|
||||
if (grammar) {
|
||||
grammar.injectionPoints.push(injectionPoint)
|
||||
if (grammar.addInjectionPoint) {
|
||||
grammar.addInjectionPoint(injectionPoint)
|
||||
} else {
|
||||
grammar.injectionPoints.push(injectionPoint)
|
||||
}
|
||||
} else {
|
||||
this.treeSitterGrammarsById[grammarId] = {
|
||||
injectionPoints: [injectionPoint]
|
||||
@@ -429,8 +433,7 @@ class GrammarRegistry {
|
||||
}
|
||||
return new Disposable(() => {
|
||||
const grammar = this.treeSitterGrammarsById[grammarId]
|
||||
const index = grammar.injectionPoints.indexOf(injectionPoint)
|
||||
if (index !== -1) grammar.injectionPoints.splice(index, 1)
|
||||
grammar.removeInjectionPoint(injectionPoint)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -454,7 +457,11 @@ class GrammarRegistry {
|
||||
if (grammar instanceof TreeSitterGrammar) {
|
||||
const existingParams = this.treeSitterGrammarsById[grammar.scopeName] || {}
|
||||
if (grammar.scopeName) this.treeSitterGrammarsById[grammar.scopeName] = grammar
|
||||
if (existingParams.injectionPoints) grammar.injectionPoints.push(...existingParams.injectionPoints)
|
||||
if (existingParams.injectionPoints) {
|
||||
for (const injectionPoint of existingParams.injectionPoints) {
|
||||
grammar.addInjectionPoint(injectionPoint)
|
||||
}
|
||||
}
|
||||
this.grammarAddedOrUpdated(grammar)
|
||||
return new Disposable(() => this.removeGrammar(grammar))
|
||||
} else {
|
||||
|
||||
@@ -40,7 +40,11 @@ class TreeSitterGrammar {
|
||||
|
||||
this.scopeMap = new SyntaxScopeMap(scopeSelectors)
|
||||
this.fileTypes = params.fileTypes || []
|
||||
this.injectionPoints = params.injectionPoints || []
|
||||
this.injectionPointsByType = {}
|
||||
|
||||
for (const injectionPoint of params.injectionPoints || []) {
|
||||
this.addInjectionPoint(injectionPoint)
|
||||
}
|
||||
|
||||
// TODO - When we upgrade to a new enough version of node, use `require.resolve`
|
||||
// with the new `paths` option instead of this private API.
|
||||
@@ -89,6 +93,25 @@ class TreeSitterGrammar {
|
||||
deactivate () {
|
||||
if (this.registration) this.registration.dispose()
|
||||
}
|
||||
|
||||
addInjectionPoint (injectionPoint) {
|
||||
let injectionPoints = this.injectionPointsByType[injectionPoint.type]
|
||||
if (!injectionPoints) {
|
||||
injectionPoints = this.injectionPointsByType[injectionPoint.type] = []
|
||||
}
|
||||
injectionPoints.push(injectionPoint)
|
||||
}
|
||||
|
||||
removeInjectionPoint (injectionPoint) {
|
||||
const injectionPoints = this.injectionPointsByType[injectionPoint.type]
|
||||
if (injectionPoints) {
|
||||
const index = injectionPoints.indexOf(injectionPoint)
|
||||
if (index !== -1) injectionPoints.splice(index, 1)
|
||||
if (injectionPoints.length === 0) {
|
||||
delete this.injectionPointsByType[injectionPoint.type]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const preprocessScopes = value =>
|
||||
|
||||
@@ -584,12 +584,12 @@ class LanguageLayer {
|
||||
|
||||
async update (nodeRangeSet) {
|
||||
if (!this.currentParsePromise) {
|
||||
do {
|
||||
while (!this.destroyed && (!this.tree || this.tree.rootNode.hasChanges())) {
|
||||
const params = {async: false}
|
||||
this.currentParsePromise = this._performUpdate(nodeRangeSet, params)
|
||||
if (!params.async) break
|
||||
await this.currentParsePromise
|
||||
} while (this.tree && this.tree.rootNode.hasChanges())
|
||||
}
|
||||
this.currentParsePromise = null
|
||||
}
|
||||
}
|
||||
@@ -610,6 +610,7 @@ class LanguageLayer {
|
||||
includedRanges = nodeRangeSet.getRanges()
|
||||
if (includedRanges.length === 0) {
|
||||
this.tree = null
|
||||
this.destroyed = true
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -694,14 +695,15 @@ class LanguageLayer {
|
||||
}
|
||||
|
||||
const markersToUpdate = new Map()
|
||||
for (const injectionPoint of this.grammar.injectionPoints) {
|
||||
const nodes = this.tree.rootNode.descendantsOfType(
|
||||
injectionPoint.type,
|
||||
range.start,
|
||||
range.end
|
||||
)
|
||||
const nodes = this.tree.rootNode.descendantsOfType(
|
||||
Object.keys(this.grammar.injectionPointsByType),
|
||||
range.start,
|
||||
range.end
|
||||
)
|
||||
|
||||
for (const node of nodes) {
|
||||
let existingInjectionMarkerIndex = 0
|
||||
for (const node of nodes) {
|
||||
for (const injectionPoint of this.grammar.injectionPointsByType[node.type]) {
|
||||
const languageName = injectionPoint.language(node)
|
||||
if (!languageName) continue
|
||||
|
||||
@@ -715,10 +717,25 @@ class LanguageLayer {
|
||||
if (!injectionNodes.length) continue
|
||||
|
||||
const injectionRange = rangeForNode(node)
|
||||
let marker = existingInjectionMarkers.find(m =>
|
||||
m.getRange().isEqual(injectionRange) &&
|
||||
m.languageLayer.grammar === grammar
|
||||
)
|
||||
|
||||
let marker
|
||||
for (let i = existingInjectionMarkerIndex, n = existingInjectionMarkers.length; i < n; i++) {
|
||||
const existingMarker = existingInjectionMarkers[i]
|
||||
const comparison = existingMarker.getRange().compare(injectionRange)
|
||||
if (comparison > 0) {
|
||||
break
|
||||
} else if (comparison === 0) {
|
||||
existingInjectionMarkerIndex = i
|
||||
if (existingMarker.languageLayer.grammar === grammar) {
|
||||
marker = existingMarker
|
||||
marker.id === node.id
|
||||
break
|
||||
}
|
||||
} else {
|
||||
existingInjectionMarkerIndex = i
|
||||
}
|
||||
}
|
||||
|
||||
if (!marker) {
|
||||
marker = this.languageMode.injectionsMarkerLayer.markRange(injectionRange)
|
||||
marker.languageLayer = new LanguageLayer(this.languageMode, grammar, injectionPoint.contentChildTypes)
|
||||
|
||||
Reference in New Issue
Block a user