Skip to content

Commit 9a1ab31

Browse files
committed
Working Java to Kotlin converter - fixes #24
1 parent 24c15d2 commit 9a1ab31

File tree

8 files changed

+65
-13
lines changed

8 files changed

+65
-13
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ dependencies {
5959
kotlinJVMLib tc("$kotlinTeamCity/lib/kotlin-plugin.jar")
6060

6161
implementation fileTree(dir: "lib", include: ["*.jar"])
62+
implementation fileTree(dir: "lib-kotlin", include: ["*.jar"])
6263
testImplementation "org.hamcrest:hamcrest-all:1.3"
6364
testImplementation "junit:junit:4.10"
6465
testImplementation "org.openjdk.jmh:jmh-core:1.20"

lib/kotlin-converter.jar

-681 KB
Binary file not shown.

src/main/kotlin/org/javacs/kt/Compiler.kt

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,17 @@
11
package org.javacs.kt
22

3+
import com.intellij.codeInsight.NullableNotNullManager
34
import com.intellij.openapi.Disposable
45
import com.intellij.openapi.vfs.StandardFileSystems
56
import com.intellij.openapi.vfs.VirtualFileManager
67
import com.intellij.psi.PsiFileFactory
8+
import com.intellij.mock.MockProject
79
import org.jetbrains.kotlin.cli.common.script.CliScriptDefinitionProvider
810
import org.jetbrains.kotlin.cli.jvm.compiler.CliBindingTrace
911
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles
1012
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
1113
import org.jetbrains.kotlin.cli.jvm.compiler.TopDownAnalyzerFacadeForJVM
12-
import org.jetbrains.kotlin.cli.jvm.config.JvmClasspathRoot
14+
import org.jetbrains.kotlin.cli.jvm.config.addJvmClasspathRoots
1315
import org.jetbrains.kotlin.config.CommonConfigurationKeys
1416
import org.jetbrains.kotlin.config.CompilerConfiguration
1517
import org.jetbrains.kotlin.config.JVMConfigurationKeys
@@ -35,6 +37,7 @@ import java.nio.file.Paths
3537
import java.util.concurrent.locks.ReentrantLock
3638
import kotlin.concurrent.withLock
3739
import org.javacs.kt.util.KotlinLSException
40+
import org.javacs.kt.util.KotlinNullableNotNullManager
3841

3942
/**
4043
* Incrementally compiles files and expressions.
@@ -43,7 +46,7 @@ import org.javacs.kt.util.KotlinLSException
4346
class Compiler(classPath: Set<Path>) {
4447
private val config = CompilerConfiguration().apply {
4548
put(CommonConfigurationKeys.MODULE_NAME, JvmAbi.DEFAULT_MODULE_NAME)
46-
addAll(JVMConfigurationKeys.CONTENT_ROOTS, classPath.map { JvmClasspathRoot(it.toFile())})
49+
addJvmClasspathRoots(classPath.map { it.toFile() })
4750
}
4851
val environment: KotlinCoreEnvironment
4952

@@ -54,6 +57,10 @@ class Compiler(classPath: Set<Path>) {
5457
configuration = config,
5558
configFiles = EnvironmentConfigFiles.JVM_CONFIG_FILES
5659
)
60+
val project = environment.project
61+
if (project is MockProject) {
62+
project.registerService(NullableNotNullManager::class.java, KotlinNullableNotNullManager(project))
63+
}
5764
}
5865

5966
private val parser = KtPsiFactory(environment.project)

src/main/kotlin/org/javacs/kt/KotlinWorkspaceService.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package org.javacs.kt
22

3+
import com.intellij.openapi.project.Project
34
import org.eclipse.lsp4j.*
45
import org.eclipse.lsp4j.services.WorkspaceService
56
import org.eclipse.lsp4j.services.LanguageClient
@@ -37,7 +38,7 @@ class KotlinWorkspaceService(
3738
val range = gson.fromJson(args[1] as JsonElement, Range::class.java)
3839

3940
val selectedJavaCode = extractRange(sp.content(filePath), range)
40-
val kotlinCode = convertJavaToKotlin(cp.compiler.environment, selectedJavaCode)
41+
val kotlinCode = convertJavaToKotlin(selectedJavaCode, cp.compiler)
4142

4243
languageClient?.applyEdit(ApplyWorkspaceEditParams(WorkspaceEdit(listOf(TextDocumentEdit(
4344
VersionedTextDocumentIdentifier().apply { uri = fileUri },
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
package org.javacs.kt.j2k
22

3-
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
3+
import com.intellij.openapi.project.Project
44
import org.jetbrains.kotlin.j2k.JavaToKotlinTranslator
55
import org.javacs.kt.LOG
6+
import org.javacs.kt.Compiler
7+
import org.javacs.kt.util.nonNull
68

7-
fun convertJavaToKotlin(environment: KotlinCoreEnvironment, javaCode: String): String {
8-
LOG.info("Converting to Kotlin: $javaCode")
9-
return JavaToKotlinTranslator.generateKotlinCode(javaCode, environment.project)
9+
fun convertJavaToKotlin(javaCode: String, compiler: Compiler): String {
10+
val project = compiler.environment.project
11+
LOG.info("Converting to Kotlin: $javaCode with project ${project}")
12+
13+
return JavaToKotlinTranslator.generateKotlinCode(
14+
nonNull(javaCode, "No Java code has been provided to the J2K-converter"),
15+
nonNull(project, "No project is present in the KotlinCoreEnvironment")
16+
)
1017
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
package org.javacs.kt.util
2+
3+
public class KotlinLSException: RuntimeException {
4+
constructor(msg: String) : super(msg) {}
5+
6+
constructor(msg: String, cause: Throwable) : super(msg, cause) {}
7+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Source: https://github.com/JetBrains/kotlin-netbeans/blob/master/src/main/java/org/jetbrains/kotlin/model/KotlinNullableNotNullManager.kt
3+
* Licensed under http://www.apache.org/licenses/LICENSE-2.0
4+
*/
5+
package org.javacs.kt.util
6+
7+
import com.intellij.openapi.project.Project
8+
import com.intellij.codeInsight.NullableNotNullManager
9+
import com.intellij.psi.PsiElement
10+
import com.intellij.psi.PsiModifierListOwner
11+
12+
class KotlinNullableNotNullManager(project: Project): NullableNotNullManager(project) {
13+
init {
14+
setNotNulls("NotNull")
15+
setNullables("Nullable")
16+
}
17+
18+
override fun hasHardcodedContracts(element: PsiElement) = false
19+
20+
override fun isNotNull(owner: PsiModifierListOwner, checkBases: Boolean): Boolean {
21+
val notNullAnnotations = notNulls.toSet()
22+
return owner.modifierList?.annotations?.any { annotation ->
23+
annotation.qualifiedName in notNullAnnotations
24+
} ?: false
25+
}
26+
27+
override fun isNullable(owner: PsiModifierListOwner, checkBases: Boolean) = !isNotNull(owner, checkBases)
28+
29+
override fun getPredefinedNotNulls() = emptyList<String>()
30+
}

src/main/kotlin/org/javacs/kt/util/utils.kt

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,6 @@ fun <T> emptyResult(message: String): List<T> = noResult(message, emptyList())
6464

6565
fun <T> nullResult(message: String): T? = noResult(message, null)
6666

67-
public class KotlinLSException: RuntimeException {
68-
constructor(msg: String) : super(msg) {}
69-
70-
constructor(msg: String, cause: Throwable) : super(msg, cause) {}
71-
}
72-
7367
fun <T> firstNonNull(vararg optionals: () -> T?): T? {
7468
for (optional in optionals) {
7569
val result = optional()
@@ -80,6 +74,11 @@ fun <T> firstNonNull(vararg optionals: () -> T?): T? {
8074
return null
8175
}
8276

77+
fun <T> nonNull(item: T?, errorMsgIfNull: String): T =
78+
if (item == null) {
79+
throw NullPointerException(errorMsgIfNull)
80+
} else item
81+
8382
fun <T> tryResolving(what: String, resolver: () -> T?): T? {
8483
try {
8584
val resolved = resolver()

0 commit comments

Comments
 (0)