Java to Kotlin converter: added auto-conversion run of Kotlin analyzer. Implemented first fix with it - redundant !! removal
This commit is contained in:
@@ -304,6 +304,9 @@
|
||||
<item name='com.intellij.psi.PsiExpressionStatement'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.psi.PsiFileFactory com.intellij.psi.PsiFileFactory getInstance(com.intellij.openapi.project.Project) 0'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
<item name='com.intellij.psi.PsiForStatement'>
|
||||
<annotation name='org.jetbrains.annotations.NotNull'/>
|
||||
</item>
|
||||
|
||||
@@ -144,23 +144,23 @@ public class JetPsiFactory {
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetClass createClass(Project project, String text) {
|
||||
public static JetClass createClass(@NotNull Project project, @NotNull String text) {
|
||||
return createDeclaration(project, text, JetClass.class);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetFile createFile(Project project, String text) {
|
||||
public static JetFile createFile(@NotNull Project project, @NotNull String text) {
|
||||
return createFile(project, "dummy.kt", text);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetFile createFile(Project project, String fileName, String text) {
|
||||
public static JetFile createFile(@NotNull Project project, @NotNull String fileName, @NotNull String text) {
|
||||
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text,
|
||||
LocalTimeCounter.currentTime(), false);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static JetFile createPhysicalFile(Project project, String fileName, String text) {
|
||||
public static JetFile createPhysicalFile(@NotNull Project project, @NotNull String fileName, @NotNull String text) {
|
||||
return (JetFile) PsiFileFactory.getInstance(project).createFileFromText(fileName, JetFileType.INSTANCE, text,
|
||||
LocalTimeCounter.currentTime(), true);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* Copyright 2010-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.jet.j2k
|
||||
|
||||
import org.jetbrains.jet.lang.psi.JetPsiFactory
|
||||
import org.jetbrains.jet.lang.resolve.java.AnalyzerFacadeForJVM
|
||||
import org.jetbrains.jet.lang.resolve.BindingTraceContext
|
||||
import org.jetbrains.jet.lang.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.jet.lang.resolve.name.Name
|
||||
import org.jetbrains.jet.lang.resolve.java.mapping.JavaToKotlinClassMap
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.jet.lang.diagnostics.Diagnostic
|
||||
import org.jetbrains.jet.lang.diagnostics.Errors
|
||||
import org.jetbrains.jet.lang.psi.JetSimpleNameExpression
|
||||
import org.jetbrains.jet.lang.psi.JetUnaryExpression
|
||||
|
||||
class AfterConversionPass(val project: Project) {
|
||||
public fun run(kotlinCode: String): String {
|
||||
val kotlinFile = JetPsiFactory.createFile(project, kotlinCode)
|
||||
val analyzeExhaust = AnalyzerFacadeForJVM.analyzeFilesWithJavaIntegration(
|
||||
project,
|
||||
listOf(kotlinFile),
|
||||
BindingTraceContext(),
|
||||
{ true },
|
||||
ModuleDescriptorImpl(Name.special("<module>"), AnalyzerFacadeForJVM.DEFAULT_IMPORTS, JavaToKotlinClassMap.getInstance()),
|
||||
null,
|
||||
null
|
||||
)
|
||||
|
||||
val problems = analyzeExhaust.getBindingContext().getDiagnostics()
|
||||
val fixes = problems.map {
|
||||
val fix = fixForProblem(it)
|
||||
if (fix != null) it.getPsiElement() to fix else null
|
||||
}.filterNotNull()
|
||||
|
||||
if (fixes.isEmpty()) return kotlinCode
|
||||
|
||||
for ((psiElement, fix) in fixes) {
|
||||
if (psiElement.isValid()) {
|
||||
fix()
|
||||
}
|
||||
}
|
||||
return kotlinFile.getText()!!
|
||||
}
|
||||
|
||||
private fun fixForProblem(problem: Diagnostic): (() -> Unit)? {
|
||||
return when (problem.getFactory()) {
|
||||
Errors.UNNECESSARY_NOT_NULL_ASSERTION -> { () ->
|
||||
val exclExclOp = problem.getPsiElement() as JetSimpleNameExpression
|
||||
val exclExclExpr = exclExclOp.getParent() as JetUnaryExpression
|
||||
exclExclExpr.replace(exclExclExpr.getBaseExpression()!!)
|
||||
}
|
||||
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -61,7 +61,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
val converted = convertTopElement(element) ?: return ""
|
||||
val builder = CodeBuilder(element)
|
||||
builder.append(converted)
|
||||
return builder.result
|
||||
return AfterConversionPass(project).run(builder.result)
|
||||
}
|
||||
|
||||
private fun convertTopElement(element: PsiElement?): Element? = when (element) {
|
||||
@@ -78,7 +78,7 @@ public class Converter private(val project: Project, val settings: ConverterSett
|
||||
else -> null
|
||||
}
|
||||
|
||||
fun convertFile(javaFile: PsiJavaFile): File {
|
||||
private fun convertFile(javaFile: PsiJavaFile): File {
|
||||
var convertedChildren = javaFile.getChildren().map {
|
||||
if (it is PsiImportList) {
|
||||
val importList = convertImportList(it)
|
||||
|
||||
@@ -21,21 +21,19 @@ import com.intellij.core.JavaCoreProjectEnvironment
|
||||
import com.intellij.lang.java.JavaLanguage
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.openapi.util.Disposer
|
||||
import com.intellij.psi.PsiElement
|
||||
import com.intellij.psi.PsiFile
|
||||
import com.intellij.psi.PsiFileFactory
|
||||
import com.intellij.psi.PsiJavaFile
|
||||
import org.jetbrains.jet.utils.PathUtil
|
||||
import java.io.File
|
||||
import java.net.URLClassLoader
|
||||
import java.util.HashSet
|
||||
|
||||
public object JavaToKotlinTranslator {
|
||||
private val DISPOSABLE = Disposer.newDisposable()
|
||||
|
||||
private fun createFile(text: String): PsiFile? {
|
||||
val javaCoreEnvironment: JavaCoreProjectEnvironment? = setUpJavaCoreEnvironment()
|
||||
return PsiFileFactory.getInstance(javaCoreEnvironment?.getProject())?.createFileFromText("test.java", JavaLanguage.INSTANCE, text)
|
||||
return PsiFileFactory.getInstance(javaCoreEnvironment?.getProject()!!)?.createFileFromText("test.java", JavaLanguage.INSTANCE, text)
|
||||
}
|
||||
|
||||
fun createFile(project: Project, text: String): PsiJavaFile {
|
||||
|
||||
@@ -2199,6 +2199,11 @@ public class JavaToKotlinConverterTestGenerated extends AbstractJavaToKotlinConv
|
||||
JetTestUtils.assertAllTestsPresentByMetadata(this.getClass(), "org.jetbrains.jet.generators.tests.TestsPackage", new File("j2k/tests/testData/ast/nullability"), Pattern.compile("^(.+)\\.java$"), true);
|
||||
}
|
||||
|
||||
@TestMetadata("autoNotNull.java")
|
||||
public void testAutoNotNull() throws Exception {
|
||||
doTest("j2k/tests/testData/ast/nullability/autoNotNull.java");
|
||||
}
|
||||
|
||||
@TestMetadata("FieldAssignedWithNull.java")
|
||||
public void testFieldAssignedWithNull() throws Exception {
|
||||
doTest("j2k/tests/testData/ast/nullability/FieldAssignedWithNull.java");
|
||||
|
||||
@@ -10,7 +10,7 @@ public class Test(str: String) {
|
||||
}
|
||||
|
||||
public fun sout(str: String) {
|
||||
System.out!!.println(str)
|
||||
System.out.println(str)
|
||||
}
|
||||
|
||||
public fun dummy(str: String): String {
|
||||
|
||||
@@ -17,6 +17,6 @@ class Test {
|
||||
barNotNull.fooNotNull.execute()
|
||||
barNotNull.fooNullable!!.execute()
|
||||
barNullable!!.fooNotNull.execute()
|
||||
barNullable!!.fooNullable!!.execute()
|
||||
barNullable.fooNullable!!.execute()
|
||||
}
|
||||
}
|
||||
@@ -8,11 +8,11 @@ import java.io.File
|
||||
public class Test {
|
||||
class object {
|
||||
public fun isDir(parent: File?): Boolean {
|
||||
if (parent == null || !parent!!.exists()) {
|
||||
if (parent == null || !parent.exists()) {
|
||||
return false
|
||||
}
|
||||
val result = true
|
||||
if (parent!!.isDirectory()) {
|
||||
if (parent.isDirectory()) {
|
||||
return true
|
||||
} else
|
||||
return false
|
||||
|
||||
@@ -0,0 +1,9 @@
|
||||
//file
|
||||
class A {
|
||||
int foo(String s) {
|
||||
if (s != null) {
|
||||
return s.length();
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
class A {
|
||||
fun foo(s: String?): Int {
|
||||
if (s != null) {
|
||||
return s.length()
|
||||
}
|
||||
return -1
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user