fix: occasional crash in TsLooperThread when text is edited too frequently

This commit is contained in:
Akash Yadav
2023-10-16 22:15:47 +05:30
parent 1d67056f32
commit 0a5a5400a5
5 changed files with 43 additions and 21 deletions
@@ -42,7 +42,11 @@ class TreeSitterQueryCapture @JvmOverloads internal constructor(
}
override fun recycle() {
(this.node as? TreeSitterNode?)?.recycle()
(this.node as? TreeSitterNode?)?.apply {
if (!isRecycled) {
recycle()
}
}
this.index = 0
this.node = null
returnToPool()
@@ -236,19 +236,23 @@ class LineSpansGenerator(
private var spans = mutableListOf<Span>()
override fun moveToLine(line: Int) {
if (line < 0 || line >= lineCount) {
spans = mutableListOf()
return
try {
if (line < 0 || line >= lineCount) {
spans = mutableListOf()
return
}
val cached = queryCache(line)
if (cached != null) {
spans = cached
return
}
val start = content.indexer.getCharPosition(line, 0).index
val end = start + content.getColumnCount(line)
spans = captureRegion(start, end)
pushCache(line, spans)
} catch (err: Throwable) {
err.printStackTrace()
}
val cached = queryCache(line)
if (cached != null) {
spans = cached
return
}
val start = content.indexer.getCharPosition(line, 0).index
val end = start + content.getColumnCount(line)
spans = captureRegion(start, end)
pushCache(line, spans)
}
override fun getSpanCount() = spans.size
@@ -256,13 +260,18 @@ class LineSpansGenerator(
override fun getSpanAt(index: Int) = spans[index]
override fun getSpansOnLine(line: Int): MutableList<Span> {
val cached = queryCache(line)
if (cached != null) {
return ArrayList(cached)
try {
val cached = queryCache(line)
if (cached != null) {
return ArrayList(cached)
}
val start = content.indexer.getCharPosition(line, 0).index
val end = start + content.getColumnCount(line)
return captureRegion(start, end)
} catch (err: Throwable) {
err.printStackTrace()
throw err
}
val start = content.indexer.getCharPosition(line, 0).index
val end = start + content.getColumnCount(line)
return captureRegion(start, end)
}
}
@@ -122,7 +122,11 @@ class TsScopedVariables(tree: TSTree, text: UTF16String, val spec: TsLanguageSpe
}
}
(capture as? TreeSitterQueryCapture?)?.recycle()
(capture as? TreeSitterQueryCapture?)?.apply {
if (!isRecycled) {
recycle()
}
}
}
}
}
@@ -26,6 +26,8 @@ open class DefaultRecyclable : RecyclableObjectPool.Recyclable {
private val _isRecycled = AtomicBoolean(false)
@set:Synchronized
@get:Synchronized
override var isRecycled: Boolean
get() = _isRecycled.get()
set(value) {
@@ -95,7 +95,10 @@ class RecyclableObjectPool<RecyclableT : RecyclableObjectPool.Recyclable> @JvmOv
* Recycle the given object.
*/
fun recycle(obj: RecyclableT): Boolean {
check(!obj.isRecycled) { "Object is already recycled" }
if (obj.isRecycled) {
log.warn("Trying to recyle already recycled object: $obj")
return false
}
return cache.offer(obj).also { inserted ->
if (inserted) {