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()
|
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 documentManager = PsiDocumentManager.getInstance(file.project)
|
||||||
val document = file.viewProvider.document!!
|
val document = file.viewProvider.document!!
|
||||||
if (!documentManager.isCommitted(document)) {
|
if (!documentManager.isCommitted(document)) {
|
||||||
@@ -106,33 +107,36 @@ class ShortenReferences(val options: (KtElement) -> Options = { Options.DEFAULT
|
|||||||
val rangeMarker = document.createRangeMarker(startOffset, endOffset)
|
val rangeMarker = document.createRangeMarker(startOffset, endOffset)
|
||||||
rangeMarker.isGreedyToLeft = true
|
rangeMarker.isGreedyToLeft = true
|
||||||
rangeMarker.isGreedyToRight = 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 {
|
try {
|
||||||
process(listOf(file)) { element ->
|
process(listOf(file)) { element ->
|
||||||
if (rangeMarker.isValid) {
|
minOf(rangeFilter(element), additionalFilter(element))
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
rangeMarker.dispose()
|
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.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.core.util.range
|
import org.jetbrains.kotlin.idea.core.util.range
|
||||||
import org.jetbrains.kotlin.idea.formatter.commitAndUnblockDocument
|
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.asLabel
|
||||||
import org.jetbrains.kotlin.nj2k.inference.common.BoundTypeCalculatorImpl
|
import org.jetbrains.kotlin.nj2k.inference.common.BoundTypeCalculatorImpl
|
||||||
import org.jetbrains.kotlin.nj2k.inference.common.ByInfoSuperFunctionsProvider
|
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.nj2k.postProcessing.postProcessing
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
import org.jetbrains.kotlin.psi.psiUtil.elementsInRange
|
||||||
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
val formatCodeProcessing =
|
val formatCodeProcessing =
|
||||||
postProcessing { file, rangeMarker, _ ->
|
postProcessing { file, rangeMarker, _ ->
|
||||||
@@ -90,12 +94,19 @@ private fun KtFile.clearUndefinedLabels() {
|
|||||||
|
|
||||||
val shortenReferencesProcessing =
|
val shortenReferencesProcessing =
|
||||||
postProcessing { file, rangeMarker, _ ->
|
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 != null) {
|
||||||
if (rangeMarker.isValid) {
|
if (rangeMarker.isValid) {
|
||||||
ShortenReferences.DEFAULT.process(file, rangeMarker.startOffset, rangeMarker.endOffset)
|
ShortenReferences.DEFAULT.process(file, rangeMarker.startOffset, rangeMarker.endOffset, filter)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ShortenReferences.DEFAULT.process(file)
|
ShortenReferences.DEFAULT.process(file, filter)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -73,7 +73,6 @@ object ConversionsRunner {
|
|||||||
|
|
||||||
//Kotlin --> Kotlin conversions
|
//Kotlin --> Kotlin conversions
|
||||||
+InnerClassConversion()
|
+InnerClassConversion()
|
||||||
+FilterImportsConversion()
|
|
||||||
+StaticsToCompanionExtractConversion()
|
+StaticsToCompanionExtractConversion()
|
||||||
+InterfaceWithFieldConversion()
|
+InterfaceWithFieldConversion()
|
||||||
+ClassToObjectPromotionConversion(context)
|
+ClassToObjectPromotionConversion(context)
|
||||||
@@ -84,6 +83,7 @@ object ConversionsRunner {
|
|||||||
+LiteralConversion()
|
+LiteralConversion()
|
||||||
|
|
||||||
+CollectImportsConversion(context)
|
+CollectImportsConversion(context)
|
||||||
|
+FilterImportsConversion()
|
||||||
+MoveInitBlocksToTheEndConversion()
|
+MoveInitBlocksToTheEndConversion()
|
||||||
+AddElementsInfoConversion(context)
|
+AddElementsInfoConversion(context)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
|
import com.intellij.psi.CommonClassNames
|
||||||
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
|
import org.jetbrains.kotlin.load.java.NULLABILITY_ANNOTATIONS
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
|
|
||||||
@@ -22,9 +23,18 @@ class ImportStorage {
|
|||||||
companion object {
|
companion object {
|
||||||
fun isImportNeeded(fqName: FqName): Boolean {
|
fun isImportNeeded(fqName: FqName): Boolean {
|
||||||
if (fqName in NULLABILITY_ANNOTATIONS) return false
|
if (fqName in NULLABILITY_ANNOTATIONS) return false
|
||||||
|
if (fqName in JAVA_TYPE_WRAPPERS_WHICH_HAVE_CONFLICTS_WITH_KOTLIN_ONES) return false
|
||||||
return true
|
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))
|
fun isImportNeeded(fqName: String): Boolean = isImportNeeded(FqName(fqName))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -12,12 +12,9 @@ import org.jetbrains.kotlin.nj2k.tree.JKTreeElement
|
|||||||
|
|
||||||
class FilterImportsConversion : RecursiveApplicableConversionBase() {
|
class FilterImportsConversion : RecursiveApplicableConversionBase() {
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
||||||
if (element is JKImportList) {
|
if (element !is JKImportList) return recurse(element)
|
||||||
for (import in element.imports) {
|
element.imports = element.imports.filter { import ->
|
||||||
if (!ImportStorage.isImportNeeded(import.name.value)) {
|
ImportStorage.isImportNeeded(import.name.value)
|
||||||
element.imports -= import
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return recurse(element)
|
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");
|
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")
|
@TestMetadata("emptyCall.java")
|
||||||
public void testEmptyCall() throws Exception {
|
public void testEmptyCall() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/methodCallExpression/emptyCall.java");
|
runTest("nj2k/testData/newJ2k/methodCallExpression/emptyCall.java");
|
||||||
|
|||||||
Reference in New Issue
Block a user