injectionPoint content can return an array of nodes now

This commit is contained in:
Ashi Krishnan
2018-07-05 17:46:13 -04:00
parent 0e15dc2ffe
commit 8f16cf1f19
2 changed files with 35 additions and 43 deletions

View File

@@ -249,6 +249,8 @@ class GrammarRegistry {
fileTypes = fileTypes.concat(customFileTypes)
}
if (!Array.isArray(fileTypes)) debugger
for (let i = 0; i < fileTypes.length; i++) {
const fileType = fileTypes[i]
const fileTypeComponents = fileType.toLowerCase().split(PATH_SPLIT_REGEX)
@@ -397,7 +399,7 @@ class GrammarRegistry {
// returns a {String} that will be tested against other grammars' `injectionRegExp` in
// order to determine what language should be embedded.
// * `content` A {Function} that is called with syntax nodes of the specified `type` and
// returns another syntax node that contains the embedded source code.
// returns another syntax node or array of syntax nodes that contain the embedded source code.
addInjectionPoint (grammarId, injectionPoint) {
const grammar = this.treeSitterGrammarsById[grammarId]
if (grammar) {

View File

@@ -410,12 +410,13 @@ class TreeSitterLanguageMode {
}
class LanguageLayer {
constructor (languageMode, grammar) {
constructor (languageMode, grammar, contentChildTypes) {
this.languageMode = languageMode
this.grammar = grammar
this.tree = null
this.currentParsePromise = null
this.patchSinceCurrentParseStarted = null
this.contentChildTypes = contentChildTypes
}
buildHighlightIterator () {
@@ -456,10 +457,10 @@ class LanguageLayer {
}
}
async update (containingNode) {
async update (containingNodes) {
if (this.currentParsePromise) return this.currentParsePromise
this.currentParsePromise = this._performUpdate(containingNode)
this.currentParsePromise = this._performUpdate(containingNodes)
await this.currentParsePromise
this.currentParsePromise = null
@@ -472,29 +473,30 @@ class LanguageLayer {
))
}
this.patchSinceCurrentParseStarted = null
this.update(containingNode)
this.update(containingNodes)
}
}
updateInjections (grammar) {
if (!grammar.injectionRegExp) return
if (!this.currentParsePromise) this.currentParsePromise = Promise.resolve()
this.currentParsePromise = this.currentParsePromise.then(async () => {
await this._populateInjections(MAX_RANGE, grammar)
const markers = this.languageMode.injectionsMarkerLayer.getMarkers().filter(marker =>
marker.parentLanguageLayer === this
)
for (const marker of markers) {
await marker.languageLayer._populateInjections(MAX_RANGE, grammar)
}
this.currentParsePromise = null
})
// if (!grammar.injectionRegExp) return
// if (!this.currentParsePromise) this.currentParsePromise = Promise.resolve()
// this.currentParsePromise = this.currentParsePromise.then(async () => {
// await this._populateInjections(MAX_RANGE, grammar)
// const markers = this.languageMode.injectionsMarkerLayer.getMarkers().filter(marker =>
// marker.parentLanguageLayer === this
// )
// for (const marker of markers) {
// await marker.languageLayer._populateInjections(MAX_RANGE, grammar)
// }
// this.currentParsePromise = null
// })
}
async _performUpdate (containingNode) {
let includedRanges
if (containingNode) {
includedRanges = this._rangesForInjectionNode(containingNode)
async _performUpdate (containingNodes) {
let includedRanges = []
if (containingNodes) {
for (const node of containingNodes)
includedRanges.push(...this._rangesForInjectionNode(node))
if (includedRanges.length === 0) return
}
@@ -561,9 +563,12 @@ class LanguageLayer {
if (!grammar) continue
if (newGrammar && grammar !== newGrammar) continue
const injectionNode = injectionPoint.content(node)
if (!injectionNode) continue
const contentNodes = injectionPoint.content(node)
if (!contentNodes) continue
const injectionNodes = [].concat(contentNodes)
if (!injectionNodes.length) continue
const injectionRange = this._rangeForNode(node)
let marker = existingInjectionMarkers.find(m =>
m.getRange().isEqual(injectionRange) &&
@@ -571,11 +576,11 @@ class LanguageLayer {
)
if (!marker) {
marker = injectionsMarkerLayer.markRange(injectionRange)
marker.languageLayer = new LanguageLayer(this.languageMode, grammar)
marker.languageLayer = new LanguageLayer(this.languageMode, grammar, injectionPoint.contentChildTypes)
marker.parentLanguageLayer = this
}
markersToUpdate.set(marker, injectionNode)
markersToUpdate.set(marker, injectionNodes)
}
}
@@ -588,31 +593,16 @@ class LanguageLayer {
}
const promises = []
for (const [marker, injectionNode] of markersToUpdate) {
promises.push(marker.languageLayer.update(injectionNode))
for (const [marker, injectionNodes] of markersToUpdate) {
promises.push(marker.languageLayer.update(injectionNodes))
}
return Promise.all(promises)
}
/**
* @param node {Parser.SyntaxNode}
* @param fromChildrenOfType {Object}
*/
_rangesForInjectionNode (node, fromChildrenOfType) {
if (!fromChildrenOfType)
return this._textRangesForInjectionNode(node)
const ranges = []
for (const child of node.namedChildren) {
if (fromChildrenOfType[child.type])
ranges.push(...this._textRangesForInjectionNode(child))
}
return ranges
}
/**
* @param node {Parser.SyntaxNode}
*/
_textRangesForInjectionNode (node) {
_rangesForInjectionNode (node) {
const result = []
let position = node.startPosition
let index = node.startIndex