Skip to content
This repository was archived by the owner on Oct 18, 2024. It is now read-only.

Commit 3f97f24

Browse files
committed
fix: TSTree instances are sometimes not closed, causing memory leak
1 parent cdc9ddb commit 3f97f24

File tree

5 files changed

+49
-41
lines changed

5 files changed

+49
-41
lines changed

.idea/misc.xml

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

editor/src/main/java/com/itsaky/androidide/editor/language/treesitter/TreeSitterLanguage.kt

Lines changed: 25 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -120,38 +120,38 @@ abstract class TreeSitterLanguage(context: Context, lang: TSLanguage, type: Stri
120120
val indentsQuery = languageSpec.indentsQuery ?: return 0
121121
return TSParser.create().use { parser ->
122122
parser.language = languageSpec.language
123-
val tree = parser.parseString(content)
124-
125-
return@use TSQueryCursor.create().use { cursor ->
126-
cursor.exec(indentsQuery, tree.rootNode)
123+
return@use parser.parseString(content).use { tree ->
124+
TSQueryCursor.create().use { cursor ->
125+
cursor.exec(indentsQuery, tree.rootNode)
126+
127+
var indent = 0
128+
var match: TSQueryMatch? = cursor.nextMatch()
129+
val captures = mutableListOf<TSQueryCapture>()
130+
while (match != null) {
131+
captures.addAll(match.captures)
132+
match = cursor.nextMatch()
133+
}
127134

128-
var indent = 0
129-
var match: TSQueryMatch? = cursor.nextMatch()
130-
val captures = mutableListOf<TSQueryCapture>()
131-
while (match != null) {
132-
captures.addAll(match.captures)
133-
match = cursor.nextMatch()
134-
}
135+
captures.sortBy { it.node.startByte }
135136

136-
captures.sortBy { it.node.startByte }
137+
for (capture in captures) {
138+
val capLine = capture.node.startPoint.row
139+
val capCol = capture.node.endPoint.column / 2
137140

138-
for (capture in captures) {
139-
val capLine = capture.node.startPoint.row
140-
val capCol = capture.node.endPoint.column / 2
141+
if (capLine > line || (capLine == line && capCol > column)) {
142+
break
143+
}
141144

142-
if (capLine > line || (capLine == line && capCol > column)) {
143-
break
145+
val captureName = indentsQuery.getCaptureNameForId(capture.index)
146+
if (captureName == "indent") {
147+
++indent
148+
} else if (captureName == "outdent") {
149+
--indent
150+
}
144151
}
145152

146-
val captureName = indentsQuery.getCaptureNameForId(capture.index)
147-
if (captureName == "indent") {
148-
++indent
149-
} else if (captureName == "outdent") {
150-
--indent
151-
}
153+
finalizeIndent(indent) - decrementBy
152154
}
153-
154-
finalizeIndent(indent) - decrementBy
155155
}
156156
}
157157
}

lsp/java/src/main/java/com/itsaky/androidide/lsp/java/compiler/JavaCompilerImpl.kt

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import com.itsaky.androidide.lsp.java.parser.ts.TSMethodPruner.prune
2424
import com.itsaky.androidide.projects.FileManager
2525
import com.itsaky.androidide.utils.StopWatch
2626
import com.itsaky.androidide.utils.VMUtils
27+
import com.itsaky.androidide.utils.withStopWatch
2728
import jdkx.tools.JavaFileObject
2829
import jdkx.tools.JavaFileObject.Kind.SOURCE
2930
import kotlin.io.path.name
@@ -58,19 +59,22 @@ class JavaCompilerImpl(context: Context?) : ReusableJavaCompiler(context) {
5859
return super.parse(filename, content)
5960
}
6061

61-
val pruned =
62-
StopWatch("${if(file is SourceFileObject) "[${file.path.name}] " else ""}Prune method bodies")
63-
.let {
64-
val contentBuilder = StringBuilder(content)
65-
val parseResult = TSJavaParser.parse(file)
66-
prune(
67-
contentBuilder,
68-
parseResult.tree,
69-
compilerConfig.completionInfo?.cursor?.index ?: -1
70-
)
71-
it.log()
72-
return@let contentBuilder
73-
}
62+
val pruned = withStopWatch("${if(file is SourceFileObject) "[${file.path.name}] " else ""}Prune method bodies") { watch ->
63+
val contentBuilder = StringBuilder(content)
64+
65+
return@withStopWatch TSJavaParser.parse(file).use { parseResult ->
66+
67+
prune(
68+
contentBuilder,
69+
parseResult.tree,
70+
compilerConfig.completionInfo?.cursor?.index ?: -1
71+
)
72+
73+
watch.log()
74+
75+
return@use contentBuilder
76+
}
77+
}
7478

7579
return super.parse(filename, pruned)
7680
}

lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/ts/TSJavaParser.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ object TSJavaParser : IJavaParser<TSParseResult> {
6969
check(file.kind == JavaFileObject.Kind.SOURCE) { "File must a source file object" }
7070

7171
synchronized(this.cache) {
72-
val result = this.cache.get(file.toUri())
72+
val result = this.cache[file.toUri()]
7373
if (result != null) {
7474
if (result.fileModified == file.lastModified) {
7575
// cache hit and cache modified == file modified

lsp/java/src/main/java/com/itsaky/androidide/lsp/java/parser/ts/TSParseResult.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,11 @@ import java.net.URI
2626
*
2727
* @author Akash Yadav
2828
*/
29-
class TSParseResult(file: JavaFileObject, val tree: TSTree) {
29+
class TSParseResult(file: JavaFileObject, val tree: TSTree) : AutoCloseable {
3030
val uri: URI = file.toUri()
3131
val fileModified: Long = file.lastModified
32+
33+
override fun close() {
34+
tree.close()
35+
}
3236
}

0 commit comments

Comments
 (0)