diff --git a/annotations/com/intellij/psi/annotations.xml b/annotations/com/intellij/psi/annotations.xml
index b024c06da0b..5b4da145766 100644
--- a/annotations/com/intellij/psi/annotations.xml
+++ b/annotations/com/intellij/psi/annotations.xml
@@ -304,6 +304,9 @@
-
+ -
+
+
-
diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java
index 9cd5d4fd696..928a3ce4e45 100644
--- a/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java
+++ b/compiler/frontend/src/org/jetbrains/jet/lang/psi/JetPsiFactory.java
@@ -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);
}
diff --git a/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt b/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt
new file mode 100644
index 00000000000..452892ad535
--- /dev/null
+++ b/j2k/src/org/jetbrains/jet/j2k/AfterConversionPass.kt
@@ -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(""), 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
+ }
+ }
+}
\ No newline at end of file
diff --git a/j2k/src/org/jetbrains/jet/j2k/Converter.kt b/j2k/src/org/jetbrains/jet/j2k/Converter.kt
index d9e3a632c77..02f35dfdd83 100644
--- a/j2k/src/org/jetbrains/jet/j2k/Converter.kt
+++ b/j2k/src/org/jetbrains/jet/j2k/Converter.kt
@@ -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)
diff --git a/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt b/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt
index 8c97cd0e710..c1b7cb7b2b6 100644
--- a/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt
+++ b/j2k/src/org/jetbrains/jet/j2k/JavaToKotlinTranslator.kt
@@ -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 {
diff --git a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java
index 40a5375571d..3bc6b7ea6e2 100644
--- a/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java
+++ b/j2k/tests/test/org/jetbrains/jet/j2k/test/JavaToKotlinConverterTestGenerated.java
@@ -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");
diff --git a/j2k/tests/testData/ast/annotations/jetbrainsNotNull.kt b/j2k/tests/testData/ast/annotations/jetbrainsNotNull.kt
index 95eb63cf760..36d5b9672a2 100644
--- a/j2k/tests/testData/ast/annotations/jetbrainsNotNull.kt
+++ b/j2k/tests/testData/ast/annotations/jetbrainsNotNull.kt
@@ -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 {
diff --git a/j2k/tests/testData/ast/annotations/jetbrainsNotNullChainExpr.kt b/j2k/tests/testData/ast/annotations/jetbrainsNotNullChainExpr.kt
index 1bfbd71d7ee..9b4ceebf396 100644
--- a/j2k/tests/testData/ast/annotations/jetbrainsNotNullChainExpr.kt
+++ b/j2k/tests/testData/ast/annotations/jetbrainsNotNullChainExpr.kt
@@ -17,6 +17,6 @@ class Test {
barNotNull.fooNotNull.execute()
barNotNull.fooNullable!!.execute()
barNullable!!.fooNotNull.execute()
- barNullable!!.fooNullable!!.execute()
+ barNullable.fooNullable!!.execute()
}
}
\ No newline at end of file
diff --git a/j2k/tests/testData/ast/issues/kt-824-isDir.kt b/j2k/tests/testData/ast/issues/kt-824-isDir.kt
index d7dfee5cea5..2239e074545 100644
--- a/j2k/tests/testData/ast/issues/kt-824-isDir.kt
+++ b/j2k/tests/testData/ast/issues/kt-824-isDir.kt
@@ -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
diff --git a/j2k/tests/testData/ast/nullability/autoNotNull.java b/j2k/tests/testData/ast/nullability/autoNotNull.java
new file mode 100644
index 00000000000..bf4ed4a8699
--- /dev/null
+++ b/j2k/tests/testData/ast/nullability/autoNotNull.java
@@ -0,0 +1,9 @@
+//file
+class A {
+ int foo(String s) {
+ if (s != null) {
+ return s.length();
+ }
+ return -1;
+ }
+}
\ No newline at end of file
diff --git a/j2k/tests/testData/ast/nullability/autoNotNull.kt b/j2k/tests/testData/ast/nullability/autoNotNull.kt
new file mode 100644
index 00000000000..ae7a34d9237
--- /dev/null
+++ b/j2k/tests/testData/ast/nullability/autoNotNull.kt
@@ -0,0 +1,8 @@
+class A {
+ fun foo(s: String?): Int {
+ if (s != null) {
+ return s.length()
+ }
+ return -1
+ }
+}
\ No newline at end of file