New J2K: Remove redundant nullability AST conversions due to having them in nullability analyser
This commit is contained in:
committed by
Ilya Kirillov
parent
b24ce99097
commit
13a9a56e85
@@ -72,10 +72,7 @@ object ConversionsRunner {
|
|||||||
+BuiltinMembersConversion(context)
|
+BuiltinMembersConversion(context)
|
||||||
+EqualsOperatorConversion(context)
|
+EqualsOperatorConversion(context)
|
||||||
+TypeMappingConversion(context)
|
+TypeMappingConversion(context)
|
||||||
+LowerNullabilityInFunctionParametersConversion(context)
|
|
||||||
+ImplicitCastsConversion(context)
|
+ImplicitCastsConversion(context)
|
||||||
+DefaultNullabilityToNullableConversion()
|
|
||||||
+NullableQualifierConversion(context)
|
|
||||||
+InternalDeclarationConversion()
|
+InternalDeclarationConversion()
|
||||||
|
|
||||||
//Kotlin --> Kotlin conversions
|
//Kotlin --> Kotlin conversions
|
||||||
|
|||||||
-20
@@ -1,20 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKTypeElementImpl
|
|
||||||
|
|
||||||
class DefaultNullabilityToNullableConversion : RecursiveApplicableConversionBase() {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKTypeElementImpl) return recurse(element)
|
|
||||||
if (element.type.nullability != Nullability.Default) return recurse(element)
|
|
||||||
return recurse(
|
|
||||||
JKTypeElementImpl(element.type.updateNullability(Nullability.Nullable))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-85
@@ -1,85 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
|
||||||
import org.jetbrains.kotlin.nj2k.ConversionContext
|
|
||||||
import org.jetbrains.kotlin.nj2k.isEquals
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKFieldSymbol
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKKtSpreadOperator
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.JKTypeElementImpl
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.cast
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
|
||||||
|
|
||||||
class LowerNullabilityInFunctionParametersConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKMethod && element !is JKLambdaExpression) return recurse(element)
|
|
||||||
val (parameters, scopes) =
|
|
||||||
when (element) {
|
|
||||||
is JKMethod -> element.parameters to
|
|
||||||
listOfNotNull(
|
|
||||||
element.block,
|
|
||||||
(element as? JKKtConstructor)?.delegationCall
|
|
||||||
) + element.parameters.mapNotNull { if (it.initializer !is JKStubExpression) it.initializer else null }
|
|
||||||
is JKLambdaExpression -> element.parameters to listOf(element.statement)
|
|
||||||
else -> return recurse(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
for (parameter in parameters) {
|
|
||||||
if (parameter.type.type.nullability != Nullability.Default) continue
|
|
||||||
if (parameter.hasNotNullUsages(scopes)) {
|
|
||||||
parameter.type = JKTypeElementImpl(parameter.type.type.updateNullability(Nullability.NotNull))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKParameter.hasNotNullUsages(scopes: List<JKTreeElement>): Boolean =
|
|
||||||
scopes.any {
|
|
||||||
val searcher = HasNotNullUsagesSearcher(context.symbolProvider.provideUniverseSymbol(this))
|
|
||||||
scopes.any { searcher.runConversion(it, context) }
|
|
||||||
searcher.found
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class HasNotNullUsagesSearcher(private val parameterSymbol: JKFieldSymbol) : RecursiveApplicableConversionBase() {
|
|
||||||
var found: Boolean = false
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
when (element) {
|
|
||||||
is JKQualifiedExpression -> {
|
|
||||||
val receiver = element.receiver as? JKFieldAccessExpression ?: return recurse(element)
|
|
||||||
if (receiver.identifier == parameterSymbol) {
|
|
||||||
found = true
|
|
||||||
return element
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is JKPrefixExpression -> {
|
|
||||||
if (element.expression.safeAs<JKFieldAccessExpression>()?.identifier == parameterSymbol
|
|
||||||
&& element.operator is JKKtSpreadOperator
|
|
||||||
) {
|
|
||||||
found = true
|
|
||||||
return element
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is JKFieldAccessExpression -> {
|
|
||||||
if (element.identifier == parameterSymbol
|
|
||||||
&& element.parent is JKBinaryExpression
|
|
||||||
&& element.parent.cast<JKBinaryExpression>().let {
|
|
||||||
!it.operator.isEquals()
|
|
||||||
&& (it.left.type(context.symbolProvider)?.asPrimitiveType() != null
|
|
||||||
|| it.right.type(context.symbolProvider)?.asPrimitiveType() != null)
|
|
||||||
}
|
|
||||||
) {
|
|
||||||
found = true
|
|
||||||
return element
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,41 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.nj2k.conversions
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.nj2k.ConversionContext
|
|
||||||
import org.jetbrains.kotlin.j2k.ast.Nullability
|
|
||||||
import org.jetbrains.kotlin.nj2k.bangedBangedExpr
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.*
|
|
||||||
import org.jetbrains.kotlin.nj2k.tree.impl.*
|
|
||||||
|
|
||||||
class NullableQualifierConversion(private val context: ConversionContext) : RecursiveApplicableConversionBase() {
|
|
||||||
override fun applyToElement(element: JKTreeElement): JKTreeElement {
|
|
||||||
if (element !is JKQualifiedExpression) return recurse(element)
|
|
||||||
if (element.isSystemCall()) return recurse(element)// we don't want to have `System.err!!.println()` like expressions :)
|
|
||||||
if (element.receiver.type(context.symbolProvider)?.nullability in listOf(Nullability.Nullable, Nullability.Default)
|
|
||||||
&& element.operator == JKJavaQualifierImpl.DOT || element.operator == JKKtQualifierImpl.DOT
|
|
||||||
) {
|
|
||||||
return recurse(
|
|
||||||
JKQualifiedExpressionImpl(
|
|
||||||
element::receiver.detached().bangedBangedExpr(context.symbolProvider),
|
|
||||||
element.operator,
|
|
||||||
element::selector.detached()
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
return recurse(element)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKQualifiedExpression.isSystemCall(): Boolean {
|
|
||||||
val deepestQualifiedExpression = generateSequence(this) { expression ->
|
|
||||||
expression.receiver as? JKQualifiedExpression
|
|
||||||
}.last()
|
|
||||||
return (deepestQualifiedExpression.receiver as? JKClassAccessExpression)
|
|
||||||
?.identifier
|
|
||||||
?.fqName
|
|
||||||
?.startsWith("java.") == true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -38,7 +38,6 @@ class TypeMappingConversion(val context: ConversionContext) : RecursiveApplicabl
|
|||||||
val newType = element.type
|
val newType = element.type
|
||||||
.fixRawType(element)
|
.fixRawType(element)
|
||||||
.mapType(element)
|
.mapType(element)
|
||||||
.refineNullability(element)
|
|
||||||
JKTypeElementImpl(newType).withNonCodeElementsFrom(element)
|
JKTypeElementImpl(newType).withNonCodeElementsFrom(element)
|
||||||
}
|
}
|
||||||
is JKJavaNewExpression -> {
|
is JKJavaNewExpression -> {
|
||||||
@@ -79,15 +78,6 @@ class TypeMappingConversion(val context: ConversionContext) : RecursiveApplicabl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun JKType.refineNullability(typeElement: JKTypeElement): JKType {
|
|
||||||
if (nullability == Nullability.Default && this is JKClassType) {
|
|
||||||
val newNullability = calculateNullability(typeElement)
|
|
||||||
if (newNullability != nullability) {
|
|
||||||
return JKClassTypeImpl(classReference, parameters, newNullability)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun JKType.fixRawType(typeElement: JKTypeElement) =
|
private fun JKType.fixRawType(typeElement: JKTypeElement) =
|
||||||
when (typeElement.parent) {
|
when (typeElement.parent) {
|
||||||
@@ -158,28 +148,6 @@ class TypeMappingConversion(val context: ConversionContext) : RecursiveApplicabl
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun calculateNullability(typeElement: JKTypeElement?): Nullability {
|
|
||||||
val parent = typeElement?.parent ?: return Nullability.Default
|
|
||||||
val psi = parent.psi
|
|
||||||
return when (parent) {
|
|
||||||
is JKMethod ->
|
|
||||||
psi?.let { typeFlavorCalculator.methodNullability(it as PsiMethod) }
|
|
||||||
.nullToDefault()
|
|
||||||
|
|
||||||
is JKVariable -> psi?.let {
|
|
||||||
typeFlavorCalculator.variableNullability(psi as PsiVariable)
|
|
||||||
}.nullToDefault()
|
|
||||||
|
|
||||||
else -> Nullability.Default
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun Nullability.defaultToNull() =
|
|
||||||
if (this == Nullability.Default) null else this
|
|
||||||
|
|
||||||
private fun Nullability?.nullToDefault() =
|
|
||||||
this ?: Nullability.Default
|
|
||||||
|
|
||||||
private fun calculateStructureMutability(typeElement: JKTypeElement?): Boolean {
|
private fun calculateStructureMutability(typeElement: JKTypeElement?): Boolean {
|
||||||
val parent = typeElement?.parent ?: return false
|
val parent = typeElement?.parent ?: return false
|
||||||
val psi = parent.psi ?: return false
|
val psi = parent.psi ?: return false
|
||||||
|
|||||||
Reference in New Issue
Block a user