Java to Kotlin converter: added auto-conversion run of Kotlin analyzer. Implemented first fix with it - redundant !! removal

This commit is contained in:
Valentin Kipyatkov
2014-07-10 15:05:54 +04:00
parent 69a5b79342
commit acc58173da
11 changed files with 107 additions and 13 deletions
@@ -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
}
}
}
+2 -2
View File
@@ -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
}
}