Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[kotlin] K2 J2K: Move VarToValProcessing LocalVarToValInspectionBasedProcessing and fixValToVarDiagnosticBasedProcessing to JKTree #2726

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -122,19 +122,11 @@ private val inspectionLikePostProcessingGroup = InspectionLikeProcessingGroup(
private val cleaningUpDiagnosticBasedPostProcessingGroup = DiagnosticBasedPostProcessingGroup(
removeUselessCastDiagnosticBasedProcessing,
removeUnnecessaryNotNullAssertionDiagnosticBasedProcessing,
fixValToVarDiagnosticBasedProcessing
)

private val inferringTypesPostProcessingGroup = NamedPostProcessingGroup(
KotlinNJ2KServicesBundle.message("processing.step.inferring.types"),
listOf(
InspectionLikeProcessingGroup(
processings = listOf(
VarToValProcessing(),
LocalVarToValInspectionBasedProcessing()
),
runSingleTime = true
),
NullabilityInferenceProcessing(),
MutabilityInferenceProcessing(),
ClearUnknownInferenceLabelsProcessing()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,6 @@ import org.jetbrains.kotlin.types.typeUtil.isSignedOrUnsignedNumberType
import org.jetbrains.kotlin.types.typeUtil.isSubtypeOf
import org.jetbrains.kotlin.types.typeUtil.makeNotNullable

internal val fixValToVarDiagnosticBasedProcessing =
diagnosticBasedProcessing(
Errors.VAL_REASSIGNMENT, Errors.CAPTURED_VAL_INITIALIZATION, Errors.CAPTURED_MEMBER_VAL_INITIALIZATION
) { element: KtExpression, _ ->
val property = element.unpackedReferenceToProperty() ?: return@diagnosticBasedProcessing
if (!property.isVar) {
property.valOrVarKeyword.replace(KtPsiFactory(element.project).createVarKeyword())
}
}

internal val fixTypeMismatchDiagnosticBasedProcessing =
diagnosticBasedProcessing(Errors.TYPE_MISMATCH) { element: PsiElement, diagnostic ->
@Suppress("UNCHECKED_CAST")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,5 +62,6 @@ fun getNewJ2KConversions(context: NewJ2kConverterContext): List<Conversion> = li
FunctionalInterfacesConversion(context),
FilterImportsConversion(context),
AddElementsInfoConversion(context),
EnumSyntheticValuesMethodConversion(context)
EnumSyntheticValuesMethodConversion(context),
InferMutabilityOfLocalVariablesConversion(context)
)
Original file line number Diff line number Diff line change
Expand Up @@ -4283,6 +4283,39 @@ public void testPackageWithStaticImports() throws Exception {
}
}

@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../shared/tests/testData/newJ2k/mutability")
public static class Mutability extends AbstractNewJavaToKotlinConverterSingleFileTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}

@TestMetadata("initStatementWithRunBlock.java")
public void testInitStatementWithRunBlock() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/initStatementWithRunBlock.java");
}

@TestMetadata("mutableParameters.java")
public void testMutableParameters() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/mutableParameters.java");
}

@TestMetadata("NestedIfStatements.java")
public void testNestedIfStatements() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/NestedIfStatements.java");
}

@TestMetadata("tryCatchVariable.java")
public void testTryCatchVariable() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/tryCatchVariable.java");
}

@TestMetadata("ValAssignedInIfStatement.java")
public void testValAssignedInIfStatement() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/ValAssignedInIfStatement.java");
}
}

@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../shared/tests/testData/newJ2k/mutableCollections")
public static class MutableCollections extends AbstractNewJavaToKotlinConverterSingleFileTest {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@ internal fun getK2J2KConversions(context: NewJ2kConverterContext): List<Conversi
RemoveRedundantQualifiersForCallsConversion(context),
FunctionalInterfacesConversion(context),
FilterImportsConversion(context),
EnumSyntheticValuesMethodConversion(context)
EnumSyntheticValuesMethodConversion(context),
InferMutabilityOfLocalVariablesConversion(context)
)
Original file line number Diff line number Diff line change
Expand Up @@ -4283,6 +4283,39 @@ public void testPackageWithStaticImports() throws Exception {
}
}

@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../shared/tests/testData/newJ2k/mutability")
public static class Mutability extends AbstractK2JavaToKotlinConverterSingleFileTest {
private void runTest(String testDataFilePath) throws Exception {
KotlinTestUtils.runTest(this::doTest, this, testDataFilePath);
}

@TestMetadata("initStatementWithRunBlock.java")
public void testInitStatementWithRunBlock() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/initStatementWithRunBlock.java");
}

@TestMetadata("mutableParameters.java")
public void testMutableParameters() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/mutableParameters.java");
}

@TestMetadata("NestedIfStatements.java")
public void testNestedIfStatements() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/NestedIfStatements.java");
}

@TestMetadata("tryCatchVariable.java")
public void testTryCatchVariable() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/tryCatchVariable.java");
}

@TestMetadata("ValAssignedInIfStatement.java")
public void testValAssignedInIfStatement() throws Exception {
runTest("../../shared/tests/testData/newJ2k/mutability/ValAssignedInIfStatement.java");
}
}

