fix: TSTree instances are sometimes not closed, causing memory leak

This commit is contained in:
Akash Yadav
2023-11-21 17:39:52 +05:30
parent cdc9ddb265
commit 3f97f24b4c
5 changed files with 52 additions and 44 deletions
+1 -1
View File
@@ -216,7 +216,7 @@
</value>
</option>
</component>
<component name="ProjectRootManager" version="2" languageLevel="JDK_1_8" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">
<output url="file://$PROJECT_DIR$/build/classes" />
</component>
<component name="ProjectType">
@@ -120,38 +120,38 @@ abstract class TreeSitterLanguage(context: Context, lang: TSLanguage, type: Stri
val indentsQuery = languageSpec.indentsQuery ?: return 0
return TSParser.create().use { parser ->
parser.language = languageSpec.language
val tree = parser.parseString(content)
return@use parser.parseString(content).use { tree ->
TSQueryCursor.create().use { cursor ->
cursor.exec(indentsQuery, tree.rootNode)
return@use TSQueryCursor.create().use { cursor ->
cursor.exec(indentsQuery, tree.rootNode)
var indent = 0
var match: TSQueryMatch? = cursor.nextMatch()
val captures = mutableListOf<TSQueryCapture>()
while (match != null) {
captures.addAll(match.captures)
match = cursor.nextMatch()
}
captures.sortBy { it.node.startByte }
for (capture in captures) {
val capLine = capture.node.startPoint.row
val capCol = capture.node.endPoint.column / 2
if (capLine > line || (capLine == line && capCol > column)) {
break
var indent = 0
var match: TSQueryMatch? = cursor.nextMatch()
val captures = mutableListOf<TSQueryCapture>()
while (match != null) {
captures.addAll(match.captures)
match = cursor.nextMatch()
}
val captureName = indentsQuery.getCaptureNameForId(capture.index)
if (captureName == "indent") {
++indent
} else if (captureName == "outdent") {
--indent
}
}
captures.sortBy { it.node.startByte }
finalizeIndent(indent) - decrementBy
for (capture in captures) {
val capLine = capture.node.startPoint.row
val capCol = capture.node.endPoint.column / 2
if (capLine > line || (capLine == line && capCol > column)) {
break
}
val captureName = indentsQuery.getCaptureNameForId(capture.index)
if (captureName == "indent") {
++indent
} else if (captureName == "outdent") {
--indent
}
}
finalizeIndent(indent) - decrementBy
}
}
}
}
@@ -24,6 +24,7 @@ import com.itsaky.androidide.lsp.java.parser.ts.TSMethodPruner.prune
import com.itsaky.androidide.projects.FileManager
import com.itsaky.androidide.utils.StopWatch
import com.itsaky.androidide.utils.VMUtils
import com.itsaky.androidide.utils.withStopWatch
import jdkx.tools.JavaFileObject
import jdkx.tools.JavaFileObject.Kind.SOURCE
import kotlin.io.path.name
@@ -58,19 +59,22 @@ class JavaCompilerImpl(context: Context?) : ReusableJavaCompiler(context) {
return super.parse(filename, content)
}
val pruned =
StopWatch("${if(file is SourceFileObject) "[${file.path.name}] " else ""}Prune method bodies")
.let {
val contentBuilder = StringBuilder(content)
val parseResult = TSJavaParser.parse(file)
prune(
contentBuilder,
parseResult.tree,
compilerConfig.completionInfo?.cursor?.index ?: -1
)
it.log()
return@let contentBuilder
}
val pruned = withStopWatch("${if(file is SourceFileObject) "[${file.path.name}] " else ""}Prune method bodies") { watch ->
val contentBuilder = StringBuilder(content)
return@withStopWatch TSJavaParser.parse(file).use { parseResult ->
prune(
contentBuilder,
parseResult.tree,
compilerConfig.completionInfo?.cursor?.index ?: -1
)
watch.log()
return@use contentBuilder
}
}
return super.parse(filename, pruned)
}
@@ -69,7 +69,7 @@ object TSJavaParser : IJavaParser<TSParseResult> {
check(file.kind == JavaFileObject.Kind.SOURCE) { "File must a source file object" }
synchronized(this.cache) {
val result = this.cache.get(file.toUri())
val result = this.cache[file.toUri()]
if (result != null) {
if (result.fileModified == file.lastModified) {
// cache hit and cache modified == file modified
@@ -26,7 +26,11 @@ import java.net.URI
*
* @author Akash Yadav
*/
class TSParseResult(file: JavaFileObject, val tree: TSTree) {
class TSParseResult(file: JavaFileObject, val tree: TSTree) : AutoCloseable {
val uri: URI = file.toUri()
val fileModified: Long = file.lastModified
override fun close() {
tree.close()
}
}