New J2K: do not shorten class references for some Java primitive class wrappers classes
It may cause unresolved call errors #KT-33500 fixed
This commit is contained in:
@@ -96,7 +96,8 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
||||
return process(listOf(element), elementFilter).single()
|
||||
}
|
||||
|
||||
fun process(file: KtFile, startOffset: Int, endOffset: Int) {
|
||||
@JvmOverloads
|
||||
fun process(file: KtFile, startOffset: Int, endOffset: Int, additionalFilter: (PsiElement) -> FilterResult = { FilterResult.PROCESS }) {
|
||||
val documentManager = PsiDocumentManager.getInstance(file.project)
|
||||
val document = file.viewProvider.document!!
|
||||
if (!documentManager.isCommitted(document)) {
|
||||
@@ -106,33 +107,36 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
||||
val rangeMarker = document.createRangeMarker(startOffset, endOffset)
|
||||
rangeMarker.isGreedyToLeft = true
|
||||
rangeMarker.isGreedyToRight = true
|
||||
|
||||
val rangeFilter = { element: PsiElement ->
|
||||
if (rangeMarker.isValid) {
|
||||
val range = TextRange(rangeMarker.startOffset, rangeMarker.endOffset)
|
||||
|
||||
val elementRange = element.textRange!!
|
||||
when {
|
||||
range.contains(elementRange) -> FilterResult.PROCESS
|
||||
|
||||
range.intersects(elementRange) -> {
|
||||
// for qualified call expression allow to shorten only the part without parenthesis
|
||||
val calleeExpression = ((element as? KtDotQualifiedExpression)
|
||||
?.selectorExpression as? KtCallExpression)
|
||||
?.calleeExpression
|
||||
if (calleeExpression != null) {
|
||||
val rangeWithoutParenthesis = TextRange(elementRange.startOffset, calleeExpression.textRange!!.endOffset)
|
||||
if (range.contains(rangeWithoutParenthesis)) FilterResult.PROCESS else FilterResult.GO_INSIDE
|
||||
} else {
|
||||
FilterResult.GO_INSIDE
|
||||
}
|
||||
}
|
||||
else -> FilterResult.SKIP
|
||||
}
|
||||
} else {
|
||||
FilterResult.SKIP
|
||||
}
|
||||
}
|
||||
try {
|
||||
process(listOf(file)) { element ->
|
||||
if (rangeMarker.isValid) {
|
||||
val range = TextRange(rangeMarker.startOffset, rangeMarker.endOffset)
|
||||
|
||||
val elementRange = element.textRange!!
|
||||
when {
|
||||
range.contains(elementRange) -> FilterResult.PROCESS
|
||||
|
||||
range.intersects(elementRange) -> {
|
||||
// for qualified call expression allow to shorten only the part without parenthesis
|
||||
val calleeExpression = ((element as? KtDotQualifiedExpression)
|
||||
?.selectorExpression as? KtCallExpression)
|
||||
?.calleeExpression
|
||||
if (calleeExpression != null) {
|
||||
val rangeWithoutParenthesis = TextRange(elementRange.startOffset, calleeExpression.textRange!!.endOffset)
|
||||
if (range.contains(rangeWithoutParenthesis)) FilterResult.PROCESS else FilterResult.GO_INSIDE
|
||||
} else {
|
||||
FilterResult.GO_INSIDE
|
||||
}
|
||||
}
|
||||
|
||||
else -> FilterResult.SKIP
|
||||
}
|
||||
} else {
|
||||
FilterResult.SKIP
|
||||
}
|
||||
minOf(rangeFilter(element), additionalFilter(element))
|
||||
}
|
||||
} finally {
|
||||
rangeMarker.dispose()
|
||||
|
||||
+13
-2
@@ -14,6 +14,9 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||
import org.jetbrains.kotlin.idea.core.util.range
|
||||
import org.jetbrains.kotlin.idea.formatter.commitAndUnblockDocument
|
||||
import org.jetbrains.kotlin.idea.refactoring.fqName.getKotlinFqName
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.nj2k.ImportStorage
|
||||
import org.jetbrains.kotlin.nj2k.asLabel
|
||||
import org.jetbrains.kotlin.nj2k.inference.common.BoundTypeCalculatorImpl
|
||||
import org.jetbrains.kotlin.nj2k.inference.common.ByInfoSuperFunctionsProvider
|
||||
@@ -29,6 +32,7 @@ import org.jetbrains.kotlin.nj2k.inference.nullability.NullabilityStateUpdater
|
||||
import org.jetbrains.kotlin.nj2k.postProcessing.postProcessing
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
|
||||
val formatCodeProcessing =
|
||||
postProcessing { file, rangeMarker, _ ->
|
||||
@@ -90,12 +94,19 @@ private fun KtFile.clearUndefinedLabels() {
|
||||
|
||||
val shortenReferencesProcessing =
|
||||
postProcessing { file, rangeMarker, _ ->
|
||||
val filter = filter@{ element: PsiElement ->
|
||||
if (element !is KtQualifiedExpression) return@filter ShortenReferences.FilterResult.PROCESS
|
||||
val fqName = element.selectorExpression?.mainReference?.resolve()?.getKotlinFqName()
|
||||
?: return@filter ShortenReferences.FilterResult.PROCESS
|
||||
if (ImportStorage.isImportNeeded(fqName)) ShortenReferences.FilterResult.PROCESS
|
||||
else ShortenReferences.FilterResult.SKIP
|
||||
}
|
||||
if (rangeMarker != null) {
|
||||
if (rangeMarker.isValid) {
|
||||
ShortenReferences.DEFAULT.process(file, rangeMarker.startOffset, rangeMarker.endOffset)
|
||||
ShortenReferences.DEFAULT.process(file, rangeMarker.startOffset, rangeMarker.endOffset, filter)
|
||||
}
|
||||
} else {
|
||||
ShortenReferences.DEFAULT.process(file)
|
||||
ShortenReferences.DEFAULT.process(file, filter)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -73,7 +73,6 @@ object ConversionsRunner {
|
||||
|
||||
//Kotlin --> Kotlin conversions
|
||||
+InnerClassConversion()
|
||||
+FilterImportsConversion()
|
||||
+StaticsToCompanionExtractConversion()
|
||||
+InterfaceWithFieldConversion()
|
||||
+ClassToObjectPromotionConversion(context)
|
||||
@@ -84,6 +83,7 @@ object ConversionsRunner {
|
||||
+LiteralConversion()
|
||||
|
||||
+CollectImportsConversion(context)
|
||||
+FilterImportsConversion()
|
||||
+MoveInitBlocksToTheEndConversion()
|
||||
+AddElementsInfoConversion(context)
|
||||
}
|
||||
|
||||
@@ -5,6 +5,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.nj2k
|
||||
|
||||
import com.intellij.psi.CommonClassNames
|
||||
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
|
||||
@@ -22,9 +23,18 @@ class ImportStorage {
|
||||
companion object {
|
||||
fun isImportNeeded(fqName: FqName): Boolean {
|
||||
if (fqName in NULLABILITY_ANNOTATIONS) return false
|
||||
if (fqName in JAVA_TYPE_WRAPPERS_WHICH_HAVE_CONFLICTS_WITH_KOTLIN_ONES) return false
|
||||
return true
|
||||
}
|
||||
|
||||
private val JAVA_TYPE_WRAPPERS_WHICH_HAVE_CONFLICTS_WITH_KOTLIN_ONES = setOf(
|
||||
FqName(CommonClassNames.JAVA_LANG_BYTE),
|
||||
FqName(CommonClassNames.JAVA_LANG_SHORT),
|
||||
FqName(CommonClassNames.JAVA_LANG_LONG),
|
||||
FqName(CommonClassNames.JAVA_LANG_FLOAT),
|
||||
FqName(CommonClassNames.JAVA_LANG_DOUBLE)
|
||||
)
|
||||
|
||||
fun isImportNeeded(fqName: String): Boolean = isImportNeeded(FqName(fqName))
|
||||
}
|
||||
}
|
||||
@@ -12,12 +12,9 @@ import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
|
||||
|
||||
class FilterImportsConversion : RecursiveApplicableConversionBase() {
|
||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||
if (element is JKImportList) {
|
||||
for (import in element.imports) {
|
||||
if (!ImportStorage.isImportNeeded(import.name.value)) {
|
||||
element.imports -= import
|
||||
}
|
||||
}
|
||||
if (element !is JKImportList) return recurse(element)
|
||||
element.imports = element.imports.filter { import ->
|
||||
ImportStorage.isImportNeeded(import.name.value)
|
||||
}
|
||||
return recurse(element)
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
// RUNTIME_WITH_FULL_JDK
|
||||
|
||||
public class Test {
|
||||
void m() {
|
||||
Double.isFinite(2.0);
|
||||
Double.isNaN(2.0);
|
||||
Float.isNaN(2.0f);
|
||||
Float.isInfinite(2.0f);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
// RUNTIME_WITH_FULL_JDK
|
||||
|
||||
class Test {
|
||||
internal fun m() {
|
||||
java.lang.Double.isFinite(2.0)
|
||||
java.lang.Double.isNaN(2.0)
|
||||
java.lang.Float.isNaN(2.0f)
|
||||
java.lang.Float.isInfinite(2.0f)
|
||||
}
|
||||
}
|
||||
+13
@@ -0,0 +1,13 @@
|
||||
// RUNTIME_WITH_FULL_JDK
|
||||
|
||||
import java.lang.Double
|
||||
import java.lang.Float
|
||||
|
||||
public class Test {
|
||||
void m() {
|
||||
Double.isFinite(2.0);
|
||||
Double.isNaN(2.0);
|
||||
Float.isNaN(2.0f);
|
||||
Float.isInfinite(2.0f);
|
||||
}
|
||||
}
|
||||
+8
@@ -0,0 +1,8 @@
|
||||
class Test {
|
||||
internal fun m() {
|
||||
java.lang.Double.isFinite(2.0)
|
||||
java.lang.Double.isNaN(2.0)
|
||||
java.lang.Float.isNaN(2.0f)
|
||||
java.lang.Float.isInfinite(2.0f)
|
||||
}
|
||||
}
|
||||
+10
@@ -3472,6 +3472,16 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
||||
runTest("nj2k/testData/newJ2k/methodCallExpression/collectionsMethods2.java");
|
||||
}
|
||||
|
||||
@TestMetadata("conflictJavaMethodCall.java")
|
||||
public void testConflictJavaMethodCall() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/methodCallExpression/conflictJavaMethodCall.java");
|
||||
}
|
||||
|
||||
@TestMetadata("conflictJavaMethodCallWithExplicitImports.java")
|
||||
public void testConflictJavaMethodCallWithExplicitImports() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/methodCallExpression/conflictJavaMethodCallWithExplicitImports.java");
|
||||
}
|
||||
|
||||
@TestMetadata("emptyCall.java")
|
||||
public void testEmptyCall() throws Exception {
|
||||
runTest("nj2k/testData/newJ2k/methodCallExpression/emptyCall.java");
|
||||
|
||||
Reference in New Issue
Block a user