@RunWith(JUnit3RunnerWithInners.class)
@TestMetadata("../../shared/tests/testData/newJ2k/mutableCollections")
public static class MutableCollections extends AbstractK2JavaToKotlinConverterSingleFileTest {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,10 @@ import org.jetbrains.kotlin.nj2k.*
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKFieldDataFromJava
import org.jetbrains.kotlin.nj2k.externalCodeProcessing.JKPhysicalMethodData
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.Visibility.PRIVATE
import org.jetbrains.kotlin.nj2k.tree.Mutability.*
import org.jetbrains.kotlin.nj2k.tree.Modality.FINAL
import org.jetbrains.kotlin.nj2k.tree.Mutability.IMMUTABLE
import org.jetbrains.kotlin.nj2k.tree.Mutability.MUTABLE
import org.jetbrains.kotlin.nj2k.tree.OtherModifier.STATIC
import org.jetbrains.kotlin.nj2k.tree.Visibility.PRIVATE
import org.jetbrains.kotlin.nj2k.types.JKJavaArrayType
import org.jetbrains.kotlin.nj2k.types.arrayInnerType
import org.jetbrains.kotlin.nj2k.types.isStringType
Expand Down Expand Up @@ -83,7 +82,18 @@ class ClassMemberConversion(context: NewJ2kConverterContext) : RecursiveConversi
context(KtAnalysisSession)
private fun JKField.convert() {
removeStaticModifierFromAnonymousClassMember()
mutability = if (modality == FINAL) IMMUTABLE else MUTABLE
val hasMutableAnnotation = annotationList.annotations.any { MUTABLE_ANNOTATIONS.contains(it.classSymbol.fqName) }
val scope = when {
parentOfType<JKConstructor>() != null -> parentOfType<JKFile>()
parentOfType<JKClass>()?.visibility == PRIVATE && parentOfType<JKClass>()?.parentOfType<JKClass>() == null -> parentOfType<JKClass>()
else -> parentOfType<JKTreeRoot>() ?: parentOfType<JKFile>()
}
mutability = when {
modality == FINAL && initializer is JKStubExpression -> IMMUTABLE
hasMutableAnnotation -> MUTABLE
scope == null -> UNKNOWN
else -> inferMutabilityFromWritableUsages(scope, context)
}
modality = FINAL

if (isExternallyAccessible()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license.

package org.jetbrains.kotlin.nj2k.conversions

import org.jetbrains.kotlin.analysis.api.KtAnalysisSession
import org.jetbrains.kotlin.nj2k.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.Mutability.UNKNOWN

class InferMutabilityOfLocalVariablesConversion(context: NewJ2kConverterContext) : RecursiveConversion(context) {
context(KtAnalysisSession)
override fun applyToElement(element: JKTreeElement): JKTreeElement {
if (element !is JKLocalVariable || element.mutability != UNKNOWN) return recurse(element)
val scope = element.parentOfType<JKMethod>() ?: element.parentOfType<JKFile>() ?: element
element.mutability = element.inferMutabilityFromWritableUsages(scope, context)
return recurse(element)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.nj2k.symbols.JKMethodSymbol
import org.jetbrains.kotlin.nj2k.symbols.JKSymbol
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.Modality.FINAL
import org.jetbrains.kotlin.nj2k.tree.JKClass.ClassKind.INTERFACE
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType
import org.jetbrains.kotlin.nj2k.types.JKNoType
Expand Down Expand Up @@ -182,9 +183,6 @@ fun JKExpression.unboxFieldReference(): JKFieldAccessExpression? = when {
else -> null
}

fun JKFieldAccessExpression.asAssignmentFromTarget(): JKKtAssignmentStatement? =
parent.safeAs<JKKtAssignmentStatement>()?.takeIf { it.field == this }

fun JKFieldAccessExpression.isInDecrementOrIncrement(): Boolean =
when (parent.safeAs<JKUnaryExpression>()?.operator?.token) {
JKOperatorToken.PLUSPLUS, JKOperatorToken.MINUSMINUS -> true
Expand All @@ -195,13 +193,6 @@ context(KtAnalysisSession)
fun JKVariable.hasUsages(scope: JKTreeElement, context: NewJ2kConverterContext): Boolean =
findUsages(scope, context).isNotEmpty()

context(KtAnalysisSession)
fun JKVariable.hasWritableUsages(scope: JKTreeElement, context: NewJ2kConverterContext): Boolean =
findUsages(scope, context).any {
it.asAssignmentFromTarget() != null
|| it.isInDecrementOrIncrement()
}

fun equalsExpression(left: JKExpression, right: JKExpression, typeFactory: JKTypeFactory) =
JKBinaryExpression(
left,
Expand All @@ -222,7 +213,7 @@ fun createCompanion(declarations: List<JKDeclaration>): JKClass =
JKAnnotationList(),
emptyList(),
JKVisibilityModifierElement(Visibility.PUBLIC),
JKModalityModifierElement(Modality.FINAL)
JKModalityModifierElement(FINAL)
)

fun JKClass.getCompanion(): JKClass? =
Expand Down