diff --git a/app/src/main/assets/data/common/tooling-api-all.jar b/app/src/main/assets/data/common/tooling-api-all.jar index 5ff75a6be..fc4aeab37 100644 Binary files a/app/src/main/assets/data/common/tooling-api-all.jar and b/app/src/main/assets/data/common/tooling-api-all.jar differ diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaLSPTest.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaLSPTest.kt index 113682c7f..66a22e126 100644 --- a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaLSPTest.kt +++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/JavaLSPTest.kt @@ -20,6 +20,7 @@ package com.itsaky.androidide.lsp.java import com.itsaky.androidide.lsp.api.ILanguageServerRegistry import com.itsaky.androidide.lsp.api.LSPTest import com.itsaky.androidide.lsp.java.actions.AddImportTester +import com.itsaky.androidide.lsp.java.compiler.CompilerTest import com.itsaky.androidide.lsp.java.compiler.JavaCompilerService import com.itsaky.androidide.lsp.java.partial.PartialReparserImplTester import com.itsaky.androidide.lsp.java.providers.JavaCompletionProviderTester @@ -59,6 +60,7 @@ open class JavaLSPTest : LSPTest() { @Test override fun test() { + CompilerTest().test() AddImportTester().test() PartialReparserImplTester().test() JavaCompletionProviderTester().test() diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/actions/AddImportTester.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/actions/AddImportTester.kt index 8a69e982b..4b02ba18c 100644 --- a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/actions/AddImportTester.kt +++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/actions/AddImportTester.kt @@ -33,9 +33,12 @@ class AddImportTester : JavaLSPTest() { openFile("AddImportAction") val diagnostic = - server.analyze(file!!).diagnostics.first { it.code == "compiler.err.cant.resolve.location" } + server.analyze(file!!).diagnostics.firstOrNull { it.code == "compiler.err.cant.resolve.location" } + + assertThat(diagnostic).isNotNull() + val file = this.file!!.toFile() - val data = createActionData(diagnostic, file, this.file!!, this.server) + val data = createActionData(diagnostic!!, file, this.file!!, this.server) val action = AddImportAction() action.prepare(data) diff --git a/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/compiler/CompilerTest.kt b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/compiler/CompilerTest.kt new file mode 100644 index 000000000..ab3d4260f --- /dev/null +++ b/lsp/java/src/test/java/com/itsaky/androidide/lsp/java/compiler/CompilerTest.kt @@ -0,0 +1,98 @@ +/* + * This file is part of AndroidIDE. + * + * AndroidIDE is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * AndroidIDE is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with AndroidIDE. If not, see . + */ + +package com.itsaky.androidide.lsp.java.compiler + +import com.google.common.truth.Truth.assertThat +import com.itsaky.androidide.lsp.java.JavaLSPTest +import java.time.Instant + +/** @author Akash Yadav */ +class CompilerTest : JavaLSPTest() { + + override fun test() { + testConcurrentAccess() + testClosedFileChannel() + testMultipleThreads() + } + + private fun testMultipleThreads() { + openFile("completion/MembersCompletionTest") + val threads = mutableListOf() + val thread = Thread { + getCompiler().compile(file!!).run { + println(Thread.currentThread().name) + delay(1000) + } + } + thread.name = "Long running task" + threads.add(thread) + thread.start() + + for (i in 0..300) { + val th = Thread { + getCompiler().compile(file!!).run { + println(Thread.currentThread().name) + } + } + th.name = "Thread #$i" + threads.add(th) + th.start() + } + + threads.forEach { it.join() } + } + + private fun testClosedFileChannel() { + openFile("completion/MembersCompletionTest") + + Thread { getCompiler().compile(file!!).run { delay(500) } }.start() + Thread { getCompiler().compile(file!!).run { delay(200) } }.start() + + getCompiler().compile(file!!).run { assertThat(it.diagnostics).isNotEmpty() } + } + + private fun delay(millis: Long) { + Thread.sleep(millis) + } + + private fun testConcurrentAccess() { + openFile("completion/MembersCompletionTest") + + var task = getCompiler().compile(file!!) + var fileObject = SourceFileObject(file!!) + val threads = mutableListOf() + for (i in 1..10) { + threads.add( + Thread { + task.run { + delay(100) + println(Thread.currentThread()) + } + } + .apply { name = "CompileTask Acessor #$i" } + ) + } + + fileObject = SourceFileObject(file!!, fileObject.contents, Instant.now()) + task = getCompiler().compile(listOf(fileObject)) + threads.forEach { it.start() } + + Thread { task.run { println("Writer thread") } }.start() + threads.forEach { it.join() } + } +} diff --git a/tests/test-home/.androidide/init/model.jar b/tests/test-home/.androidide/init/model.jar index 5991dba6c..e10bcdcf9 100644 Binary files a/tests/test-home/.androidide/init/model.jar and b/tests/test-home/.androidide/init/model.jar differ