class TreeSitterSyntaxState {
constructor(tree, upto) {
this.tree = tree
this.upto = upto
this.parsingTask = null
this.updatedTree = tree
}
static _parseOrFail(parser, doc, parseArgs, time = 0, _upto = 5e6) {
let result = null
const oldParseTimeout = parser.getTimeoutMicros()
parser.setTimeoutMicros(time)
try {
result = parser.parse((index, position) => {
const {row, column} = position
const line = doc.text[row]
if (line != null) {
return (line + (row != doc.lines - 1 ? '\n' : '')).slice(column)
}
}, ...parseArgs);
} catch (e) {
if (e.message == 'Parsing failed') {
console.warn('TreeSitter parsing failed, usually due to timeout...')
} else {
console.error('Exception from tree-sitter! There may be bugs in tree-sitter or language definition.', e)
}
} finally {
parser.setTimeoutMicros(oldParseTimeout)
}
return result
}
static init(parser, doc) {
const tsTree = TreeSitterSyntaxState._parseOrFail(parser, doc, [])
const tree = tsTree ? new SitterTree(tsTree).build() : _LezerTree.Tree.empty
return new TreeSitterSyntaxState(tree, tsTree ? doc.length : 0)
}
apply(tr, parser, effect) {
for (let e of tr.effects) if (e.is(effect)) return e.value
if (!tr.docChanged) return this
return TreeSitterSyntaxState.init(parser, tr.doc)
}
startParse(parser, doc) {
this.parsingTask = TreeSitterSyntaxState._parseOrFail(parser, doc, [this.updatedTree])
}
}