From 95512147c509d6c379db0fa9ab3c2c2f065305eb Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 26 Apr 2025 12:04:29 +0200 Subject: [PATCH 01/17] upgrade Kotlin to 2.1.20 --- rewrite-kotlin/build.gradle.kts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rewrite-kotlin/build.gradle.kts b/rewrite-kotlin/build.gradle.kts index d2a112aa76..0342394843 100644 --- a/rewrite-kotlin/build.gradle.kts +++ b/rewrite-kotlin/build.gradle.kts @@ -2,10 +2,10 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { id("org.openrewrite.build.language-library") - kotlin("jvm") version "1.9.25" + kotlin("jvm") version "2.1.20" } -val kotlinVersion = "1.9.25" +val kotlinVersion = "2.1.20" dependencies { compileOnly(project(":rewrite-core")) From 1f9ef6616a6b4ba2faef0565227aa61d6fda877b Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 26 Apr 2025 12:04:44 +0200 Subject: [PATCH 02/17] remove generics from IrConst usage --- .../main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt | 4 ++-- .../org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt | 4 ++-- .../openrewrite/kotlin/internal/PsiElementIrAssociations.kt | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt index a9f2f4d586..ce73928a31 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt @@ -95,7 +95,7 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin return type(baseType.type) } - is IrConst<*> -> { + is IrConst -> { return primitive(baseType) } @@ -536,7 +536,7 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin fun primitive(type: Any?): JavaType.Primitive { return when (type) { - is IrConst<*> -> { + is IrConst -> { when (type.kind) { IrConstKind.Int -> JavaType.Primitive.Int IrConstKind.Boolean -> JavaType.Primitive.Boolean diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt index 60ec2b21ce..d432c90e23 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt @@ -63,7 +63,7 @@ class KotlinTypeIrSignatureBuilder : JavaTypeSignatureBuilder { return signature(baseType.type) } - is IrConst<*> -> { + is IrConst -> { return primitiveSignature(baseType) } @@ -265,7 +265,7 @@ class KotlinTypeIrSignatureBuilder : JavaTypeSignatureBuilder { override fun primitiveSignature(type: Any): String { return when (type) { - is IrConst<*> -> type.type.classFqName!!.asString() + is IrConst -> type.type.classFqName!!.asString() else -> { throw UnsupportedOperationException("Unsupported primitive type" + type.javaClass) } diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt index 9275293db7..32bbf92f29 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt @@ -147,7 +147,7 @@ class PsiElementIrAssociations(private val typeMapping: KotlinIrTypeMapping, pri } is KtConstantExpression, is KtStringTemplateExpression -> { - { it is IrConst<*> } + { it is IrConst } } is KtClassLiteralExpression -> { From d6b3304c84712554b58515a417f82dd6056a871e Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 26 Apr 2025 12:56:55 +0200 Subject: [PATCH 03/17] fix type.toRegularClassSymbol(firSession) --- .../main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt index bc38a7b188..28fed548df 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol import org.jetbrains.kotlin.fir.resolve.providers.toSymbol import org.jetbrains.kotlin.fir.resolve.toFirRegularClass +import org.jetbrains.kotlin.fir.resolve.toRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* @@ -312,7 +313,7 @@ class KotlinTypeMapping( val firClass = when (type) { is FirClass -> type is FirResolvedQualifier -> { - val ref = type.typeRef.toRegularClassSymbol(firSession) + val ref = type.resolvedType.toRegularClassSymbol(firSession) if (type.typeArguments.isNotEmpty()) { params = type.typeArguments } @@ -1233,7 +1234,7 @@ class KotlinTypeMapping( private fun listAnnotations(firAnnotations: List): MutableList? { var annotations: MutableList? = null for (firAnnotation in firAnnotations) { - val fir = firAnnotation.typeRef.toRegularClassSymbol(firSession)?.fir + val fir = firAnnotation.resolvedType.toRegularClassSymbol(firSession)?.fir if (fir != null && isNotSourceRetention(fir.annotations)) { if (annotations == null) { annotations = ArrayList() From 378374d09791baee5f8bed47b89de6ce14c63a39 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 10 May 2025 16:19:35 +0200 Subject: [PATCH 04/17] Replaced outdated Kotlin FIR API calls and updated type references to align with the latest API changes. Removed deprecated methods, modified method calls, and streamlined type resolution to improve code clarity and maintain compatibility with updated Kotlin FIR. --- .../org/openrewrite/kotlin/KotlinParser.java | 46 +++++++++++------- .../kotlin/internal/PsiTreePrinter.java | 11 ++--- .../openrewrite/kotlin/KotlinTypeMapping.kt | 48 +++++++++---------- .../kotlin/KotlinTypeSignatureBuilder.kt | 39 +++++++-------- .../kotlin/internal/PsiElementAssociations.kt | 20 ++++---- .../internal/PsiElementIrAssociations.kt | 2 +- 6 files changed, 89 insertions(+), 77 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java index 735f157bbf..da3563388c 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java @@ -51,17 +51,15 @@ import org.jetbrains.kotlin.fir.pipeline.AnalyseKt; import org.jetbrains.kotlin.fir.pipeline.FirUtilsKt; import org.jetbrains.kotlin.fir.resolve.ScopeSession; +import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory; import org.jetbrains.kotlin.fir.session.FirSessionConfigurator; -import org.jetbrains.kotlin.fir.session.FirSessionFactoryHelper; import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope; import org.jetbrains.kotlin.idea.KotlinFileType; import org.jetbrains.kotlin.idea.KotlinLanguage; import org.jetbrains.kotlin.load.kotlin.PackagePartProvider; import org.jetbrains.kotlin.modules.Module; import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms; import org.jetbrains.kotlin.psi.KtFile; -import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformAnalyzerServices; import org.jetbrains.kotlin.utils.PathUtil; import org.jspecify.annotations.Nullable; import org.openrewrite.*; @@ -445,7 +443,7 @@ public CompiledSource parse(List sources, Disposable disposable, E VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), providerFunction1); - AbstractProjectFileSearchScope sourceScope = projectEnvironment.getSearchScopeByPsiFiles(ktFiles, false); + AbstractProjectFileSearchScope sourceScope = projectEnvironment.getSearchScopeByPsiFiles(ktFiles); sourceScope.plus(projectEnvironment.getSearchScopeForProjectJavaSources()); AbstractProjectFileSearchScope libraryScope = projectEnvironment.getSearchScopeForProjectLibraries(); @@ -472,25 +470,39 @@ public CompiledSource parse(List sources, Disposable disposable, E Function1 sessionConfigurator = session -> Unit.INSTANCE; - FirSession firSession = FirSessionFactoryHelper.INSTANCE.createSessionWithDependencies( + FirSession firSession = FirJvmSessionFactory.INSTANCE.createLibrarySession( Name.identifier(module.getModuleName()), - JvmPlatforms.INSTANCE.getUnspecifiedJvmPlatform(), - JvmPlatformAnalyzerServices.INSTANCE, sessionProvider, + null, projectEnvironment, + null, + sourceScope.plus(libraryScope), + null, languageVersionSettings, - sourceScope, - libraryScope, - compilerConfiguration.get(LOOKUP_TRACKER), - compilerConfiguration.get(ENUM_WHEN_TRACKER), - compilerConfiguration.get(IMPORT_TRACKER), - null, // Do not incrementally compile - emptyList(), // Add extension registrars when needed here. - true, - dependencyListBuilderProvider, - sessionConfigurator + null ); + //TODO build session with dependencies + +// FirSession firSession = FirSessionFactoryHelper.INSTANCE.createSessionWithDependencies( +// Name.identifier(module.getModuleName()), +// JvmPlatforms.INSTANCE.getUnspecifiedJvmPlatform(), +// JvmPlatformAnalyzerServices.INSTANCE, +// sessionProvider, +// projectEnvironment, +// languageVersionSettings, +// sourceScope, +// libraryScope, +// compilerConfiguration.get(LOOKUP_TRACKER), +// compilerConfiguration.get(ENUM_WHEN_TRACKER), +// compilerConfiguration.get(IMPORT_TRACKER), +// null, // Do not incrementally compile +// emptyList(), // Add extension registrars when needed here. +// true, +// dependencyListBuilderProvider, +// sessionConfigurator +// ); + List rawFir = FirUtilsKt.buildFirFromKtFiles(firSession, ktFiles); Pair> result = AnalyseKt.runResolution(firSession, rawFir); assert kotlinSources.size() == result.getSecond().size(); diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/PsiTreePrinter.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/PsiTreePrinter.java index fce9c49394..f8fa67afda 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/PsiTreePrinter.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/PsiTreePrinter.java @@ -17,7 +17,7 @@ import lombok.AllArgsConstructor; import lombok.Data; -import org.jetbrains.kotlin.KtFakeSourceElement; +import org.jetbrains.kotlin.KtFakePsiSourceElement; import org.jetbrains.kotlin.KtRealPsiSourceElement; import org.jetbrains.kotlin.KtSourceElement; import org.jetbrains.kotlin.com.intellij.openapi.util.TextRange; @@ -29,7 +29,6 @@ import org.jetbrains.kotlin.fir.declarations.FirProperty; import org.jetbrains.kotlin.fir.expressions.*; import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference; -import org.jetbrains.kotlin.fir.symbols.ConeClassLikeLookupTag; import org.jetbrains.kotlin.fir.types.*; import org.jetbrains.kotlin.fir.visitors.FirDefaultVisitor; import org.jetbrains.kotlin.ir.IrElement; @@ -486,7 +485,7 @@ public static String printFirElement(FirElement firElement) { if (source instanceof KtRealPsiSourceElement) { sb.append("Real "); - } else if (source instanceof KtFakeSourceElement) { + } else if (source instanceof KtFakePsiSourceElement) { sb.append("Fake "); } else { sb.append(source.getClass().getSimpleName()); @@ -545,7 +544,7 @@ private static String printConeKotlinType(ConeTypeProjection coneKotlinType) { return ((FirProperty) firElement).getName().toString(); } else if (firElement instanceof FirResolvedTypeRef) { FirResolvedTypeRef resolvedTypeRef = (FirResolvedTypeRef) firElement; - ConeKotlinType coneKotlinType = resolvedTypeRef.getType(); + ConeKotlinType coneKotlinType = resolvedTypeRef.getConeType(); return printConeKotlinType(coneKotlinType); } else if (firElement instanceof FirResolvedNamedReference) { return ((FirResolvedNamedReference) firElement).getName().toString(); @@ -575,8 +574,8 @@ private static String printConeKotlinType(ConeTypeProjection coneKotlinType) { } return sb.toString(); } - } else if (firElement instanceof FirConstExpression) { - Object value = ((FirConstExpression) firElement).getValue(); + } else if (firElement instanceof FirLiteralExpression) { + Object value = ((FirLiteralExpression) firElement).getValue(); return value != null ? value.toString() : null; // return ((FirConstExpression) firElement).getKind().toString(); } else if (firElement instanceof FirWhenBranch) { diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt index 28fed548df..b19203d8a4 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt @@ -39,8 +39,6 @@ import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol -import org.jetbrains.kotlin.fir.resolve.providers.toSymbol -import org.jetbrains.kotlin.fir.resolve.toFirRegularClass import org.jetbrains.kotlin.fir.resolve.toRegularClassSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals @@ -76,7 +74,7 @@ class KotlinTypeMapping( private val signatureBuilder: KotlinTypeSignatureBuilder = KotlinTypeSignatureBuilder(firSession, firFile) override fun type(type: Any?): JavaType { - if (type == null || type is FirErrorTypeRef || type is FirExpression && type.typeRef is FirErrorTypeRef || type is FirResolvedQualifier && type.classId == null) { + if (type == null || type is FirErrorTypeRef || type is FirExpression && type.resolvedType is FirErrorTypeRef || type is FirResolvedQualifier && type.classId == null) { return Unknown.getInstance() } @@ -90,7 +88,7 @@ class KotlinTypeMapping( } fun type(type: Any?, parent: Any?): JavaType? { - if (type == null || type is FirErrorTypeRef || type is FirExpression && type.typeRef is FirErrorTypeRef || type is FirResolvedQualifier && type.classId == null) { + if (type == null || type is FirErrorTypeRef || type is FirExpression && type.resolvedType is FirErrorTypeRef || type is FirResolvedQualifier && type.classId == null) { return Unknown.getInstance() } val signature = signatureBuilder.signature(type, parent) @@ -202,11 +200,11 @@ class KotlinTypeMapping( } is FirVariableAssignment -> { - type(type.lValue.typeRef, parent, signature) + type(type.lValue.resolvedType, parent, signature) } is FirExpression -> { - type(type.typeRef, parent, signature) + type(type.resolvedType, parent, signature) } is JavaElement -> { @@ -327,7 +325,7 @@ class KotlinTypeMapping( is ConeClassLikeType -> { if (type.toSymbol(firSession) is FirTypeAliasSymbol) { return classType( - (type.toSymbol(firSession) as FirTypeAliasSymbol).resolvedExpandedTypeRef.type, + (type.toSymbol(firSession) as FirTypeAliasSymbol).resolvedExpandedTypeRef.coneType, parent, signature ) @@ -500,7 +498,7 @@ class KotlinTypeMapping( @OptIn(SymbolInternals::class) fun methodDeclarationType(enumEntry: FirEnumEntry): Method? { - val type = when (val fir = enumEntry.symbol.getContainingClassSymbol(firSession)?.fir) { + val type = when (val fir = enumEntry.symbol.getContainingClassSymbol()?.fir) { is FirClass -> { when (val primary = fir.declarations.firstOrNull { it is FirPrimaryConstructor }) { is FirPrimaryConstructor -> type(primary as FirFunction) @@ -550,8 +548,8 @@ class KotlinTypeMapping( var parentType = when { function.symbol is FirConstructorSymbol -> type(function.returnTypeRef) function.dispatchReceiverType != null -> type(function.dispatchReceiverType!!) - function.symbol.getOwnerLookupTag()?.toFirRegularClass(firSession) != null -> { - type(function.symbol.getOwnerLookupTag()!!.toFirRegularClass(firSession)!!) + function.symbol.getOwnerLookupTag()?.toRegularClassSymbol(firSession) != null -> { + type(function.symbol.getOwnerLookupTag()!!.toRegularClassSymbol(firSession)!!) } parent is FirRegularClass || parent != null -> type(parent) @@ -673,7 +671,8 @@ class KotlinTypeMapping( } fun methodInvocationType(fir: FirFunctionCall): Method? { - if (fir.typeRef is FirErrorTypeRef) { + //TODO is this correct? + if (!fir.isResolved) { return null } val signature = signatureBuilder.methodCallSignature(fir) @@ -743,11 +742,11 @@ class KotlinTypeMapping( if (resolvedSymbol.dispatchReceiverType is ConeClassLikeType) { declaringType = TypeUtils.asFullyQualified(type(resolvedSymbol.dispatchReceiverType)) } else if (resolvedSymbol.containingClassLookupTag() != null && - resolvedSymbol.containingClassLookupTag()!!.toFirRegularClass(firSession) != null + resolvedSymbol.containingClassLookupTag()!!.toRegularClassSymbol(firSession) != null ) { declaringType = TypeUtils.asFullyQualified( type( - resolvedSymbol.containingClassLookupTag()!!.toFirRegularClass(firSession) + resolvedSymbol.containingClassLookupTag()!!.toRegularClassSymbol(firSession) ) ) } else if (resolvedSymbol.origin == FirDeclarationOrigin.Library) { @@ -767,19 +766,19 @@ class KotlinTypeMapping( declaringType = createShallowClass("kotlin.Library") } } else if (resolvedSymbol.origin == FirDeclarationOrigin.SamConstructor) { - declaringType = when(val type = type(function.typeRef)) { + declaringType = when(val type = type(function.resolvedType)) { is Class -> type is Parameterized -> type.type else -> Unknown.getInstance() } } } else { - declaringType = TypeUtils.asFullyQualified(type(function.typeRef)) + declaringType = TypeUtils.asFullyQualified(type(function.resolvedType)) } if (declaringType == null) { declaringType = TypeUtils.asFullyQualified(type(firFile)) } - val returnType = type(function.typeRef) + val returnType = type(function.resolvedType) if (function.toResolvedCallableSymbol()?.receiverParameter != null) { paramTypes!!.add(type(function.toResolvedCallableSymbol()?.receiverParameter!!.typeRef)) @@ -806,12 +805,12 @@ class KotlinTypeMapping( if (t is GenericTypeVariable) { if (mapNames && args != null) { if (args.containsKey(p.name.asString())) { - paramTypes.add(type(args[p.name.asString()]!!.typeRef, function)!!) + paramTypes.add(type(args[p.name.asString()]!!.resolvedType, function)!!) } else { paramTypes.add(t) } } else if (index < valueParams.size) { - paramTypes.add(type(function.arguments[index].typeRef, function)!!) + paramTypes.add(type(function.arguments[index].resolvedType, function)!!) } } else { paramTypes.add(t) @@ -897,9 +896,9 @@ class KotlinTypeMapping( declaringType = type(variable.symbol.dispatchReceiverType) } - variable.symbol.getContainingClassSymbol(firSession) != null -> { - if (variable.symbol.getContainingClassSymbol(firSession) !is FirAnonymousObjectSymbol) { - declaringType = type(variable.symbol.getContainingClassSymbol(firSession)!!.fir) + variable.symbol.getContainingClassSymbol() != null -> { + if (variable.symbol.getContainingClassSymbol() !is FirAnonymousObjectSymbol) { + declaringType = type(variable.symbol.getContainingClassSymbol()!!.fir) } } @@ -1268,9 +1267,10 @@ class KotlinTypeMapping( private fun isNotSourceRetention(annotations: List): Boolean { for (ann in annotations) { - if ("kotlin.annotation.Retention" == convertClassIdToFqn(ann.typeRef.coneType.classId)) { + if ("kotlin.annotation.Retention" == convertClassIdToFqn(ann.resolvedType.classId)) { for (v in ann.argumentMapping.mapping.values) { - if (v.calleeReference is FirResolvedNamedReference && (v.calleeReference as FirResolvedNamedReference).name.asString() == "SOURCE") { + val reference = v.toReference(firSession) + if (reference is FirResolvedNamedReference && reference.name.asString() == "SOURCE") { return false } } @@ -1346,7 +1346,7 @@ class KotlinTypeMapping( fun primitive(type: FirElement): Primitive { return when (type) { - is FirConstExpression<*> -> { + is FirLiteralExpression -> { when (type.kind) { ConstantValueKind.Boolean -> Primitive.Boolean ConstantValueKind.Byte, ConstantValueKind.UnsignedByte -> Primitive.Byte diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt index 30da757c78..a8de70d88b 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt @@ -26,8 +26,8 @@ import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.toResolvedBaseSymbol import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol import org.jetbrains.kotlin.fir.resolve.inference.ConeTypeParameterBasedTypeVariable -import org.jetbrains.kotlin.fir.resolve.providers.toSymbol -import org.jetbrains.kotlin.fir.resolve.toFirRegularClass +import org.jetbrains.kotlin.fir.resolve.toRegularClassSymbol +import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* @@ -67,9 +67,10 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val signature(type.lowerBound) } - is ConeStubTypeForChainInference -> { - signature(type.constructor.variable) - } + //TODO handle this case +// is ConeStubTypeForChainInference -> { +// signature(type.constructor.variable) +// } is ConeTypeProjection -> { coneTypeProjectionSignature(type) @@ -144,7 +145,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val } is FirStringConcatenationCall -> { - signature(type.typeRef) + signature(type.resolvedType) } is FirSuperReference -> { @@ -168,11 +169,11 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val } is FirVariableAssignment -> { - signature(type.lValue.typeRef, parent) + signature(type.lValue.resolvedType, parent) } is FirExpression -> { - signature(type.typeRef) + signature(type.resolvedType) } is JavaElement -> { @@ -216,10 +217,10 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val return when (type) { is ConeClassLikeType -> convertClassIdToFqn(type.classId) is ConeFlexibleType -> convertClassIdToFqn(type.lowerBound.classId) - is ConeTypeParameterType -> signature(type.type) + is ConeTypeParameterType -> signature(type) is FirClass -> convertClassIdToFqn(type.classId) is FirFile -> fileSignature(type) - is FirResolvedTypeRef -> classSignature(type.type) + is FirResolvedTypeRef -> classSignature(type.coneType) is FirResolvedQualifier -> convertClassIdToFqn(type.classId) else -> { throw UnsupportedOperationException("Unsupported class type: ${type.javaClass.name}") @@ -323,8 +324,8 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val function.symbol is FirConstructorSymbol -> classSignature(function.returnTypeRef) function.dispatchReceiverType != null -> classSignature(function.dispatchReceiverType!!) function.symbol.getOwnerLookupTag() != null && function.symbol.getOwnerLookupTag()!! - .toFirRegularClass(firSession) != null -> { - classSignature(function.symbol.getOwnerLookupTag()!!.toFirRegularClass(firSession)!!) + .toRegularClassSymbol(firSession) != null -> { + classSignature(function.symbol.getOwnerLookupTag()!!.toRegularClassSymbol(firSession)!!) } parent is FirClass -> classSignature(parent) @@ -362,9 +363,9 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val if (resolvedSymbol.dispatchReceiverType is ConeClassLikeType) { declaringSig = signature(resolvedSymbol.dispatchReceiverType) } else if (resolvedSymbol.containingClassLookupTag() != null && - resolvedSymbol.containingClassLookupTag()!!.toFirRegularClass(firSession) != null + resolvedSymbol.containingClassLookupTag()!!.toRegularClassSymbol(firSession) != null ) { - declaringSig = signature(resolvedSymbol.containingClassLookupTag()!!.toFirRegularClass(firSession)) + declaringSig = signature(resolvedSymbol.containingClassLookupTag()!!.toRegularClassSymbol(firSession)) } else if (resolvedSymbol.origin == FirDeclarationOrigin.Library) { if (resolvedSymbol.fir.containerSource is JvmPackagePartSource) { val source: JvmPackagePartSource? = resolvedSymbol.fir.containerSource as JvmPackagePartSource? @@ -383,7 +384,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val } } } else if (sym is FirFunctionSymbol<*>) { - declaringSig = signature(function.typeRef) + declaringSig = signature(function.resolvedType) } if (declaringSig == null) { declaringSig = signature(firFile) @@ -392,10 +393,10 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val val sig = StringBuilder(declaringSig) when { sym is FirConstructorSymbol || - sym is FirSyntheticFunctionSymbol && sym.origin == FirDeclarationOrigin.SamConstructor -> sig.append("{name=,return=${signature(function.typeRef)}") + sym is FirSyntheticFunctionSymbol && sym.origin == FirDeclarationOrigin.SamConstructor -> sig.append("{name=,return=${signature(function.resolvedType)}") sym is FirNamedFunctionSymbol -> { sig.append("{name=${sym.name.asString()}") - sig.append(",return=${signature(function.typeRef)}") + sig.append(",return=${signature(function.resolvedType)}") } else -> throw UnsupportedOperationException("Unsupported function calleeReference: ${function.calleeReference.name}") @@ -429,9 +430,9 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val val sig = signature(p.returnTypeRef, function) if (sig.startsWith("Generic{")) { if (mapNames && args != null && args.containsKey(p.name.asString())) { - genericArgumentTypes.add(signature(args[p.name.asString()]!!.typeRef, function)) + genericArgumentTypes.add(signature(args[p.name.asString()]!!.resolvedType, function)) } else if (index < function.arguments.size) { - genericArgumentTypes.add(signature((function.arguments[index]).typeRef, function)) + genericArgumentTypes.add(signature((function.arguments[index]).resolvedType, function)) } } else { genericArgumentTypes.add(sig) diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt index e413cd1988..8866610532 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt @@ -32,7 +32,7 @@ import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.resolved import org.jetbrains.kotlin.fir.resolve.calls.FirSyntheticFunctionSymbol -import org.jetbrains.kotlin.fir.resolve.providers.toSymbol +import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.symbols.SymbolInternals import org.jetbrains.kotlin.fir.symbols.impl.* import org.jetbrains.kotlin.fir.types.* @@ -76,12 +76,12 @@ class PsiElementAssociations(val typeMapping: KotlinTypeMapping, val file: FirFi ) { super.visitResolvedTypeRef(resolvedTypeRef, data) if (resolvedTypeRef.psi is KtTypeReference) { - if (resolvedTypeRef.type is ConeClassLikeType) { - if (resolvedTypeRef.type.typeArguments.isNotEmpty() && resolvedTypeRef.psi is KtTypeReference) { - visitType(resolvedTypeRef.type, resolvedTypeRef.psi as KtTypeReference, data) + if (resolvedTypeRef.coneType is ConeClassLikeType) { + if (resolvedTypeRef.coneType.typeArguments.isNotEmpty() && resolvedTypeRef.psi is KtTypeReference) { + visitType(resolvedTypeRef.coneType, resolvedTypeRef.psi as KtTypeReference, data) } - } else if (resolvedTypeRef.type is ConeTypeParameterType) { - visitType(resolvedTypeRef.type, resolvedTypeRef.psi as KtTypeReference, data) + } else if (resolvedTypeRef.coneType is ConeTypeParameterType) { + visitType(resolvedTypeRef.coneType, resolvedTypeRef.psi as KtTypeReference, data) } } } @@ -252,7 +252,7 @@ class PsiElementAssociations(val typeMapping: KotlinTypeMapping, val file: FirFi fun primitiveType(psi: PsiElement): JavaType.Primitive { return when (val fir = primary(psi)) { - is FirConstExpression<*> -> { + is FirLiteralExpression -> { typeMapping.primitive(fir) } else -> JavaType.Primitive.None @@ -293,10 +293,10 @@ class PsiElementAssociations(val typeMapping: KotlinTypeMapping, val file: FirFi else -> { return when (p) { is KtConstantExpression -> { - directFirInfos.firstOrNull { it.fir is FirConstExpression<*> }?.fir + directFirInfos.firstOrNull { it.fir is FirLiteralExpression }?.fir } is KtImportDirective -> { - directFirInfos.firstOrNull { it.fir is FirImport && it.fir !is FirErrorImport }?.fir + directFirInfos.firstOrNull { it.fir is FirImport }?.fir //TODO what is equivalent of && it.fir !is FirErrorImport } is KtNamedFunction -> { val found = directFirInfos.firstOrNull { it.fir is FirFunction }?.fir @@ -369,7 +369,7 @@ class PsiElementAssociations(val typeMapping: KotlinTypeMapping, val file: FirFi } is FirSafeCallExpression -> { return when (fir.selector) { - is FirFunctionCall -> when (fir.selector.calleeReference?.resolved?.resolvedSymbol) { + is FirFunctionCall -> when ((fir.selector as FirFunctionCall).calleeReference.resolved?.resolvedSymbol) { is FirConstructorSymbol -> ExpressionType.CONSTRUCTOR is FirNamedFunctionSymbol -> ExpressionType.METHOD_INVOCATION else -> null diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt index 32bbf92f29..9021baf534 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt @@ -54,7 +54,7 @@ class PsiElementIrAssociations(private val typeMapping: KotlinIrTypeMapping, pri if (element.metadata is FirMetadataSource) { when (element.metadata) { is FirMetadataSource.File -> { - val source = (element.metadata!! as FirMetadataSource.File).files[0].source + val source = (element.metadata!! as FirMetadataSource.File).source if (source is KtRealPsiSourceElement) { elementMap.computeIfAbsent(source.psi) { ArrayList() } += IrInfo(element, depth) } From b0226fe69db8b2e34c59ec85dc455bf7f5cc3ea1 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sun, 1 Jun 2025 14:25:12 +0200 Subject: [PATCH 05/17] Updated KotlinParser to utilize the latest Kotlin FIR APIs, added support for Kotlin 2.1, and replaced deprecated methods. Adjusted language and API version handling to ensure compatibility with updated Kotlin standards. --- rewrite-kotlin/build.gradle.kts | 2 +- .../org/openrewrite/kotlin/KotlinParser.java | 209 +++++++++++------- 2 files changed, 127 insertions(+), 84 deletions(-) diff --git a/rewrite-kotlin/build.gradle.kts b/rewrite-kotlin/build.gradle.kts index d06da193a8..2a3ef03987 100644 --- a/rewrite-kotlin/build.gradle.kts +++ b/rewrite-kotlin/build.gradle.kts @@ -5,7 +5,7 @@ plugins { kotlin("jvm") version "2.1.20" } -val kotlinVersion = "2.1.20" +val kotlinVersion = "2.1.21" dependencies { compileOnly(project(":rewrite-core")) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java index da3563388c..480ca96778 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java @@ -22,7 +22,9 @@ import lombok.AccessLevel; import lombok.RequiredArgsConstructor; import org.intellij.lang.annotations.Language; +import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.KtRealPsiSourceElement; +import org.jetbrains.kotlin.cli.common.SessionConstructionUtils; import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.kotlin.cli.common.messages.MessageCollector; @@ -51,14 +53,15 @@ import org.jetbrains.kotlin.fir.pipeline.AnalyseKt; import org.jetbrains.kotlin.fir.pipeline.FirUtilsKt; import org.jetbrains.kotlin.fir.resolve.ScopeSession; -import org.jetbrains.kotlin.fir.session.FirJvmSessionFactory; -import org.jetbrains.kotlin.fir.session.FirSessionConfigurator; import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope; import org.jetbrains.kotlin.idea.KotlinFileType; import org.jetbrains.kotlin.idea.KotlinLanguage; import org.jetbrains.kotlin.load.kotlin.PackagePartProvider; import org.jetbrains.kotlin.modules.Module; import org.jetbrains.kotlin.name.Name; +import org.jetbrains.kotlin.platform.TargetPlatform; +import org.jetbrains.kotlin.platform.jvm.JvmPlatforms; +import org.jetbrains.kotlin.psi.KtCommonFile; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.utils.PathUtil; import org.jspecify.annotations.Nullable; @@ -136,21 +139,22 @@ public Stream parse(@Language("kotlin") String... sources) { return parseInputs( Arrays.stream(sources) - .map(sourceFile -> { - Matcher packageMatcher = packagePattern.matcher(sourceFile); - String pkg = packageMatcher.find() ? packageMatcher.group(1).replace('.', '/') + "/" : ""; - - String className = Optional.ofNullable(simpleName.apply(sourceFile)) - .orElse(Long.toString(System.nanoTime())) + ".kt"; - - Path path = Paths.get(pkg + className); - return new Input( - path, null, - () -> new ByteArrayInputStream(sourceFile.getBytes(StandardCharsets.UTF_8)), - true - ); - }) - .collect(toList()), + .map(sourceFile -> { + Matcher packageMatcher = packagePattern.matcher(sourceFile); + String pkg = packageMatcher.find() ? packageMatcher.group(1) + .replace('.', '/') + "/" : ""; + + String className = Optional.ofNullable(simpleName.apply(sourceFile)) + .orElse(Long.toString(System.nanoTime())) + ".kt"; + + Path path = Paths.get(pkg + className); + return new Input( + path, null, + () -> new ByteArrayInputStream(sourceFile.getBytes(StandardCharsets.UTF_8)), + true + ); + }) + .collect(toList()), null, new InMemoryExecutionContext() ); @@ -168,44 +172,52 @@ public Stream parseInputs(Iterable sources, @Nullable Path re try { compilerCus = parse(acceptedInputs, disposable, pctx); } catch (Exception e) { - return acceptedInputs.stream().map(input -> ParseError.build(this, input, relativeTo, ctx, e)); + return acceptedInputs.stream() + .map(input -> ParseError.build(this, input, relativeTo, ctx, e)); } FirSession firSession = compilerCus.getFirSession(); return Stream.concat( - compilerCus.getSources().stream() - .map(kotlinSource -> { - try { - assert kotlinSource.getFirFile() != null; - assert kotlinSource.getFirFile().getSource() != null; - PsiElement psi = ((KtRealPsiSourceElement) kotlinSource.getFirFile().getSource()).getPsi(); - AnalyzerWithCompilerReport.SyntaxErrorReport report = - AnalyzerWithCompilerReport.Companion.reportSyntaxErrors(psi, new PrintingMessageCollector(System.err, PLAIN_FULL_PATHS, true)); - if (report.isHasErrors()) { - return ParseError.build(KotlinParser.this, kotlinSource.getInput(), relativeTo, ctx, new RuntimeException()); - } - - KotlinTypeMapping typeMapping = new KotlinTypeMapping(typeCache, firSession, kotlinSource.getFirFile()); - PsiElementAssociations associations = new PsiElementAssociations(typeMapping, kotlinSource.getFirFile()); - associations.initialize(); - KotlinTreeParserVisitor psiParser = new KotlinTreeParserVisitor(kotlinSource, associations, styles, relativeTo, ctx); - SourceFile cu = psiParser.parse(); - - parsingListener.parsed(kotlinSource.getInput(), cu); - return requirePrintEqualsInput(cu, kotlinSource.getInput(), relativeTo, ctx); - } catch (Throwable t) { - ctx.getOnError().accept(t); - return ParseError.build(this, kotlinSource.getInput(), relativeTo, ctx, t); - } - }), - Stream.generate(() -> { - // The disposable should be disposed of exactly once after all sources have been parsed - Disposer.dispose(disposable); - return (SourceFile) null; - }) - .limit(1)) - .filter(Objects::nonNull) - .filter(source -> !source.getSourcePath().getFileName().toString().startsWith("dependsOn-")); + compilerCus.getSources() + .stream() + .map(kotlinSource -> { + try { + assert kotlinSource.getFirFile() != null; + assert kotlinSource.getFirFile() + .getSource() != null; + PsiElement psi = ((KtRealPsiSourceElement) kotlinSource.getFirFile() + .getSource()).getPsi(); + AnalyzerWithCompilerReport.SyntaxErrorReport report = + AnalyzerWithCompilerReport.Companion.reportSyntaxErrors(psi, new PrintingMessageCollector(System.err, PLAIN_FULL_PATHS, true)); + if (report.isHasErrors()) { + return ParseError.build(KotlinParser.this, kotlinSource.getInput(), relativeTo, ctx, new RuntimeException()); + } + + KotlinTypeMapping typeMapping = new KotlinTypeMapping(typeCache, firSession, kotlinSource.getFirFile()); + PsiElementAssociations associations = new PsiElementAssociations(typeMapping, kotlinSource.getFirFile()); + associations.initialize(); + KotlinTreeParserVisitor psiParser = new KotlinTreeParserVisitor(kotlinSource, associations, styles, relativeTo, ctx); + SourceFile cu = psiParser.parse(); + + parsingListener.parsed(kotlinSource.getInput(), cu); + return requirePrintEqualsInput(cu, kotlinSource.getInput(), relativeTo, ctx); + } catch (Throwable t) { + ctx.getOnError() + .accept(t); + return ParseError.build(this, kotlinSource.getInput(), relativeTo, ctx, t); + } + }), + Stream.generate(() -> { + // The disposable should be disposed of exactly once after all sources have been parsed + Disposer.dispose(disposable); + return (SourceFile) null; + }) + .limit(1)) + .filter(Objects::nonNull) + .filter(source -> !source.getSourcePath() + .getFileName() + .toString() + .startsWith("dependsOn-")); } @Override @@ -265,7 +277,7 @@ public static class Builder extends Parser.Builder { private boolean logCompilationWarningsAndErrors; private final List styles = new ArrayList<>(); private String moduleName = "main"; - private KotlinLanguageLevel languageLevel = KotlinLanguageLevel.KOTLIN_1_9; + private KotlinLanguageLevel languageLevel = KotlinLanguageLevel.KOTLIN_2_1; private boolean isKotlinScript = false; public Builder() { @@ -324,8 +336,8 @@ public Builder addClasspathEntry(Path entry) { public Builder dependsOn(@Language("kotlin") String... inputsAsStrings) { this.dependsOn = Arrays.stream(inputsAsStrings) - .map(input -> Input.fromString(determinePath("dependsOn-", input), input)) - .collect(toList()); + .map(input -> Input.fromString(determinePath("dependsOn-", input), input)) + .collect(toList()); return this; } @@ -401,7 +413,8 @@ public CompiledSource parse(List sources, Disposable disposable, E configureJdkClasspathRoots(compilerConfiguration); configureBaseRoots(compilerConfiguration, arguments); - Module module = configureModuleChunk(compilerConfiguration, arguments, null).getModules().get(0); + Module module = configureModuleChunk(compilerConfiguration, arguments, null).getModules() + .get(0); KotlinCoreEnvironment environment = KotlinCoreEnvironment.createForProduction( disposable, @@ -409,21 +422,14 @@ public CompiledSource parse(List sources, Disposable disposable, E EnvironmentConfigFiles.JVM_CONFIG_FILES); List ktFiles = new ArrayList<>(sources.size()); - List kotlinSources = new ArrayList<>(sources.size()); + for (int i = 0; i < sources.size(); i++) { Parser.Input source = sources.get(i); - String fileName; + String fileName = buildFilename(source, i); - if ("openRewriteFile.kt".equals(source.getPath().toString())) { - fileName = "openRewriteFile" + i + ".kt"; - } else if ("openRewriteFile.kts".equals(source.getPath().toString())) { - fileName = "openRewriteFile" + i + ".kts"; - } else { - fileName = source.getPath().toString(); - } - - String sourceText = source.getSource(ctx).readFully(); + String sourceText = source.getSource(ctx) + .readFully(); List cRLFLocations = getCRLFLocations(sourceText); VirtualFile vFile = new LightVirtualFile(fileName, KotlinFileType.INSTANCE, StringUtilRt.convertLineSeparators(sourceText)); @@ -440,7 +446,8 @@ public CompiledSource parse(List sources, Disposable disposable, E Function1 providerFunction1 = environment::createPackagePartProvider; VfsBasedProjectEnvironment projectEnvironment = new VfsBasedProjectEnvironment( environment.getProject(), - VirtualFileManager.getInstance().getFileSystem(StandardFileSystems.FILE_PROTOCOL), + VirtualFileManager.getInstance() + .getFileSystem(StandardFileSystems.FILE_PROTOCOL), providerFunction1); AbstractProjectFileSearchScope sourceScope = projectEnvironment.getSearchScopeByPsiFiles(ktFiles); @@ -468,19 +475,28 @@ public CompiledSource parse(List sources, Disposable disposable, E return Unit.INSTANCE; }; - Function1 sessionConfigurator = session -> Unit.INSTANCE; + Name name = Name.identifier(module.getModuleName()); + TargetPlatform jvmPlatform = JvmPlatforms.INSTANCE.getDefaultJvmPlatform(); + + FirSession firSession = SessionConstructionUtils.INSTANCE + .prepareSessions( + ktFiles, + compilerConfiguration, + name, + jvmPlatform, + false, + null, + ktFile -> true, + KtCommonFile::isScript, + null, + null, + null + ) + .stream() + .findFirst() + .orElseThrow(() -> new IllegalStateException("Unable to create FirSession")) + .getSession(); - FirSession firSession = FirJvmSessionFactory.INSTANCE.createLibrarySession( - Name.identifier(module.getModuleName()), - sessionProvider, - null, - projectEnvironment, - null, - sourceScope.plus(libraryScope), - null, - languageVersionSettings, - null - ); //TODO build session with dependencies @@ -505,9 +521,12 @@ public CompiledSource parse(List sources, Disposable disposable, E List rawFir = FirUtilsKt.buildFirFromKtFiles(firSession, ktFiles); Pair> result = AnalyseKt.runResolution(firSession, rawFir); - assert kotlinSources.size() == result.getSecond().size(); + assert kotlinSources.size() == result.getSecond() + .size(); for (int i = 0; i < kotlinSources.size(); i++) { - kotlinSources.get(i).setFirFile(result.getSecond().get(i)); + kotlinSources.get(i) + .setFirFile(result.getSecond() + .get(i)); } // IR generation. // BaseDiagnosticsCollector diagnosticsReporter = DiagnosticReporterFactory.INSTANCE.createReporter(false); @@ -541,6 +560,19 @@ public CompiledSource parse(List sources, Disposable disposable, E return new CompiledSource(firSession, kotlinSources); } + private static @NotNull String buildFilename(Input source, int index) { + Path path = source.getPath(); + String pathName = path.toString(); + + if ("openRewriteFile.kt".equals(pathName)) { + return "openRewriteFile" + index + ".kt"; + } else if ("openRewriteFile.kts".equals(pathName)) { + return "openRewriteFile" + index + ".kts"; + } else { + return pathName; + } + } + public enum KotlinLanguageLevel { KOTLIN_1_0, KOTLIN_1_1, @@ -551,7 +583,9 @@ public enum KotlinLanguageLevel { KOTLIN_1_6, KOTLIN_1_7, KOTLIN_1_8, - KOTLIN_1_9 + KOTLIN_1_9, + KOTLIN_2_0, + KOTLIN_2_1, } private CompilerConfiguration compilerConfiguration() { @@ -597,6 +631,10 @@ private LanguageVersion getLanguageVersion(KotlinLanguageLevel languageLevel) { return LanguageVersion.KOTLIN_1_8; case KOTLIN_1_9: return LanguageVersion.KOTLIN_1_9; + case KOTLIN_2_0: + return LanguageVersion.KOTLIN_2_0; + case KOTLIN_2_1: + return LanguageVersion.KOTLIN_2_1; default: throw new IllegalArgumentException("Unknown language level: " + languageLevel); } @@ -624,6 +662,10 @@ private ApiVersion getApiVersion(KotlinLanguageLevel languageLevel) { return ApiVersion.KOTLIN_1_8; case KOTLIN_1_9: return ApiVersion.KOTLIN_1_9; + case KOTLIN_2_0: + return ApiVersion.KOTLIN_2_0; + case KOTLIN_2_1: + return ApiVersion.KOTLIN_2_1; default: throw new IllegalArgumentException("Unknown language level: " + languageLevel); } @@ -668,7 +710,8 @@ static Path determinePath(String prefix, String sourceCode) { .orElseGet(() -> matchClassPattern(classPattern, sourceCode) .orElse(Long.toString(System.nanoTime()))); Matcher packageMatcher = packagePattern.matcher(sourceCode); - String pkg = packageMatcher.find() ? packageMatcher.group(1).replace('.', '/') + "/" : ""; + String pkg = packageMatcher.find() ? packageMatcher.group(1) + .replace('.', '/') + "/" : ""; return Paths.get(pkg, prefix + className + ".kt"); } } From 21048af587ec9a3757d05bec33660f261a1cfb76 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 7 Jun 2025 18:21:57 +0200 Subject: [PATCH 06/17] Refactor: Simplify module building in KotlinParser and enhance type signature handling --- .../org/openrewrite/kotlin/KotlinParser.java | 89 +++++++++++-------- .../kotlin/KotlinTypeSignatureBuilder.kt | 1 + 2 files changed, 51 insertions(+), 39 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java index 480ca96778..95f51b6f82 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java @@ -29,10 +29,13 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.kotlin.cli.common.messages.MessageCollector; import org.jetbrains.kotlin.cli.common.messages.PrintingMessageCollector; +import org.jetbrains.kotlin.cli.common.modules.ModuleChunk; +import org.jetbrains.kotlin.cli.jvm.compiler.CliCompilerUtilsKt; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.VfsBasedProjectEnvironment; import org.jetbrains.kotlin.cli.jvm.config.JvmContentRootsKt; +import org.jetbrains.kotlin.cli.pipeline.jvm.JvmFrontendPipelinePhase; import org.jetbrains.kotlin.com.intellij.openapi.Disposable; import org.jetbrains.kotlin.com.intellij.openapi.util.Disposer; import org.jetbrains.kotlin.com.intellij.openapi.util.text.StringUtilRt; @@ -43,12 +46,12 @@ import org.jetbrains.kotlin.com.intellij.psi.PsiElement; import org.jetbrains.kotlin.com.intellij.psi.PsiManager; import org.jetbrains.kotlin.com.intellij.psi.SingleRootFileViewProvider; -import org.jetbrains.kotlin.com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.kotlin.com.intellij.testFramework.LightVirtualFile; import org.jetbrains.kotlin.config.*; import org.jetbrains.kotlin.fir.DependencyListForCliModule; import org.jetbrains.kotlin.fir.FirSession; import org.jetbrains.kotlin.fir.declarations.FirFile; +import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider; import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider; import org.jetbrains.kotlin.fir.pipeline.AnalyseKt; import org.jetbrains.kotlin.fir.pipeline.FirUtilsKt; @@ -56,7 +59,6 @@ import org.jetbrains.kotlin.fir.session.environment.AbstractProjectFileSearchScope; import org.jetbrains.kotlin.idea.KotlinFileType; import org.jetbrains.kotlin.idea.KotlinLanguage; -import org.jetbrains.kotlin.load.kotlin.PackagePartProvider; import org.jetbrains.kotlin.modules.Module; import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.platform.TargetPlatform; @@ -391,30 +393,7 @@ public KotlinParser.Builder clone() { public CompiledSource parse(List sources, Disposable disposable, ExecutionContext ctx) { CompilerConfiguration compilerConfiguration = compilerConfiguration(); - if (classpath != null) { - for (Path path : classpath) { - File file; - try { - file = path.toFile(); - } catch (UnsupportedOperationException ex) { - continue; - } - addJvmClasspathRoot(compilerConfiguration, file); - } - } - addJvmClasspathRoot(compilerConfiguration, PathUtil.getResourcePathForClass(AnnotationTarget.class)); - - K2JVMCompilerArguments arguments = new K2JVMCompilerArguments(); - configureJdkHome(compilerConfiguration, arguments); - configureJavaModulesContentRoots(compilerConfiguration, arguments); - configureAdvancedJvmOptions(compilerConfiguration, arguments); - configureKlibPaths(compilerConfiguration, arguments); - configureContentRootsFromClassPath(compilerConfiguration, arguments); - configureJdkClasspathRoots(compilerConfiguration); - configureBaseRoots(compilerConfiguration, arguments); - - Module module = configureModuleChunk(compilerConfiguration, arguments, null).getModules() - .get(0); + Module module = buildModule(compilerConfiguration); KotlinCoreEnvironment environment = KotlinCoreEnvironment.createForProduction( disposable, @@ -443,12 +422,12 @@ public CompiledSource parse(List sources, Disposable disposable, E kotlinSources.add(new KotlinSource(source, file, cRLFLocations)); } - Function1 providerFunction1 = environment::createPackagePartProvider; VfsBasedProjectEnvironment projectEnvironment = new VfsBasedProjectEnvironment( environment.getProject(), VirtualFileManager.getInstance() .getFileSystem(StandardFileSystems.FILE_PROTOCOL), - providerFunction1); + environment::createPackagePartProvider + ); AbstractProjectFileSearchScope sourceScope = projectEnvironment.getSearchScopeByPsiFiles(ktFiles); sourceScope.plus(projectEnvironment.getSearchScopeForProjectJavaSources()); @@ -478,19 +457,23 @@ public CompiledSource parse(List sources, Disposable disposable, E Name name = Name.identifier(module.getModuleName()); TargetPlatform jvmPlatform = JvmPlatforms.INSTANCE.getDefaultJvmPlatform(); - FirSession firSession = SessionConstructionUtils.INSTANCE - .prepareSessions( + DependencyListForCliModule libraryList = CliCompilerUtilsKt.createLibraryListForJvm( + module.getModuleName(), + compilerConfiguration, + emptyList() + ); + FirSession firSession = JvmFrontendPipelinePhase.INSTANCE + .prepareJvmSessions( ktFiles, - compilerConfiguration, name, - jvmPlatform, - false, - null, - ktFile -> true, - KtCommonFile::isScript, - null, - null, - null + compilerConfiguration, + projectEnvironment, + libraryScope, + libraryList, + ktFile -> false, + KtFile::isScript, + (ktFile, s) -> true, + ktFiles1 -> null ) .stream() .findFirst() @@ -560,6 +543,34 @@ public CompiledSource parse(List sources, Disposable disposable, E return new CompiledSource(firSession, kotlinSources); } + private Module buildModule(CompilerConfiguration compilerConfiguration) { + if (classpath != null) { + for (Path path : classpath) { + File file; + try { + file = path.toFile(); + } catch (UnsupportedOperationException ex) { + continue; + } + addJvmClasspathRoot(compilerConfiguration, file); + } + } + addJvmClasspathRoot(compilerConfiguration, PathUtil.getResourcePathForClass(AnnotationTarget.class)); + + K2JVMCompilerArguments arguments = new K2JVMCompilerArguments(); + configureJdkHome(compilerConfiguration, arguments); + configureJavaModulesContentRoots(compilerConfiguration, arguments); + configureAdvancedJvmOptions(compilerConfiguration, arguments); + configureKlibPaths(compilerConfiguration, arguments); + configureContentRootsFromClassPath(compilerConfiguration, arguments); + configureJdkClasspathRoots(compilerConfiguration); + configureBaseRoots(compilerConfiguration, arguments); + + ModuleChunk moduleChunk = configureModuleChunk(compilerConfiguration, arguments, null); + return moduleChunk.getModules() + .get(0); + } + private static @NotNull String buildFilename(Input source, int index) { Path path = source.getPath(); String pathName = path.toString(); diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt index a8de70d88b..bad35aff9f 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt @@ -222,6 +222,7 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val is FirFile -> fileSignature(type) is FirResolvedTypeRef -> classSignature(type.coneType) is FirResolvedQualifier -> convertClassIdToFqn(type.classId) + is FirRegularClassSymbol -> convertClassIdToFqn(type.classId) else -> { throw UnsupportedOperationException("Unsupported class type: ${type.javaClass.name}") } From 1147abfdf87dea8ad3aeaed8c5e070a214422c15 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Tue, 17 Jun 2025 07:18:45 +0200 Subject: [PATCH 07/17] fix ++ issues --- .../org/openrewrite/kotlin/KotlinParser.java | 46 +++---------------- .../openrewrite/kotlin/KotlinTypeMapping.kt | 1 + .../kotlin/KotlinTypeSignatureBuilder.kt | 12 ++++- .../kotlin/internal/PsiElementAssociations.kt | 2 +- .../kotlin/tree/MethodInvocationTest.java | 2 +- 5 files changed, 20 insertions(+), 43 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java index 95f51b6f82..e954cc4dc8 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java @@ -24,7 +24,6 @@ import org.intellij.lang.annotations.Language; import org.jetbrains.annotations.NotNull; import org.jetbrains.kotlin.KtRealPsiSourceElement; -import org.jetbrains.kotlin.cli.common.SessionConstructionUtils; import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments; import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport; import org.jetbrains.kotlin.cli.common.messages.MessageCollector; @@ -51,8 +50,6 @@ import org.jetbrains.kotlin.fir.DependencyListForCliModule; import org.jetbrains.kotlin.fir.FirSession; import org.jetbrains.kotlin.fir.declarations.FirFile; -import org.jetbrains.kotlin.fir.deserialization.ModuleDataProvider; -import org.jetbrains.kotlin.fir.java.FirProjectSessionProvider; import org.jetbrains.kotlin.fir.pipeline.AnalyseKt; import org.jetbrains.kotlin.fir.pipeline.FirUtilsKt; import org.jetbrains.kotlin.fir.resolve.ScopeSession; @@ -61,9 +58,6 @@ import org.jetbrains.kotlin.idea.KotlinLanguage; import org.jetbrains.kotlin.modules.Module; import org.jetbrains.kotlin.name.Name; -import org.jetbrains.kotlin.platform.TargetPlatform; -import org.jetbrains.kotlin.platform.jvm.JvmPlatforms; -import org.jetbrains.kotlin.psi.KtCommonFile; import org.jetbrains.kotlin.psi.KtFile; import org.jetbrains.kotlin.utils.PathUtil; import org.jspecify.annotations.Nullable; @@ -95,7 +89,6 @@ import static java.util.Collections.emptyList; import static java.util.stream.Collectors.toList; -import static org.jetbrains.kotlin.cli.common.CLIConfigurationKeys.MESSAGE_COLLECTOR_KEY; import static org.jetbrains.kotlin.cli.common.messages.MessageRenderer.PLAIN_FULL_PATHS; import static org.jetbrains.kotlin.cli.jvm.JvmArgumentsKt.*; import static org.jetbrains.kotlin.cli.jvm.K2JVMCompilerKt.configureModuleChunk; @@ -433,9 +426,6 @@ public CompiledSource parse(List sources, Disposable disposable, E sourceScope.plus(projectEnvironment.getSearchScopeForProjectJavaSources()); AbstractProjectFileSearchScope libraryScope = projectEnvironment.getSearchScopeForProjectLibraries(); - LanguageVersionSettings languageVersionSettings = compilerConfiguration.getNotNull(LANGUAGE_VERSION_SETTINGS); - - FirProjectSessionProvider sessionProvider = new FirProjectSessionProvider(); Function1 dependencyListBuilderProvider = builder -> { List jvmContentFiles = JvmContentRootsKt.getJvmClasspathRoots(compilerConfiguration); @@ -455,12 +445,10 @@ public CompiledSource parse(List sources, Disposable disposable, E }; Name name = Name.identifier(module.getModuleName()); - TargetPlatform jvmPlatform = JvmPlatforms.INSTANCE.getDefaultJvmPlatform(); - DependencyListForCliModule libraryList = CliCompilerUtilsKt.createLibraryListForJvm( - module.getModuleName(), - compilerConfiguration, - emptyList() + module.getModuleName(), + compilerConfiguration, + compilerConfiguration.get(JVMConfigurationKeys.FRIEND_PATHS, emptyList()) ); FirSession firSession = JvmFrontendPipelinePhase.INSTANCE .prepareJvmSessions( @@ -472,36 +460,14 @@ public CompiledSource parse(List sources, Disposable disposable, E libraryList, ktFile -> false, KtFile::isScript, - (ktFile, s) -> true, - ktFiles1 -> null + (ktFile, moduleName) -> {return true;}, //TODO how to find out whether file belongs to the module or not? + files -> null ) .stream() .findFirst() .orElseThrow(() -> new IllegalStateException("Unable to create FirSession")) .getSession(); - - //TODO build session with dependencies - -// FirSession firSession = FirSessionFactoryHelper.INSTANCE.createSessionWithDependencies( -// Name.identifier(module.getModuleName()), -// JvmPlatforms.INSTANCE.getUnspecifiedJvmPlatform(), -// JvmPlatformAnalyzerServices.INSTANCE, -// sessionProvider, -// projectEnvironment, -// languageVersionSettings, -// sourceScope, -// libraryScope, -// compilerConfiguration.get(LOOKUP_TRACKER), -// compilerConfiguration.get(ENUM_WHEN_TRACKER), -// compilerConfiguration.get(IMPORT_TRACKER), -// null, // Do not incrementally compile -// emptyList(), // Add extension registrars when needed here. -// true, -// dependencyListBuilderProvider, -// sessionConfigurator -// ); - List rawFir = FirUtilsKt.buildFirFromKtFiles(firSession, ktFiles); Pair> result = AnalyseKt.runResolution(firSession, rawFir); assert kotlinSources.size() == result.getSecond() @@ -602,7 +568,7 @@ public enum KotlinLanguageLevel { private CompilerConfiguration compilerConfiguration() { CompilerConfiguration compilerConfiguration = new CompilerConfiguration(); - compilerConfiguration.put(CommonConfigurationKeys.MODULE_NAME, moduleName); + compilerConfiguration.put(MODULE_NAME, moduleName); compilerConfiguration.put(MESSAGE_COLLECTOR_KEY, logCompilationWarningsAndErrors ? new PrintingMessageCollector(System.err, PLAIN_FULL_PATHS, true) : MessageCollector.Companion.getNONE()); diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt index b19203d8a4..9a0bbcccfe 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeMapping.kt @@ -212,6 +212,7 @@ class KotlinTypeMapping( } else -> { + println("Unsupported type: $type") Unknown.getInstance() } } diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt index bad35aff9f..37cf6f9a19 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt @@ -188,7 +188,17 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val type.asString() } - else -> "{undefined}" + is FirRegularClassSymbol -> { + if (type.fir.typeParameters.isNotEmpty()) { + parameterizedSignature(type.fir) + } else { + classSignature(type.fir) + } + } + else -> { + println("Undefined type: $type") + "{undefined}" + } } } diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt index 8866610532..9010c05eb9 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementAssociations.kt @@ -334,7 +334,7 @@ class PsiElementAssociations(val typeMapping: KotlinTypeMapping, val file: FirFi p is KtPostfixExpression -> allFirInfos.firstOrNull { it.fir is FirResolvedTypeRef || it.fir is FirFunctionCall }?.fir p is KtTypeReference -> allFirInfos.firstOrNull { it.fir is FirResolvedTypeRef }?.fir p is KtWhenConditionInRange || p is KtBinaryExpression -> allFirInfos.firstOrNull { it.fir is FirFunctionCall }?.fir - p is KtNameReferenceExpression -> allFirInfos.firstOrNull { it.fir is FirClass }?.fir + p is KtNameReferenceExpression -> allFirInfos.firstOrNull { it.fir is FirDesugaredAssignmentValueReferenceExpression }?.fir else -> { throw IllegalStateException("Unable to determine the FIR element associated to the PSI." + if (psi == null) "null element" else "original PSI: ${psi.javaClass.name}, mapped PSI: ${p.javaClass.name}") } diff --git a/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java b/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java index 357db341a9..93ad75b2b5 100644 --- a/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java +++ b/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java @@ -91,7 +91,7 @@ class SpecScope { fun id ( id : String ) : Spec = delegate . id ( id ) } infix fun Spec . version ( version : String ) : Spec = version ( version ) - public inline val SpecScope . `java-library` : Spec get ( ) = id ( "org.gradle.java-library" ) + public inline val SpecScope . `java-library` : Spec get( ) = id ( "org.gradle.java-library" ) class DSL { fun plugins ( block : SpecScope . ( ) -> Unit ) { From 5d5a2913e7fe415048af23f99f3239aff879f896 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sun, 29 Jun 2025 19:29:45 +0200 Subject: [PATCH 08/17] upgrade to Kotlin 2.2.0 --- rewrite-kotlin/build.gradle.kts | 4 ++-- .../org/openrewrite/kotlin/KotlinParser.java | 16 +++++++++---- .../openrewrite/kotlin/KotlinIrTypeMapping.kt | 24 ++++++++++++------- .../kotlin/KotlinTypeIrSignatureBuilder.kt | 7 ++++-- .../openrewrite/kotlin/KotlinTypeMapping.kt | 17 +++++++------ .../kotlin/KotlinTypeSignatureBuilder.kt | 9 +++++-- .../kotlin/internal/IrTreeVisitor.kt | 4 ++-- .../internal/PsiElementIrAssociations.kt | 4 ++-- 8 files changed, 55 insertions(+), 30 deletions(-) diff --git a/rewrite-kotlin/build.gradle.kts b/rewrite-kotlin/build.gradle.kts index 2a3ef03987..9bd04ad239 100644 --- a/rewrite-kotlin/build.gradle.kts +++ b/rewrite-kotlin/build.gradle.kts @@ -2,10 +2,10 @@ import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { id("org.openrewrite.build.language-library") - kotlin("jvm") version "2.1.20" + kotlin("jvm") version "2.2.0" } -val kotlinVersion = "2.1.21" +val kotlinVersion = "2.2.0" dependencies { compileOnly(project(":rewrite-core")) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java index e954cc4dc8..56e48b6e06 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/KotlinParser.java @@ -96,7 +96,7 @@ import static org.jetbrains.kotlin.config.CommonConfigurationKeys.*; import static org.jetbrains.kotlin.config.JVMConfigurationKeys.DO_NOT_CLEAR_BINDING_CONTEXT; import static org.jetbrains.kotlin.config.JVMConfigurationKeys.LINK_VIA_SIGNATURES; -import static org.jetbrains.kotlin.incremental.IncrementalFirJvmCompilerRunnerKt.configureBaseRoots; +import static org.jetbrains.kotlin.incremental.IncrementalFirJvmCompilerRunnerKt.*; import static org.openrewrite.kotlin.KotlinParser.SourcePathFromSourceTextResolver.determinePath; @SuppressWarnings("CommentedOutCode") @@ -272,7 +272,7 @@ public static class Builder extends Parser.Builder { private boolean logCompilationWarningsAndErrors; private final List styles = new ArrayList<>(); private String moduleName = "main"; - private KotlinLanguageLevel languageLevel = KotlinLanguageLevel.KOTLIN_2_1; + private KotlinLanguageLevel languageLevel = KotlinLanguageLevel.KOTLIN_2_2; private boolean isKotlinScript = false; public Builder() { @@ -433,14 +433,15 @@ public CompiledSource parse(List sources, Disposable disposable, E for (File jvmContentFile : jvmContentFiles) { jvmContentPaths.add(jvmContentFile.toPath()); } - builder.dependencies(jvmContentPaths); +// builder.dependencies(jvmContentPaths); //TODO how to replace this? List jvmModularFiles = JvmContentRootsKt.getJvmModularRoots(compilerConfiguration); List jvmModularPaths = new ArrayList<>(jvmModularFiles.size()); for (File jvmModularFile : jvmModularFiles) { jvmModularPaths.add(jvmModularFile.toPath()); } - builder.dependencies(jvmModularPaths); +// builder.dependencies(jvmModularPaths); //TODO how to replace this? + return Unit.INSTANCE; }; @@ -530,7 +531,7 @@ private Module buildModule(CompilerConfiguration compilerConfiguration) { configureKlibPaths(compilerConfiguration, arguments); configureContentRootsFromClassPath(compilerConfiguration, arguments); configureJdkClasspathRoots(compilerConfiguration); - configureBaseRoots(compilerConfiguration, arguments); +// configureBaseRoots(compilerConfiguration, arguments); //TODO how to replace this? ModuleChunk moduleChunk = configureModuleChunk(compilerConfiguration, arguments, null); return moduleChunk.getModules() @@ -563,6 +564,7 @@ public enum KotlinLanguageLevel { KOTLIN_1_9, KOTLIN_2_0, KOTLIN_2_1, + KOTLIN_2_2, } private CompilerConfiguration compilerConfiguration() { @@ -612,6 +614,8 @@ private LanguageVersion getLanguageVersion(KotlinLanguageLevel languageLevel) { return LanguageVersion.KOTLIN_2_0; case KOTLIN_2_1: return LanguageVersion.KOTLIN_2_1; + case KOTLIN_2_2: + return LanguageVersion.KOTLIN_2_2; default: throw new IllegalArgumentException("Unknown language level: " + languageLevel); } @@ -643,6 +647,8 @@ private ApiVersion getApiVersion(KotlinLanguageLevel languageLevel) { return ApiVersion.KOTLIN_2_0; case KOTLIN_2_1: return ApiVersion.KOTLIN_2_1; + case KOTLIN_2_2: + return ApiVersion.KOTLIN_2_2; default: throw new IllegalArgumentException("Unknown language level: " + languageLevel); } diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt index ce73928a31..cef41c1e87 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinIrTypeMapping.kt @@ -15,12 +15,12 @@ */ package org.openrewrite.kotlin +import org.jetbrains.kotlin.DeprecatedForRemovalCompilerApi import org.jetbrains.kotlin.descriptors.ClassKind import org.jetbrains.kotlin.descriptors.DescriptorVisibility import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction -import org.jetbrains.kotlin.ir.backend.js.utils.valueArguments import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrConstructorImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl @@ -352,6 +352,7 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin return methodDeclarationType(function, signature) } + @OptIn(DeprecatedForRemovalCompilerApi::class) private fun methodDeclarationType(function: IrFunction, signature: String): JavaType.Method { val paramNames: MutableList? = if (function.valueParameters.isEmpty()) null else ArrayList(function.valueParameters.size) @@ -424,8 +425,9 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin } } + @OptIn(DeprecatedForRemovalCompilerApi::class) fun methodInvocationType(type: IrCall, signature: String): JavaType.Method { - val paramNames: MutableList = ArrayList(type.valueArguments.size) + val paramNames: MutableList = ArrayList(type.valueArgumentsCount) for (v in type.symbol.owner.valueParameters) { paramNames.add(v.name.asString()) @@ -450,12 +452,13 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin } val returnType = type(type.symbol.owner.returnType) val paramTypes: MutableList? = - if (type.valueArguments.isNotEmpty() || type.extensionReceiver != null) ArrayList(type.valueArguments.size + (if (type.extensionReceiver != null) 1 else 0)) + if (type.valueArgumentsCount > 0 || type.extensionReceiver != null) ArrayList(type.valueArgumentsCount + (if (type.extensionReceiver != null) 1 else 0)) else null if (type.extensionReceiver != null) { paramTypes!!.add(type(type.extensionReceiver!!.type)) } - for (param: IrExpression? in type.valueArguments) { + for (i in 0 until type.valueArgumentsCount) { + val param: IrExpression? = type.getValueArgument(i) if (param != null) { paramTypes!!.add(type(param.type)) } @@ -468,8 +471,9 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin return method } + @OptIn(DeprecatedForRemovalCompilerApi::class) fun methodInvocationType(type: IrConstructorCall, signature: String): JavaType.Method { - val paramNames: MutableList = ArrayList(type.valueArguments.size) + val paramNames: MutableList = ArrayList(type.valueArgumentsCount) for (v in type.symbol.owner.valueParameters) { paramNames.add(v.name.asString()) @@ -494,12 +498,14 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin } val returnType = declaringType val paramTypes: MutableList? = - if (type.valueArguments.isNotEmpty() || type.extensionReceiver != null) ArrayList(type.valueArguments.size + (if (type.extensionReceiver != null) 1 else 0)) + if (type.valueArgumentsCount > 0 || type.extensionReceiver != null) ArrayList(type.valueArgumentsCount + (if (type.extensionReceiver != null) 1 else 0)) else null if (type.extensionReceiver != null) { paramTypes!!.add(type(type.extensionReceiver!!.type)) } - for (param: IrExpression? in type.valueArguments) { + for (i in 0 until type.valueArgumentsCount) { + val param: IrExpression? = type.getValueArgument(i) + if (param != null) { paramTypes!!.add(type(param.type)) } @@ -720,10 +726,12 @@ class KotlinIrTypeMapping(private val typeCache: JavaTypeCache) : JavaTypeMappin return true } + @OptIn(DeprecatedForRemovalCompilerApi::class) private fun isSourceRetention(annotation: IrConstructorCall): Boolean { val sig = signatureBuilder.classSignature(annotation.type) if (sig == "kotlin.annotation.Retention" || sig == "java.lang.annotation") { - for (args in annotation.valueArguments) { + for (i in 0.. annotation.valueArgumentsCount) { + val args = annotation.getValueArgument(i) if (args is IrDeclarationReference && args.symbol.owner is IrDeclarationWithName) { return (args.symbol.owner as IrDeclarationWithName).name.asString() == "SOURCE" } diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt index d432c90e23..623c0aa6f4 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeIrSignatureBuilder.kt @@ -15,10 +15,10 @@ */ package org.openrewrite.kotlin +import org.jetbrains.kotlin.DeprecatedForRemovalCompilerApi import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyClass import org.jetbrains.kotlin.fir.lazy.Fir2IrLazyConstructor import org.jetbrains.kotlin.fir.lazy.Fir2IrLazySimpleFunction -import org.jetbrains.kotlin.ir.backend.js.utils.valueArguments import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.symbols.IrClassifierSymbol @@ -329,6 +329,7 @@ class KotlinTypeIrSignatureBuilder : JavaTypeSignatureBuilder { return signature.toString() } + @OptIn(DeprecatedForRemovalCompilerApi::class) private fun methodArgumentSignature(function: IrFunction): String { val genericArgumentTypes = StringJoiner(",", "[", "]") if (function.extensionReceiverParameter != null) { @@ -361,12 +362,14 @@ class KotlinTypeIrSignatureBuilder : JavaTypeSignatureBuilder { return signature.toString() } + @OptIn(DeprecatedForRemovalCompilerApi::class) private fun methodArgumentSignature(function: IrFunctionAccessExpression): String { val genericArgumentTypes = StringJoiner(",", "[", "]") if (function.extensionReceiver != null) { genericArgumentTypes.add(signature(function.extensionReceiver!!.type)) } - for (param: IrExpression? in function.valueArguments) { + for(i in 0.. { + type(type.source, parent, signature) + } + else -> { println("Unsupported type: $type") Unknown.getInstance() @@ -304,7 +307,7 @@ class KotlinTypeMapping( return gtv } - @OptIn(SymbolInternals::class) + @OptIn(SymbolInternals::class, DirectDeclarationsAccess::class) private fun classType(type: Any, parent: Any?, signature: String): FullyQualified { val fqn = signatureBuilder.classSignature(type) val fq: FullyQualified? = typeCache.get(fqn) @@ -497,7 +500,7 @@ class KotlinTypeMapping( return clazz } - @OptIn(SymbolInternals::class) + @OptIn(SymbolInternals::class, DirectDeclarationsAccess::class) fun methodDeclarationType(enumEntry: FirEnumEntry): Method? { val type = when (val fir = enumEntry.symbol.getContainingClassSymbol()?.fir) { is FirClass -> { @@ -687,7 +690,7 @@ class KotlinTypeMapping( @OptIn(SymbolInternals::class) fun methodInvocationType(function: FirFunctionCall, signature: String): Method? { val sym = function.calleeReference.toResolvedBaseSymbol() ?: return null - val receiver = if (sym is FirFunctionSymbol<*>) sym.receiverParameter else null + val receiver = if (sym is FirFunctionSymbol<*>) sym.receiverParameterSymbol else null val paramNames: MutableList? = when { sym is FirFunctionSymbol<*> && (receiver != null || sym.valueParameterSymbols.isNotEmpty()) -> { @@ -781,8 +784,8 @@ class KotlinTypeMapping( } val returnType = type(function.resolvedType) - if (function.toResolvedCallableSymbol()?.receiverParameter != null) { - paramTypes!!.add(type(function.toResolvedCallableSymbol()?.receiverParameter!!.typeRef)) + if (function.toResolvedCallableSymbol()?.receiverParameterSymbol != null) { + paramTypes!!.add(type(function.toResolvedCallableSymbol()?.receiverParameterSymbol!!.resolvedType)) } val mapNames = function.arguments.any { it is FirNamedArgumentExpression } var args: MutableMap? = null diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt index 37cf6f9a19..a1184faf07 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.fir.* import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.utils.classId import org.jetbrains.kotlin.fir.expressions.* +import org.jetbrains.kotlin.fir.expressions.impl.FirResolvedArgumentList import org.jetbrains.kotlin.fir.references.FirErrorNamedReference import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference import org.jetbrains.kotlin.fir.references.FirSuperReference @@ -46,6 +47,7 @@ import org.openrewrite.java.JavaTypeSignatureBuilder import org.openrewrite.java.tree.JavaType import java.util.* import kotlin.collections.HashMap +import kotlin.math.sign @Suppress("DuplicatedCode") class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val firFile: FirFile) : @@ -195,6 +197,9 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val classSignature(type.fir) } } + is FirResolvedArgumentList -> { + type.arguments.joinToString { signature(it, parent) } + } else -> { println("Undefined type: $type") "{undefined}" @@ -420,8 +425,8 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession, private val @OptIn(SymbolInternals::class) private fun methodCallArgumentSignature(function: FirFunctionCall): String { val genericArgumentTypes = StringJoiner(",", "[", "]") - if (function.toResolvedCallableSymbol()?.receiverParameter != null) { - genericArgumentTypes.add(signature(function.toResolvedCallableSymbol()?.receiverParameter!!.typeRef)) + if (function.toResolvedCallableSymbol()?.receiverParameterSymbol != null) { + genericArgumentTypes.add(signature(function.toResolvedCallableSymbol()?.receiverParameterSymbol!!.resolvedType)) } val mapNames = function.arguments.any { it is FirNamedArgumentExpression } var args: MutableMap? = null diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/IrTreeVisitor.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/IrTreeVisitor.kt index 355fb3d3be..92ba49b499 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/IrTreeVisitor.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/IrTreeVisitor.kt @@ -16,9 +16,9 @@ package org.openrewrite.kotlin.internal import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.ir.visitors.IrVisitor -open class IrTreeVisitor : IrElementVisitor { +open class IrTreeVisitor : IrVisitor() { override fun visitElement(element: IrElement, data: T) : Unit { element.acceptChildren(this, data) } diff --git a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt index 9021baf534..bd232d709c 100644 --- a/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt +++ b/rewrite-kotlin/src/main/kotlin/org/openrewrite/kotlin/internal/PsiElementIrAssociations.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.fir.expressions.impl.FirSingleExpressionBlock import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.visitors.IrElementVisitor +import org.jetbrains.kotlin.ir.visitors.IrVisitor import org.jetbrains.kotlin.psi.* import org.openrewrite.java.tree.JavaType import org.openrewrite.kotlin.KotlinIrTypeMapping @@ -48,7 +48,7 @@ class PsiElementIrAssociations(private val typeMapping: KotlinIrTypeMapping, pri } }.visitFile(psiFile) - object : IrElementVisitor>> { + object : IrVisitor>>() { override fun visitElement(element: IrElement, data: MutableMap>) { if (element is IrMetadataSourceOwner) { if (element.metadata is FirMetadataSource) { From 761cbfed9e862d958acebfc31fed661b0f8fb827 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sun, 6 Jul 2025 07:56:36 +0200 Subject: [PATCH 09/17] fix compilation errors caused by addition of dimensionsBeforeName parameter --- .../kotlin/internal/KotlinTreeParserVisitor.java | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java index aedbae4b6c..29e24ce855 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java @@ -952,6 +952,7 @@ public J visitParameter(KtParameter parameter, ExecutionContext data) { modifiers, typeExpression, null, + emptyList(), vars ); } @@ -2411,6 +2412,7 @@ public J visitDestructuringDeclaration(KtDestructuringDeclaration multiDeclarati emptyList(), typeExpression, null, + emptyList(), singletonList(padRight(namedVariable, prefix(entry.getColon()))) ); @@ -2436,6 +2438,7 @@ public J visitDestructuringDeclaration(KtDestructuringDeclaration multiDeclarati modifiers, null, null, + emptyList(), singletonList(padRight(emptyWithInitializer, Space.EMPTY)) ); @@ -2698,6 +2701,7 @@ private J visitNamedFunction0(KtNamedFunction function, ExecutionContext data) { emptyList(), null, null, + emptyList(), singletonList(infixReceiver) ); implicitParam = implicitParam.withMarkers(implicitParam.getMarkers().addIfAbsent(new TypeReferencePrefix(randomId(), Space.EMPTY))); @@ -2970,6 +2974,7 @@ public J visitProperty(KtProperty property, ExecutionContext data) { modifiers, typeExpression, null, + emptyList(), variables ); @@ -3991,6 +3996,7 @@ private J mapDestructuringDeclaration(KtDestructuringDeclaration ktDestructuring emptyList(), null, null, + emptyList(), variables ); From 84f2de157f6dee823a77df276a1285d893ab9ac5 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 26 Jul 2025 08:06:18 +0200 Subject: [PATCH 10/17] allow running SpacesTest.extensionProperty test alone --- rewrite-kotlin/build.gradle.kts | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/rewrite-kotlin/build.gradle.kts b/rewrite-kotlin/build.gradle.kts index 9bd04ad239..2180fa4838 100644 --- a/rewrite-kotlin/build.gradle.kts +++ b/rewrite-kotlin/build.gradle.kts @@ -21,11 +21,11 @@ dependencies { implementation(kotlin("stdlib")) testImplementation("org.assertj:assertj-core:latest.release") - testImplementation("org.junit.jupiter:junit-jupiter-api:latest.release") - testImplementation("org.junit.jupiter:junit-jupiter-params:latest.release") + testImplementation("org.junit.jupiter:junit-jupiter-api:5.13.4") + testImplementation("org.junit.jupiter:junit-jupiter-params:5.13.4") testImplementation("org.junit-pioneer:junit-pioneer:latest.release") testImplementation(project(":rewrite-test")) - testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:latest.release") + testRuntimeOnly("org.junit.jupiter:junit-jupiter-engine:5.13.4") testRuntimeOnly(project(":rewrite-java-21")) testRuntimeOnly("org.antlr:antlr4-runtime:4.13.2") From f9a4826c65e208029412c9c171d7a1987919d31f Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 26 Jul 2025 08:06:43 +0200 Subject: [PATCH 11/17] fix compiling errors after latest update --- .../main/java/org/openrewrite/test/MockHttpSender.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/rewrite-test/src/main/java/org/openrewrite/test/MockHttpSender.java b/rewrite-test/src/main/java/org/openrewrite/test/MockHttpSender.java index ba6966f5d5..0d373da5ed 100644 --- a/rewrite-test/src/main/java/org/openrewrite/test/MockHttpSender.java +++ b/rewrite-test/src/main/java/org/openrewrite/test/MockHttpSender.java @@ -29,7 +29,6 @@ public class MockHttpSender implements HttpSender { final UncheckedSupplier is; int responseCode = 200; - Map> responseHeaders = Collections.emptyMap(); public MockHttpSender(UncheckedSupplier is) { this.is = is; @@ -40,18 +39,13 @@ public MockHttpSender(int responseCode) { this.responseCode = responseCode; } - public MockHttpSender withResponseHeaders(Map> headers) { - this.responseHeaders = headers; - return this; - } - @Override public Response send(Request request) { if (responseCode != 200) { - return new Response(responseCode, null, responseHeaders, () -> { + return new Response(responseCode, null, () -> { }); } else { - return new Response(responseCode, is.get(), responseHeaders, () -> { + return new Response(responseCode, is.get(), () -> { }); } } From 40856b36fcaa649e34862b82a05d3078fc5480a3 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 26 Jul 2025 11:01:56 +0200 Subject: [PATCH 12/17] revert test change --- .../java/org/openrewrite/kotlin/tree/MethodInvocationTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java b/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java index c36883aa27..39f13cd886 100644 --- a/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java +++ b/rewrite-kotlin/src/test/java/org/openrewrite/kotlin/tree/MethodInvocationTest.java @@ -91,7 +91,7 @@ class SpecScope { fun id ( id : String ) : Spec = delegate . id ( id ) } infix fun Spec . version ( version : String ) : Spec = version ( version ) - public inline val SpecScope . `java-library` : Spec get( ) = id ( "org.gradle.java-library" ) + public inline val SpecScope . `java-library` : Spec get ( ) = id ( "org.gradle.java-library" ) class DSL { fun plugins ( block : SpecScope . ( ) -> Unit ) { From 3245818814121f65f836ada7120a0f313c12b001 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 9 Aug 2025 10:53:15 +0200 Subject: [PATCH 13/17] update jvmTarget gradle configuration --- rewrite-kotlin/build.gradle.kts | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/rewrite-kotlin/build.gradle.kts b/rewrite-kotlin/build.gradle.kts index 2bcaffbe1b..3b9eed1429 100644 --- a/rewrite-kotlin/build.gradle.kts +++ b/rewrite-kotlin/build.gradle.kts @@ -1,4 +1,4 @@ -import org.jetbrains.kotlin.gradle.tasks.KotlinCompile +import org.jetbrains.kotlin.gradle.dsl.JvmTarget plugins { id("org.openrewrite.build.language-library") @@ -29,6 +29,8 @@ dependencies { testImplementation("com.google.testing.compile:compile-testing:0.+") } -tasks.withType().configureEach { - kotlinOptions.jvmTarget = if (name.contains("Test")) "21" else "1.8" +kotlin { + compilerOptions { + jvmTarget.set(if (name.contains("Test")) JvmTarget.JVM_21 else JvmTarget.JVM_1_8) + } } From dbf162cf24de731795f6d3bcc0b843f62609cd31 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 9 Aug 2025 11:02:37 +0200 Subject: [PATCH 14/17] parameters and parathesis are now encapsulated in an object -> get parent to access whitespaces before --- .../openrewrite/kotlin/internal/KotlinTreeParserVisitor.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java index d4b4607647..58678a9631 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java @@ -1050,10 +1050,10 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat parameters.add(padRight(stmt, prefix(accessor.getRightParenthesis()))); } - params = JContainer.build(prefix(accessor.getLeftParenthesis()), parameters, Markers.EMPTY); + params = JContainer.build(prefix(accessor.getLeftParenthesis().getParent()), parameters, Markers.EMPTY); } else { params = JContainer.build( - prefix(accessor.getLeftParenthesis()), + prefix(accessor.getLeftParenthesis().getParent()), singletonList(padRight(new J.Empty(randomId(), prefix(accessor.getRightParenthesis()), Markers.EMPTY), Space.EMPTY)), Markers.EMPTY ); From dc9c8b446e1a4b4bbb7600cc8442b75d8bd9c45c Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 9 Aug 2025 11:12:56 +0200 Subject: [PATCH 15/17] handle null getLeftParenthesis --- .../kotlin/internal/KotlinTreeParserVisitor.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java index 58678a9631..38ee0e8c40 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java @@ -1050,10 +1050,10 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat parameters.add(padRight(stmt, prefix(accessor.getRightParenthesis()))); } - params = JContainer.build(prefix(accessor.getLeftParenthesis().getParent()), parameters, Markers.EMPTY); + params = JContainer.build(prefix(getLeftParenthesis(accessor)), parameters, Markers.EMPTY); } else { params = JContainer.build( - prefix(accessor.getLeftParenthesis().getParent()), + prefix(getLeftParenthesis(accessor)), singletonList(padRight(new J.Empty(randomId(), prefix(accessor.getRightParenthesis()), Markers.EMPTY), Space.EMPTY)), Markers.EMPTY ); @@ -1094,6 +1094,17 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat )); } + private static PsiElement getLeftParenthesis(KtPropertyAccessor accessor) { + PsiElement lpar = accessor.getLeftParenthesis(); + if (lpar == null) { + return null; + } + if (lpar.getPrevSibling() == null) { + return lpar.getParent(); + } + return lpar; + } + @Override public J visitQualifiedExpression(KtQualifiedExpression expression, ExecutionContext data) { Expression receiver = convertToExpression(expression.getReceiverExpression().accept(this, data)); From 27dbc79084d768beec06ebf45d5c9a21c2eaf9bf Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 9 Aug 2025 16:07:36 +0200 Subject: [PATCH 16/17] get parent to access whitespaces after --- .../kotlin/internal/KotlinTreeParserVisitor.java | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java index 38ee0e8c40..34981abcd0 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java @@ -1060,7 +1060,7 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat } if (accessor.getReturnTypeReference() != null) { - markers = markers.addIfAbsent(new TypeReferencePrefix(randomId(), suffix(accessor.getRightParenthesis()))); + markers = markers.addIfAbsent(new TypeReferencePrefix(randomId(), suffix(getRightParenthesis(accessor)))); returnTypeExpression = accessor.getReturnTypeReference().accept(this, data).withPrefix(prefix(accessor.getReturnTypeReference())); } @@ -1094,7 +1094,18 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat )); } - private static PsiElement getLeftParenthesis(KtPropertyAccessor accessor) { + private static @org.jetbrains.annotations.Nullable PsiElement getRightParenthesis(KtPropertyAccessor accessor) { + PsiElement rpar = accessor.getRightParenthesis(); + if (rpar == null) { + return null; + } + if (rpar.getNextSibling() == null) { + return rpar.getParent(); + } + return rpar; + } + + private static @org.jetbrains.annotations.Nullable PsiElement getLeftParenthesis(KtPropertyAccessor accessor) { PsiElement lpar = accessor.getLeftParenthesis(); if (lpar == null) { return null; From 235e4397f09357050ae68bec3d64c482b56edf00 Mon Sep 17 00:00:00 2001 From: Marius Barbulescu Date: Sat, 9 Aug 2025 17:44:33 +0200 Subject: [PATCH 17/17] fix missing spaces before the parameter list --- .../internal/KotlinTreeParserVisitor.java | 686 ++++++++++++------ 1 file changed, 446 insertions(+), 240 deletions(-) diff --git a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java index 34981abcd0..bbd981be57 100644 --- a/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java +++ b/rewrite-kotlin/src/main/java/org/openrewrite/kotlin/internal/KotlinTreeParserVisitor.java @@ -95,9 +95,12 @@ public KotlinTreeParserVisitor(KotlinSource kotlinSource, this.kotlinSource = kotlinSource; this.psiElementAssociations = psiElementAssociations; this.styles = styles; - sourcePath = kotlinSource.getInput().getRelativePath(relativeTo); - fileAttributes = kotlinSource.getInput().getFileAttributes(); - EncodingDetectingInputStream stream = kotlinSource.getInput().getSource(ctx); + sourcePath = kotlinSource.getInput() + .getRelativePath(relativeTo); + fileAttributes = kotlinSource.getInput() + .getFileAttributes(); + EncodingDetectingInputStream stream = kotlinSource.getInput() + .getSource(ctx); charset = stream.getCharset(); charsetBomMarked = stream.isCharsetBomMarked(); ownerStack.push(kotlinSource.getKtFile()); @@ -122,7 +125,8 @@ public J visitParenthesizedExpression(KtParenthesizedExpression expression, Exec randomId(), deepPrefix(expression), Markers.EMPTY, - padRight(expression.getExpression().accept(this, data), prefix(rPar)) + padRight(expression.getExpression() + .accept(this, data), prefix(rPar)) ); } @@ -138,10 +142,13 @@ public J visitForExpression(KtForExpression expression, ExecutionContext data) { Markers.EMPTY, padRight((J.VariableDeclarations) requireNonNull(expression.getLoopParameter()).accept(this, data), suffix(expression.getLoopParameter())), padRight(requireNonNull(expression.getLoopRange()).accept(this, data) - .withPrefix(prefix(expression.getLoopRange().getParent())), suffix(expression.getLoopRange().getParent())) + .withPrefix(prefix(expression.getLoopRange() + .getParent())), suffix(expression.getLoopRange() + .getParent())) ), padRight(requireNonNull(expression.getBody()).accept(this, data) - .withPrefix(prefix(expression.getBody().getParent())), suffix(expression.getBody())) + .withPrefix(prefix(expression.getBody() + .getParent())), suffix(expression.getBody())) ); } @@ -215,7 +222,8 @@ public J visitBackingField(KtBackingField accessor, ExecutionContext data) { @Override public J visitBinaryWithTypeRHSExpression(KtBinaryExpressionWithTypeRHS expression, ExecutionContext data) { - IElementType type = expression.getOperationReference().getReferencedNameElementType(); + IElementType type = expression.getOperationReference() + .getReferencedNameElementType(); if (type == KtTokens.AS_KEYWORD || type == KtTokens.AS_SAFE) { TypeTree clazz = (TypeTree) (requireNonNull(expression.getRight()).accept(this, data)); @@ -234,7 +242,8 @@ public J visitBinaryWithTypeRHSExpression(KtBinaryExpressionWithTypeRHS expressi Markers.EMPTY, JRightPadded.build(clazz) ), - convertToExpression(expression.getLeft().accept(this, data)) + convertToExpression(expression.getLeft() + .accept(this, data)) ); } @@ -262,7 +271,8 @@ public J visitBreakExpression(KtBreakExpression expression, ExecutionContext dat randomId(), deepPrefix(expression), Markers.EMPTY, - expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel().getIdentifier()), null) : null + expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel() + .getIdentifier()), null) : null ); } @@ -271,31 +281,36 @@ public J visitCallableReferenceExpression(KtCallableReferenceExpression expressi FirElement firElement = psiElementAssociations.primary(expression.getCallableReference()); if (!(firElement instanceof FirResolvedCallableReference || firElement instanceof FirCallableReferenceAccess)) { throw new UnsupportedOperationException(java.lang.String.format("Unsupported callable reference: fir class: %s, fir: %s, psi class: %s.", - firElement == null ? "null" : firElement.getClass().getName(), + firElement == null ? "null" : firElement.getClass() + .getName(), PsiTreePrinter.print(psiElementAssociations.primary(expression)), - expression.getClass().getName())); + expression.getClass() + .getName())); } JavaType.Method methodReferenceType = null; JavaType.Variable fieldReferenceType = null; if (firElement instanceof FirResolvedCallableReference) { FirResolvedCallableReference reference = (FirResolvedCallableReference) psiElementAssociations.primary(expression.getCallableReference()); if (reference != null && reference.getResolvedSymbol() instanceof FirNamedFunctionSymbol) { - methodReferenceType = psiElementAssociations.getTypeMapping().methodDeclarationType( - ((FirNamedFunctionSymbol) reference.getResolvedSymbol()).getFir(), - expression.getReceiverExpression() - ); + methodReferenceType = psiElementAssociations.getTypeMapping() + .methodDeclarationType( + ((FirNamedFunctionSymbol) reference.getResolvedSymbol()).getFir(), + expression.getReceiverExpression() + ); } if (reference != null && reference.getResolvedSymbol() instanceof FirConstructorSymbol) { - methodReferenceType = psiElementAssociations.getTypeMapping().methodDeclarationType( - ((FirConstructorSymbol) reference.getResolvedSymbol()).getFir(), - expression.getReceiverExpression() - ); + methodReferenceType = psiElementAssociations.getTypeMapping() + .methodDeclarationType( + ((FirConstructorSymbol) reference.getResolvedSymbol()).getFir(), + expression.getReceiverExpression() + ); } if (reference != null && reference.getResolvedSymbol() instanceof FirPropertySymbol) { - fieldReferenceType = psiElementAssociations.getTypeMapping().variableType( - ((FirPropertySymbol) reference.getResolvedSymbol()).getFir(), - expression.getReceiverExpression() - ); + fieldReferenceType = psiElementAssociations.getTypeMapping() + .variableType( + ((FirPropertySymbol) reference.getResolvedSymbol()).getFir(), + expression.getReceiverExpression() + ); } } @@ -304,7 +319,8 @@ public J visitCallableReferenceExpression(KtCallableReferenceExpression expressi receiver = padRight(new J.Empty(randomId(), Space.EMPTY, Markers.EMPTY), prefix(expression.findColonColon())); } else { - Expression receiverExp = convertToExpression(expression.getReceiverExpression().accept(this, data)); + Expression receiverExp = convertToExpression(expression.getReceiverExpression() + .accept(this, data)); if (expression.getHasQuestionMarks()) { PsiElement questionMark = PsiTreeUtil.findSiblingForward(expression.getFirstChild(), KtTokens.QUEST, null); @@ -324,7 +340,9 @@ public J visitCallableReferenceExpression(KtCallableReferenceExpression expressi Markers.EMPTY, receiver, null, - padLeft(prefix(expression.getLastChild()), expression.getCallableReference().accept(this, data).withPrefix(Space.EMPTY)), + padLeft(prefix(expression.getLastChild()), expression.getCallableReference() + .accept(this, data) + .withPrefix(Space.EMPTY)), type(expression), methodReferenceType, fieldReferenceType @@ -351,8 +369,10 @@ public J visitCatchSection(KtCatchClause catchClause, ExecutionContext data) { @Override public J visitClassInitializer(KtClassInitializer initializer, ExecutionContext data) { - J.Block staticInit = requireNonNull(initializer.getBody()).accept(this, data).withPrefix(deepPrefix(initializer)); - return staticInit.getPadding().withStatic(padRight(true, prefix(initializer.getBody()))); + J.Block staticInit = requireNonNull(initializer.getBody()).accept(this, data) + .withPrefix(deepPrefix(initializer)); + return staticInit.getPadding() + .withStatic(padRight(true, prefix(initializer.getBody()))); } @Override @@ -380,18 +400,20 @@ public J visitClassOrObject(KtClassOrObject classOrObject, ExecutionContext data @Override public J visitCollectionLiteralExpression(KtCollectionLiteralExpression expression, ExecutionContext data) { JContainer elements; - if (expression.getInnerExpressions().isEmpty()) { + if (expression.getInnerExpressions() + .isEmpty()) { elements = JContainer.build(singletonList( padRight(new J.Empty(randomId(), Space.EMPTY, Markers.EMPTY), prefix(expression.getRightBracket())))); } else { - List> rps = new ArrayList<>(expression.getInnerExpressions().size()); + List> rps = new ArrayList<>(expression.getInnerExpressions() + .size()); for (KtExpression ktExpression : expression.getInnerExpressions()) { rps.add(padRight(convertToExpression(ktExpression.accept(this, data)), suffix(ktExpression))); } if (expression.getTrailingComma() != null) { rps = ListUtils.mapLast(rps, rp -> rp.withMarkers(rp.getMarkers() - .addIfAbsent(new TrailingComma(randomId(), suffix(expression.getTrailingComma()))))); + .addIfAbsent(new TrailingComma(randomId(), suffix(expression.getTrailingComma()))))); } elements = JContainer.build(Space.EMPTY, rps, Markers.EMPTY); @@ -428,7 +450,8 @@ public J visitContinueExpression(KtContinueExpression expression, ExecutionConte randomId(), deepPrefix(expression), Markers.EMPTY, - expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel().getIdentifier()), null) : null + expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel() + .getIdentifier()), null) : null ); } @@ -459,7 +482,8 @@ public J visitDoWhileExpression(KtDoWhileExpression expression, ExecutionContext JRightPadded body; if (expression.getBody() != null) { body = JRightPadded.build(requireNonNull(expression.getBody()).accept(this, data) - .withPrefix(prefix(expression.getBody().getParent()))); + .withPrefix(prefix(expression.getBody() + .getParent()))); } else { J.Block emptyBlock = new J.Block( randomId(), @@ -500,7 +524,8 @@ public J visitDynamicType(KtDynamicType type, ExecutionContext data) { @Override public J visitEnumEntry(KtEnumEntry enumEntry, ExecutionContext data) { List annotations = new ArrayList<>(); - if (!enumEntry.getAnnotationEntries().isEmpty()) { + if (!enumEntry.getAnnotationEntries() + .isEmpty()) { mapModifiers(enumEntry.getModifierList(), annotations, emptyList(), data); } @@ -511,12 +536,14 @@ public J visitEnumEntry(KtEnumEntry enumEntry, ExecutionContext data) { JavaType.Method mt = methodDeclarationType(enumEntry); if (enumEntry.getInitializerList() != null) { - initializer = (J.NewClass) enumEntry.getInitializerList().accept(this, data); + initializer = (J.NewClass) enumEntry.getInitializerList() + .accept(this, data); initializer = initializer.withMethodType(mt); } if (enumEntry.getBody() != null) { - J.Block body = (J.Block) enumEntry.getBody().accept(this, data); + J.Block body = (J.Block) enumEntry.getBody() + .accept(this, data); if (initializer != null) { initializer = initializer.withBody(body); @@ -574,7 +601,8 @@ public J visitExpression(KtExpression expression, ExecutionContext data) { if (!valueParameters.isEmpty()) { for (int i = 0; i < valueParameters.size(); i++) { KtParameter ktParameter = valueParameters.get(i); - J expr = ktParameter.accept(this, data).withPrefix(prefix(ktParameter)); + J expr = ktParameter.accept(this, data) + .withPrefix(prefix(ktParameter)); valueParams.add(maybeTrailingComma(ktParameter, padRight(expr, suffix(ktParameter)), i == valueParameters.size() - 1)); } } else if (ktFunctionLiteral.getArrow() != null) { @@ -612,7 +640,8 @@ public J visitFileAnnotationList(KtFileAnnotationList fileAnnotationList, Execut @Override public J visitFinallySection(KtFinallySection finallySection, ExecutionContext data) { - return finallySection.getFinalExpression().accept(this, data); + return finallySection.getFinalExpression() + .accept(this, data); } @Override @@ -620,9 +649,11 @@ public J visitFunctionType(KtFunctionType type, ExecutionContext data) { List> params; Set consumedSpaces = new HashSet<>(); - if (type.getParameters().isEmpty()) { + if (type.getParameters() + .isEmpty()) { params = singletonList(JRightPadded - .build(new J.Empty(randomId(), prefix(requireNonNull(requireNonNull(type.getParameterList()).getNode().findChildByType(KtTokens.RPAR)).getPsi()), Markers.EMPTY)) + .build(new J.Empty(randomId(), prefix(requireNonNull(requireNonNull(type.getParameterList()).getNode() + .findChildByType(KtTokens.RPAR)).getPsi()), Markers.EMPTY)) .withAfter(Space.EMPTY)); } else { params = new ArrayList<>(); @@ -694,7 +725,8 @@ public J visitInitializerList(KtInitializerList list, ExecutionContext data) { KtSuperTypeCallEntry superTypeCallEntry = (KtSuperTypeCallEntry) entries.get(0); JContainer args; - if (!superTypeCallEntry.getValueArguments().isEmpty()) { + if (!superTypeCallEntry.getValueArguments() + .isEmpty()) { args = mapValueArguments(superTypeCallEntry.getValueArgumentList(), data); } else { KtValueArgumentList ktArgList = superTypeCallEntry.getValueArgumentList(); @@ -739,9 +771,11 @@ public J visitIntersectionType(KtIntersectionType definitelyNotNullType, Executi public J visitIsExpression(KtIsExpression expression, ExecutionContext data) { Markers markers = Markers.EMPTY; - Expression element = convertToExpression(expression.getLeftHandSide().accept(this, data)); + Expression element = convertToExpression(expression.getLeftHandSide() + .accept(this, data)); - if (expression.getOperationReference().getReferencedNameElementType() == KtTokens.NOT_IS) { + if (expression.getOperationReference() + .getReferencedNameElementType() == KtTokens.NOT_IS) { markers = markers.addIfAbsent(new NotIs(randomId())); } @@ -775,7 +809,8 @@ public J visitLabeledExpression(KtLabeledExpression expression, ExecutionContext @Override public J visitLambdaExpression(KtLambdaExpression expression, ExecutionContext data) { KtFunctionLiteral functionLiteral = expression.getFunctionLiteral(); - return functionLiteral.accept(this, data).withPrefix(prefix(expression)); + return functionLiteral.accept(this, data) + .withPrefix(prefix(expression)); } @Override @@ -785,8 +820,12 @@ public J visitLiteralStringTemplateEntry(KtLiteralStringTemplateEntry entry, Exe } String value = maybeAdjustCRLF(entry); - boolean quoted = entry.getPrevSibling().getNode().getElementType() == KtTokens.OPEN_QUOTE && - entry.getNextSibling().getNode().getElementType() == KtTokens.CLOSING_QUOTE; + boolean quoted = entry.getPrevSibling() + .getNode() + .getElementType() == KtTokens.OPEN_QUOTE && + entry.getNextSibling() + .getNode() + .getElementType() == KtTokens.CLOSING_QUOTE; String valueSource = quoted ? "\"" + value + "\"" : value; @@ -826,8 +865,9 @@ public J visitNullableType(KtNullableType nullableType, ExecutionContext data) { TypeTree typeTree = (TypeTree) requireNonNull(innerType).accept(this, data); Set consumedSpaces = new HashSet<>(); if (innerType.getNextSibling() != null && - isSpace(innerType.getNextSibling().getNode()) && - !(innerType instanceof KtNullableType)) { + isSpace(innerType.getNextSibling() + .getNode()) && + !(innerType instanceof KtNullableType)) { consumedSpaces.add(innerType.getNextSibling()); } @@ -841,7 +881,8 @@ public J visitNullableType(KtNullableType nullableType, ExecutionContext data) { modifiers = ListUtils.mapFirst(modifiers, mod -> mod.withPrefix(merge(deepPrefix(nullableType.getModifierList()), mod.getPrefix()))); } - typeTree = ((K.FunctionType) typeTree).withModifiers(modifiers).withLeadingAnnotations(leadingAnnotations); + typeTree = ((K.FunctionType) typeTree).withModifiers(modifiers) + .withLeadingAnnotations(leadingAnnotations); } // Handle parentheses or potential nested parentheses @@ -879,7 +920,8 @@ public J visitNullableType(KtNullableType nullableType, ExecutionContext data) { merge(deepPrefix(nullableType), j.getPrefix()), Markers.EMPTY, emptyList(), - padRight(j, prefix(findFirstChild(nullableType, c -> c.getNode().getElementType() == KtTokens.QUEST))) + padRight(j, prefix(findFirstChild(nullableType, c -> c.getNode() + .getElementType() == KtTokens.QUEST))) ); } @@ -894,8 +936,10 @@ public J visitParameter(KtParameter parameter, ExecutionContext data) { Set consumedSpaces = preConsumedInfix(parameter); // todo, simplify this logic - int valOrVarOffset = parameter.getValOrVarKeyword() != null ? parameter.getValOrVarKeyword().getTextOffset() : -1; - int modifierOffset = parameter.getModifierList() != null ? parameter.getModifierList().getTextOffset() : -1; + int valOrVarOffset = parameter.getValOrVarKeyword() != null ? parameter.getValOrVarKeyword() + .getTextOffset() : -1; + int modifierOffset = parameter.getModifierList() != null ? parameter.getModifierList() + .getTextOffset() : -1; if (valOrVarOffset < modifierOffset) { if (parameter.getValOrVarKeyword() != null) { @@ -924,12 +968,14 @@ public J visitParameter(KtParameter parameter, ExecutionContext data) { J.Identifier name = createIdentifier(requireNonNull(parameter.getNameIdentifier()), vt, consumedSpaces); if (parameter.getTypeReference() != null) { - typeExpression = (TypeTree) parameter.getTypeReference().accept(this, data); + typeExpression = (TypeTree) parameter.getTypeReference() + .accept(this, data); // TODO: get type from IR of KtProperty. } JLeftPadded initializer = - parameter.getDefaultValue() != null ? padLeft(prefix(parameter.getEqualsToken()), convertToExpression(parameter.getDefaultValue().accept(this, data))) : null; + parameter.getDefaultValue() != null ? padLeft(prefix(parameter.getEqualsToken()), convertToExpression(parameter.getDefaultValue() + .accept(this, data))) : null; J.VariableDeclarations.NamedVariable namedVariable = new J.VariableDeclarations.NamedVariable( randomId(), @@ -1011,7 +1057,8 @@ public J visitPrimaryConstructor(KtPrimaryConstructor constructor, ExecutionCont null, null, new J.MethodDeclaration.IdentifierWithAnnotations( - name.withMarkers(name.getMarkers().addIfAbsent(new Implicit(randomId()))), + name.withMarkers(name.getMarkers() + .addIfAbsent(new Implicit(randomId()))), emptyList() ), params, @@ -1034,7 +1081,8 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat Set consumedSpaces = preConsumedInfix(accessor); JavaType.Method type = methodDeclarationType(accessor); - J.Identifier name = createIdentifier(accessor.getNamePlaceholder().getText(), + J.Identifier name = createIdentifier(accessor.getNamePlaceholder() + .getText(), prefix(accessor.getNamePlaceholder(), consumedSpaces), type); @@ -1044,11 +1092,10 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat throw new UnsupportedOperationException("TODO"); } - List> parameters = new ArrayList<>(); - for (KtParameter ktParameter : ktParameters) { - Statement stmt = convertToStatement(ktParameter.accept(this, data).withPrefix(prefix(ktParameter.getParent()))); - parameters.add(padRight(stmt, prefix(accessor.getRightParenthesis()))); - } + KtParameter ktParameter = ktParameters.get(0); + Statement stmt = convertToStatement(ktParameter.accept(this, data) + .withPrefix(prefix(ktParameter))); + List> parameters = singletonList(padRight(stmt, prefix(accessor.getRightParenthesis()))); params = JContainer.build(prefix(getLeftParenthesis(accessor)), parameters, Markers.EMPTY); } else { @@ -1061,17 +1108,21 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat if (accessor.getReturnTypeReference() != null) { markers = markers.addIfAbsent(new TypeReferencePrefix(randomId(), suffix(getRightParenthesis(accessor)))); - returnTypeExpression = accessor.getReturnTypeReference().accept(this, data).withPrefix(prefix(accessor.getReturnTypeReference())); + returnTypeExpression = accessor.getReturnTypeReference() + .accept(this, data) + .withPrefix(prefix(accessor.getReturnTypeReference())); } if (accessor.getBodyBlockExpression() != null) { - body = accessor.getBodyBlockExpression().accept(this, data).withPrefix(prefix(accessor.getBodyBlockExpression())); + body = accessor.getBodyBlockExpression() + .accept(this, data) + .withPrefix(prefix(accessor.getBodyBlockExpression())); } else if (accessor.getBodyExpression() != null) { body = convertToBlock(accessor.getBodyExpression(), data).withPrefix(prefix(accessor.getEqualsToken())); } else { params = JContainer.empty(); params = params.withBefore(Space.EMPTY) - .withMarkers(Markers.EMPTY.addIfAbsent(new OmitParentheses(randomId()))); + .withMarkers(Markers.EMPTY.addIfAbsent(new OmitParentheses(randomId()))); } return mapType(new J.MethodDeclaration( @@ -1118,14 +1169,16 @@ public J visitPropertyAccessor(KtPropertyAccessor accessor, ExecutionContext dat @Override public J visitQualifiedExpression(KtQualifiedExpression expression, ExecutionContext data) { - Expression receiver = convertToExpression(expression.getReceiverExpression().accept(this, data)); + Expression receiver = convertToExpression(expression.getReceiverExpression() + .accept(this, data)); Expression selector = convertToExpression(requireNonNull(expression.getSelectorExpression()).accept(this, data)); if (selector instanceof J.MethodInvocation) { J.MethodInvocation methodInvocation = (J.MethodInvocation) selector; return methodInvocation.getPadding() - .withSelect(padRight(receiver, suffix(expression.getReceiverExpression()))) - .withName(methodInvocation.getName().withPrefix(prefix(expression.getSelectorExpression()))) - .withPrefix(endFixPrefixAndInfix(expression)); + .withSelect(padRight(receiver, suffix(expression.getReceiverExpression()))) + .withName(methodInvocation.getName() + .withPrefix(prefix(expression.getSelectorExpression()))) + .withPrefix(endFixPrefixAndInfix(expression)); } else { J.Identifier identifier = (J.Identifier) selector; return mapType(new J.FieldAccess( @@ -1148,7 +1201,8 @@ public J visitReferenceExpression(KtReferenceExpression expression, ExecutionCon public J visitReturnExpression(KtReturnExpression expression, ExecutionContext data) { KtExpression returnedExpression = expression.getReturnedExpression(); Expression returnExpr = returnedExpression != null ? - convertToExpression(returnedExpression.accept(this, data).withPrefix(prefix(returnedExpression))) : + convertToExpression(returnedExpression.accept(this, data) + .withPrefix(prefix(returnedExpression))) : null; return new K.Return( randomId(), @@ -1158,19 +1212,22 @@ public J visitReturnExpression(KtReturnExpression expression, ExecutionContext d Markers.EMPTY, returnExpr ), - expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel().getIdentifier()), null) : null + expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel() + .getIdentifier()), null) : null ); } @Override public J visitSafeQualifiedExpression(KtSafeQualifiedExpression expression, ExecutionContext data) { J j = visitQualifiedExpression(expression, data); - return j.withMarkers(j.getMarkers().addIfAbsent(new IsNullSafe(randomId()))); + return j.withMarkers(j.getMarkers() + .addIfAbsent(new IsNullSafe(randomId()))); } @Override public J visitScript(KtScript script, ExecutionContext data) { - return script.getBlockExpression().accept(this, data); + return script.getBlockExpression() + .accept(this, data); } @Override @@ -1197,17 +1254,22 @@ public J visitSecondaryConstructor(KtSecondaryConstructor constructor, Execution Markers.EMPTY ); - K.ConstructorInvocation delegationCall = constructor.getDelegationCall().isImplicit() ? null : new K.ConstructorInvocation( + K.ConstructorInvocation delegationCall = constructor.getDelegationCall() + .isImplicit() ? null : new K.ConstructorInvocation( randomId(), prefix(constructor.getDelegationCall()), Markers.EMPTY, - createIdentifier(requireNonNull(constructor.getDelegationCall().getCalleeExpression()), type(constructor.getDelegationCall().getCalleeExpression())), - mapValueArguments(constructor.getDelegationCall().getValueArgumentList(), data) + createIdentifier(requireNonNull(constructor.getDelegationCall() + .getCalleeExpression()), type(constructor.getDelegationCall() + .getCalleeExpression())), + mapValueArguments(constructor.getDelegationCall() + .getValueArgumentList(), data) ); J.Block body = null; if (constructor.getBodyExpression() != null) { - body = (J.Block) constructor.getBodyExpression().accept(this, data); + body = (J.Block) constructor.getBodyExpression() + .accept(this, data); } J.MethodDeclaration methodDeclaration = mapType(new J.MethodDeclaration( @@ -1262,7 +1324,8 @@ public J visitSuperTypeEntry(KtSuperTypeEntry specifier, ExecutionContext data) J j = requireNonNull(specifier.getTypeReference()).accept(this, data); if (j instanceof J.Identifier) { J.Identifier ident = (J.Identifier) j; - if (!ident.getAnnotations().isEmpty()) { + if (!ident.getAnnotations() + .isEmpty()) { j = ident.withAnnotations(ListUtils.mapFirst(ident.getAnnotations(), a -> a.withPrefix(prefix(specifier.getParent())))); } else { j = ident.withPrefix(prefix(specifier)); @@ -1283,7 +1346,8 @@ public J visitThisExpression(KtThisExpression expression, ExecutionContext data) randomId(), deepPrefix(expression), Markers.EMPTY, - expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel().getIdentifier()), null) : null, + expression.getTargetLabel() != null ? createIdentifier(requireNonNull(expression.getTargetLabel() + .getIdentifier()), null) : null, type(expression) ); } @@ -1301,7 +1365,8 @@ public J visitThrowExpression(KtThrowExpression expression, ExecutionContext dat @Override public J visitTryExpression(KtTryExpression expression, ExecutionContext data) { List ktCatchClauses = expression.getCatchClauses(); - J.Block block = (J.Block) expression.getTryBlock().accept(this, data); + J.Block block = (J.Block) expression.getTryBlock() + .accept(this, data); List catches = new ArrayList<>(ktCatchClauses.size()); JLeftPadded finallyBlock = null; for (KtCatchClause catchClause : ktCatchClauses) { @@ -1309,7 +1374,8 @@ public J visitTryExpression(KtTryExpression expression, ExecutionContext data) { } if (expression.getFinallyBlock() != null) { - finallyBlock = padLeft(prefix(expression.getFinallyBlock()), (J.Block) expression.getFinallyBlock().accept(this, data)); + finallyBlock = padLeft(prefix(expression.getFinallyBlock()), (J.Block) expression.getFinallyBlock() + .accept(this, data)); } return new J.Try( @@ -1344,9 +1410,11 @@ public J visitTypeAlias(KtTypeAlias typeAlias, ExecutionContext data) { typeParams = JContainer.build(prefix(typeAlias.getTypeParameterList()), mapTypeParameters(typeAlias.getTypeParameterList(), data), Markers.EMPTY); } - Expression expr = convertToExpression(typeAlias.getTypeReference().accept(this, data)); + Expression expr = convertToExpression(typeAlias.getTypeReference() + .accept(this, data)); - ASTNode node = typeAlias.getNode().findChildByType(KtTokens.EQ); + ASTNode node = typeAlias.getNode() + .findChildByType(KtTokens.EQ); Space prefix = node != null ? prefix(node.getPsi()) : Space.EMPTY; return new K.TypeAlias( @@ -1418,7 +1486,8 @@ public J visitTypeParameter(KtTypeParameter parameter, ExecutionContext data) { if (parameter.getExtendsBound() != null) { bounds = JContainer.build(suffix(parameter.getNameIdentifier()), - singletonList(padRight((TypeTree) parameter.getExtendsBound().accept(this, data), + singletonList(padRight((TypeTree) parameter.getExtendsBound() + .accept(this, data), Space.EMPTY)), Markers.EMPTY); markers = markers.addIfAbsent(new TypeReferencePrefix(randomId(), Space.EMPTY)); @@ -1475,7 +1544,7 @@ public J visitTypeProjection(KtTypeProjection typeProjection, ExecutionContext d bounds = JContainer.build( prefix(typeProjection.getProjectionToken()), singletonList(padRight(requireNonNull(typeProjection.getTypeReference()).accept(this, data) - .withPrefix(prefix(typeProjection.getTypeReference())), Space.EMPTY)), + .withPrefix(prefix(typeProjection.getTypeReference())), Space.EMPTY)), Markers.EMPTY ); break; @@ -1562,7 +1631,7 @@ public J visitWhenConditionIsPattern(KtWhenConditionIsPattern condition, Executi @Override public J visitWhenConditionWithExpression(KtWhenConditionWithExpression condition, ExecutionContext data) { return requireNonNull(condition.getExpression()).accept(this, data) - .withPrefix(deepPrefix(condition)); + .withPrefix(deepPrefix(condition)); } @Override @@ -1597,8 +1666,10 @@ private JRightPadded maybeTrailingComma(KtElement element, JRightPadded controlParentheses = null; if (expression.getSubjectExpression() != null) { - J subject = expression.getSubjectExpression().accept(this, data); + J subject = expression.getSubjectExpression() + .accept(this, data); controlParentheses = new J.ControlParentheses<>( randomId(), prefix(expression.getLeftParenthesis()), @@ -1652,7 +1724,9 @@ public J visitWhileExpression(KtWhileExpression expression, ExecutionContext dat Markers.EMPTY, mapControlParentheses(requireNonNull(expression.getCondition()), data).withPrefix(prefix(expression.getLeftParenthesis())), expression.getBody() == null ? JRightPadded.build(new J.Empty(randomId(), suffix(expression.getRightParenthesis()), Markers.EMPTY)) : - JRightPadded.build(requireNonNull(expression.getBody()).accept(this, data).withPrefix(prefix(expression.getBody().getParent()))) + JRightPadded.build(requireNonNull(expression.getBody()).accept(this, data) + .withPrefix(prefix(expression.getBody() + .getParent()))) ); } @@ -1686,20 +1760,24 @@ public J visitKtFile(KtFile file, ExecutionContext data) { String shebang = null; Space spaceAfterShebang = null; PsiElement maybeShebang = file.getFirstChild(); - if (maybeShebang instanceof PsiComment && maybeShebang.getNode().getElementType() == KtTokens.SHEBANG_COMMENT) { + if (maybeShebang instanceof PsiComment && maybeShebang.getNode() + .getElementType() == KtTokens.SHEBANG_COMMENT) { shebang = maybeShebang.getText(); spaceAfterShebang = suffix(maybeShebang); } JRightPadded pkg = null; - if (!file.getPackageFqName().isRoot()) { + if (!file.getPackageFqName() + .isRoot()) { pkg = maybeTrailingSemicolon((J.Package) requireNonNull(file.getPackageDirective()).accept(this, data), file.getPackageDirective()); spaceAfterShebang = null; consumedSpaces.add(findFirstPrefixSpace(file.getPackageDirective())); } - List> imports = new ArrayList<>(file.getImportDirectives().size()); - if (!file.getImportDirectives().isEmpty()) { + List> imports = new ArrayList<>(file.getImportDirectives() + .size()); + if (!file.getImportDirectives() + .isEmpty()) { List importDirectives = file.getImportDirectives(); for (int i = 0; i < importDirectives.size(); i++) { KtImportDirective importDirective = importDirectives.get(i); @@ -1717,7 +1795,8 @@ public J visitKtFile(KtFile file, ExecutionContext data) { } } - List> statements = new ArrayList<>(file.getDeclarations().size()); + List> statements = new ArrayList<>(file.getDeclarations() + .size()); List declarations = file.getDeclarations(); for (KtDeclaration declaration : declarations) { Statement statement; @@ -1735,10 +1814,14 @@ public J visitKtFile(KtFile file, ExecutionContext data) { new J.Unknown.Source( randomId(), Space.EMPTY, - Markers.build(singletonList(ParseExceptionResult.build(KotlinParser.builder().build(), e) - .withTreeType(declaration.getClass().getName()))), - file.getText().substring(PsiUtilsKt.getStartOffsetSkippingComments(declaration), - declaration.getTextRange().getEndOffset()))); + Markers.build(singletonList(ParseExceptionResult.build(KotlinParser.builder() + .build(), e) + .withTreeType(declaration.getClass() + .getName()))), + file.getText() + .substring(PsiUtilsKt.getStartOffsetSkippingComments(declaration), + declaration.getTextRange() + .getEndOffset()))); } statements.add(maybeTrailingSemicolon(statement, declaration)); @@ -1767,7 +1850,8 @@ public J visitAnnotation(KtAnnotation annotation, ExecutionContext data) { Expression target; if (annotation.getUseSiteTarget() != null) { - target = (J.Identifier) annotation.getUseSiteTarget().accept(this, data); + target = (J.Identifier) annotation.getUseSiteTarget() + .accept(this, data); } else { target = new J.Empty(randomId(), Space.EMPTY, Markers.EMPTY); } @@ -1777,17 +1861,20 @@ public J visitAnnotation(KtAnnotation annotation, ExecutionContext data) { J.Annotation anno = null; for (KtAnnotationEntry ktAnnotationEntry : annotationEntries) { anno = (J.Annotation) ktAnnotationEntry.accept(this, data); - anno = anno.withMarkers(anno.getMarkers().addIfAbsent(new AnnotationConstructor(randomId()))); + anno = anno.withMarkers(anno.getMarkers() + .addIfAbsent(new AnnotationConstructor(randomId()))); rpAnnotations.add(padRight(anno, Space.EMPTY)); } - PsiElement maybeLBracket = findFirstChild(annotation, an -> an.getNode().getElementType() == KtTokens.LBRACKET); + PsiElement maybeLBracket = findFirstChild(annotation, an -> an.getNode() + .getElementType() == KtTokens.LBRACKET); boolean isImplicitBracket = maybeLBracket == null; Space beforeLBracket = isImplicitBracket ? Space.EMPTY : prefix(maybeLBracket); if (!isImplicitBracket) { rpAnnotations = ListUtils.mapLast(rpAnnotations, - rp -> rp.withAfter(prefix(findFirstChild(annotation, an -> an.getNode().getElementType() == KtTokens.RBRACKET)))); + rp -> rp.withAfter(prefix(findFirstChild(annotation, an -> an.getNode() + .getElementType() == KtTokens.RBRACKET)))); } NameTree annotationType; @@ -1828,8 +1915,10 @@ public J visitAnnotationEntry(KtAnnotationEntry annotationEntry, ExecutionContex nameTree = new K.AnnotationType(randomId(), Space.EMPTY, Markers.EMPTY, - padRight(convertToExpression(annotationEntry.getUseSiteTarget().accept(this, data)), - prefix(findFirstChild(annotationEntry, p -> p.getNode().getElementType() == KtTokens.COLON))), + padRight(convertToExpression(annotationEntry.getUseSiteTarget() + .accept(this, data)), + prefix(findFirstChild(annotationEntry, p -> p.getNode() + .getElementType() == KtTokens.COLON))), callee); } else { nameTree = (NameTree) requireNonNull(annotationEntry.getCalleeExpression()).accept(this, data); @@ -1853,11 +1942,13 @@ public J visitArgument(KtValueArgument argument, ExecutionContext data) { throw new UnsupportedOperationException("TODO"); } else if (argument.isNamed()) { J.Identifier name = createIdentifier(requireNonNull(argument.getArgumentName()), type(argument.getArgumentName())); - Expression expr = convertToExpression(argument.getArgumentExpression().accept(this, data)); + Expression expr = convertToExpression(argument.getArgumentExpression() + .accept(this, data)); if (argument.isSpread()) { expr = new K.SpreadArgument( randomId(), - prefix(findFirstChild(argument, c -> c.getNode().getElementType() == KtTokens.MUL)), + prefix(findFirstChild(argument, c -> c.getNode() + .getElementType() == KtTokens.MUL)), Markers.EMPTY, expr ); @@ -1871,7 +1962,8 @@ public J visitArgument(KtValueArgument argument, ExecutionContext data) { type(argument.getArgumentExpression()) )); } else if (argument.isSpread()) { - Expression j = (Expression) argument.getArgumentExpression().accept(this, data); + Expression j = (Expression) argument.getArgumentExpression() + .accept(this, data); return new K.SpreadArgument( randomId(), deepPrefix(argument), @@ -1880,8 +1972,11 @@ public J visitArgument(KtValueArgument argument, ExecutionContext data) { ); } - J j = argument.getArgumentExpression().accept(this, data).withPrefix(deepPrefix(argument)); - return argument instanceof KtLambdaArgument ? j.withMarkers(j.getMarkers().addIfAbsent(new TrailingLambdaArgument(randomId()))) : j; + J j = argument.getArgumentExpression() + .accept(this, data) + .withPrefix(deepPrefix(argument)); + return argument instanceof KtLambdaArgument ? j.withMarkers(j.getMarkers() + .addIfAbsent(new TrailingLambdaArgument(randomId()))) : j; } @Override @@ -1894,7 +1989,8 @@ public J visitBinaryExpression(KtBinaryExpression expression, ExecutionContext d J.AssignmentOperation.Type assignmentOperationType = javaBinaryType == null ? mapAssignmentOperationType(operationReference) : null; K.Binary.Type kotlinBinaryType = javaBinaryType == null && assignmentOperationType == null ? mapKBinaryType(operationReference) : null; - Expression left = convertToExpression(expression.getLeft().accept(this, data)).withPrefix(Space.EMPTY); + Expression left = convertToExpression(expression.getLeft() + .accept(this, data)).withPrefix(Space.EMPTY); Expression right = convertToExpression((expression.getRight()).accept(this, data)) .withPrefix(prefix(expression.getRight())); JavaType type = type(expression); @@ -1977,7 +2073,9 @@ public J visitBlockExpression(KtBlockExpression expression, ExecutionContext dat Space prefix = prefix(expression); Space blockPrefix = prefix; if (!hasBraces && !statements.isEmpty()) { - statements = ListUtils.mapFirst(statements, s -> s.withElement(s.getElement().withPrefix(merge(prefix, s.getElement().getPrefix())))); + statements = ListUtils.mapFirst(statements, s -> s.withElement(s.getElement() + .withPrefix(merge(prefix, s.getElement() + .getPrefix())))); blockPrefix = Space.EMPTY; } @@ -2001,10 +2099,13 @@ public J visitCallExpression(KtCallExpression expression, ExecutionContext data) if (type == PsiElementAssociations.ExpressionType.CONSTRUCTOR) { JavaType.Method mt = methodInvocationType(expression); - TypeTree name = (J.Identifier) expression.getCalleeExpression().accept(this, data); + TypeTree name = (J.Identifier) expression.getCalleeExpression() + .accept(this, data); name = name.withType(mt != null ? mt.getReturnType() : JavaType.Unknown.getInstance()); - if (!expression.getTypeArguments().isEmpty()) { - List> parameters = new ArrayList<>(expression.getTypeArguments().size()); + if (!expression.getTypeArguments() + .isEmpty()) { + List> parameters = new ArrayList<>(expression.getTypeArguments() + .size()); for (KtTypeProjection ktTypeProjection : expression.getTypeArguments()) { parameters.add(padRight(convertToExpression(ktTypeProjection.accept(this, data)), suffix(ktTypeProjection))); } @@ -2039,7 +2140,8 @@ public J visitCallExpression(KtCallExpression expression, ExecutionContext data) mt )); } else if (type == null || type == PsiElementAssociations.ExpressionType.METHOD_INVOCATION) { - J j = expression.getCalleeExpression().accept(this, data); + J j = expression.getCalleeExpression() + .accept(this, data); JRightPadded select = null; J.Identifier name; if (j instanceof J.Identifier) { @@ -2054,7 +2156,8 @@ public J visitCallExpression(KtCallExpression expression, ExecutionContext data) JContainer args = mapValueArgumentsMaybeWithTrailingLambda(expression.getValueArgumentList(), expression.getValueArguments(), data); if (expression.getValueArgumentList() == null) { - args = args.withMarkers(args.getMarkers().addIfAbsent(new OmitParentheses(randomId()))); + args = args.withMarkers(args.getMarkers() + .addIfAbsent(new OmitParentheses(randomId()))); } return mapType(new J.MethodInvocation( @@ -2068,7 +2171,8 @@ public J visitCallExpression(KtCallExpression expression, ExecutionContext data) methodInvocationType(expression) )); } else if (type == PsiElementAssociations.ExpressionType.QUALIFIER) { - TypeTree typeTree = (TypeTree) expression.getCalleeExpression().accept(this, data); + TypeTree typeTree = (TypeTree) expression.getCalleeExpression() + .accept(this, data); JContainer typeParams = mapTypeArguments(expression.getTypeArgumentList(), data); return mapType(new J.ParameterizedType( @@ -2080,7 +2184,8 @@ public J visitCallExpression(KtCallExpression expression, ExecutionContext data) type(expression) )); } else { - throw new UnsupportedOperationException("ExpressionType not found: " + expression.getCalleeExpression().getText()); + throw new UnsupportedOperationException("ExpressionType not found: " + expression.getCalleeExpression() + .getText()); } } @@ -2127,7 +2232,9 @@ public J visitConstantExpression(KtConstantExpression expression, ExecutionConte } else if (elementType == KtNodeTypes.BOOLEAN_CONSTANT) { value = ParseUtilsKt.parseBoolean(expression.getText()); } else if (elementType == KtNodeTypes.CHARACTER_CONSTANT) { - value = unescape(expression.getText().substring(1, expression.getText().length() - 1)); + value = unescape(expression.getText() + .substring(1, expression.getText() + .length() - 1)); } else if (elementType == KtNodeTypes.NULL) { value = null; } else { @@ -2232,7 +2339,8 @@ private J visitClass0(KtClass klass, ExecutionContext data) { J.Block body; if (klass.getBody() != null) { - body = (J.Block) klass.getBody().accept(this, data); + body = (J.Block) klass.getBody() + .accept(this, data); } else { body = new J.Block( randomId(), @@ -2245,7 +2353,8 @@ private J visitClass0(KtClass klass, ExecutionContext data) { } if (klass.getPrimaryConstructor() != null) { - primaryConstructor = (J.MethodDeclaration) klass.getPrimaryConstructor().accept(this, data); + primaryConstructor = (J.MethodDeclaration) klass.getPrimaryConstructor() + .accept(this, data); body = body.withStatements(ListUtils.concat(primaryConstructor, body.getStatements())); markers = markers.addIfAbsent(new PrimaryConstructor(randomId())); } @@ -2261,10 +2370,12 @@ private J visitClass0(KtClass klass, ExecutionContext data) { K.TypeConstraints typeConstraints = null; if (klass.getTypeConstraintList() != null) { - typeConstraints = (K.TypeConstraints) klass.getTypeConstraintList().accept(this, data); - PsiElement whereKeyword = requireNonNull(klass.getNode().findChildByType(KtTokens.WHERE_KEYWORD)).getPsi(); + typeConstraints = (K.TypeConstraints) klass.getTypeConstraintList() + .accept(this, data); + PsiElement whereKeyword = requireNonNull(klass.getNode() + .findChildByType(KtTokens.WHERE_KEYWORD)).getPsi(); typeConstraints = typeConstraints.withConstraints(ListUtils.mapFirst(typeConstraints.getConstraints(), constraint -> constraint.withPrefix(suffix(whereKeyword)))) - .withPrefix(prefix(whereKeyword)); + .withPrefix(prefix(whereKeyword)); } J.ClassDeclaration classDeclaration = new J.ClassDeclaration( @@ -2293,17 +2404,22 @@ public J visitClassBody(KtClassBody classBody, ExecutionContext data) { Space after = endFixPrefixAndInfix(classBody.getRBrace()); - if (!classBody.getEnumEntries().isEmpty()) { - List> enumValues = new ArrayList<>(classBody.getEnumEntries().size()); + if (!classBody.getEnumEntries() + .isEmpty()) { + List> enumValues = new ArrayList<>(classBody.getEnumEntries() + .size()); boolean terminatedWithSemicolon = false; - for (int i = 0; i < classBody.getEnumEntries().size(); i++) { - KtEnumEntry ktEnumEntry = classBody.getEnumEntries().get(i); + for (int i = 0; i < classBody.getEnumEntries() + .size(); i++) { + KtEnumEntry ktEnumEntry = classBody.getEnumEntries() + .get(i); PsiElement comma = PsiTreeUtil.findSiblingForward(requireNonNull(ktEnumEntry.getIdentifyingElement()), KtTokens.COMMA, null); PsiElement semicolon = PsiTreeUtil.findSiblingForward(ktEnumEntry.getIdentifyingElement(), KtTokens.SEMICOLON, null); JRightPadded rp = padRight((J.EnumValue) ktEnumEntry.accept(this, data), Space.EMPTY); - if (i == classBody.getEnumEntries().size() - 1) { + if (i == classBody.getEnumEntries() + .size() - 1) { if (semicolon != null) { terminatedWithSemicolon = true; } @@ -2316,7 +2432,8 @@ public J visitClassBody(KtClassBody classBody, ExecutionContext data) { afterComma = suffix(comma); } - rp = rp.withMarkers(rp.getMarkers().addIfAbsent(new TrailingComma(randomId(), afterComma))); + rp = rp.withMarkers(rp.getMarkers() + .addIfAbsent(new TrailingComma(randomId(), afterComma))); } else { if (semicolon != null) { rp = rp.withAfter(prefix(semicolon)); @@ -2380,7 +2497,8 @@ public J visitDestructuringDeclaration(KtDestructuringDeclaration multiDeclarati if (multiDeclaration.getInitializer() != null) { paddedInitializer = padLeft(suffix(multiDeclaration.getRPar()), - convertToExpression(multiDeclaration.getInitializer().accept(this, data)) + convertToExpression(multiDeclaration.getInitializer() + .accept(this, data)) .withPrefix(prefix(multiDeclaration.getInitializer()))); } @@ -2423,7 +2541,8 @@ public J visitDestructuringDeclaration(KtDestructuringDeclaration multiDeclarati TypeTree typeExpression = null; if (entry.getTypeReference() != null) { - typeExpression = (TypeTree) entry.getTypeReference().accept(this, data); + typeExpression = (TypeTree) entry.getTypeReference() + .accept(this, data); } J.VariableDeclarations variableDeclarations = new J.VariableDeclarations(randomId(), @@ -2479,12 +2598,14 @@ public J visitDotQualifiedExpression(KtDotQualifiedExpression expression, Execut if (expression.getSelectorExpression() instanceof KtCallExpression) { KtCallExpression callExpression = (KtCallExpression) expression.getSelectorExpression(); Space callExpressionPrefix = prefix(callExpression); - Expression receiver = convertToExpression(expression.getReceiverExpression().accept(this, data)); + Expression receiver = convertToExpression(expression.getReceiverExpression() + .accept(this, data)); J j = callExpression.accept(this, data); if (j instanceof J.Annotation) { J.Annotation a = (J.Annotation) j; - a = a.withAnnotationType(a.getAnnotationType().withPrefix(callExpressionPrefix)); + a = a.withAnnotationType(a.getAnnotationType() + .withPrefix(callExpressionPrefix)); J.FieldAccess newName = mapType(new J.FieldAccess( randomId(), receiver.getPrefix(), @@ -2493,10 +2614,12 @@ public J visitDotQualifiedExpression(KtDotQualifiedExpression expression, Execut padLeft(suffix(expression.getReceiverExpression()), (J.Identifier) a.getAnnotationType()), a.getType() )); - return a.withAnnotationType(newName).withPrefix(prefix); + return a.withAnnotationType(newName) + .withPrefix(prefix); } else if (j instanceof J.ParameterizedType) { J.ParameterizedType pt = (J.ParameterizedType) j; - pt = pt.withClazz(pt.getClazz().withPrefix(callExpressionPrefix)); + pt = pt.withClazz(pt.getClazz() + .withPrefix(callExpressionPrefix)); J.FieldAccess newName = mapType(new J.FieldAccess( randomId(), receiver.getPrefix(), @@ -2505,11 +2628,14 @@ public J visitDotQualifiedExpression(KtDotQualifiedExpression expression, Execut padLeft(suffix(expression.getReceiverExpression()), (J.Identifier) pt.getClazz()), pt.getType() )); - return mapType(pt.withClazz(newName).withPrefix(prefix)); + return mapType(pt.withClazz(newName) + .withPrefix(prefix)); } else if (j instanceof J.MethodInvocation) { J.MethodInvocation m = (J.MethodInvocation) j; - return m.getPadding().withSelect(padRight(receiver, suffix(expression.getReceiverExpression()))) - .withName(m.getName().withPrefix(callExpressionPrefix)) + return m.getPadding() + .withSelect(padRight(receiver, suffix(expression.getReceiverExpression()))) + .withName(m.getName() + .withPrefix(callExpressionPrefix)) .withPrefix(prefix); } else if (j instanceof J.NewClass) { J.NewClass n = (J.NewClass) j; @@ -2518,7 +2644,8 @@ public J visitDotQualifiedExpression(KtDotQualifiedExpression expression, Execut if (n.getClazz() instanceof J.ParameterizedType) { J.ParameterizedType pt = (J.ParameterizedType) n.getClazz(); if (pt != null) { - pt = pt.withClazz(pt.getClazz().withPrefix(callExpressionPrefix)); + pt = pt.withClazz(pt.getClazz() + .withPrefix(callExpressionPrefix)); J.FieldAccess newName = mapType(new J.FieldAccess( randomId(), receiver.getPrefix(), @@ -2543,25 +2670,31 @@ public J visitDotQualifiedExpression(KtDotQualifiedExpression expression, Execut padLeft(suffix(expression.getReceiverExpression()), id), id.getType() )); - n = n.withClazz(newName).withPrefix(prefix); + n = n.withClazz(newName) + .withPrefix(prefix); } } } return n; } - throw new UnsupportedOperationException("Unsupported call expression " + j.getClass().getName()); + throw new UnsupportedOperationException("Unsupported call expression " + j.getClass() + .getName()); } else if (expression.getSelectorExpression() instanceof KtNameReferenceExpression) { // Maybe need to type check before creating a field access. return mapType(new J.FieldAccess( randomId(), prefix, Markers.EMPTY, - convertToExpression(expression.getReceiverExpression().accept(this, data).withPrefix(Space.EMPTY)), - padLeft(suffix(expression.getReceiverExpression()), (J.Identifier) expression.getSelectorExpression().accept(this, data)), + convertToExpression(expression.getReceiverExpression() + .accept(this, data) + .withPrefix(Space.EMPTY)), + padLeft(suffix(expression.getReceiverExpression()), (J.Identifier) expression.getSelectorExpression() + .accept(this, data)), type(expression.getSelectorExpression()) )); } else { - throw new UnsupportedOperationException("Unsupported dot qualified selector: " + expression.getSelectorExpression().getClass()); + throw new UnsupportedOperationException("Unsupported dot qualified selector: " + expression.getSelectorExpression() + .getClass()); } } @@ -2584,13 +2717,15 @@ public J visitImportDirective(KtImportDirective importDirective, ExecutionContex JLeftPadded rpStatic = padLeft(Space.EMPTY, isStaticImport); KtImportAlias alias = importDirective.getAlias(); - ASTNode node = importDirective.getNode().findChildByType(KtTokens.IMPORT_KEYWORD); + ASTNode node = importDirective.getNode() + .findChildByType(KtTokens.IMPORT_KEYWORD); LeafPsiElement importPsi = (LeafPsiElement) node; PsiElement first = PsiTreeUtil.skipWhitespacesAndCommentsForward(importPsi); PsiElement last = findLastChild(importDirective, psi -> !(psi instanceof KtImportAlias) && - !isSpace(psi.getNode()) && - psi.getNode().getElementType() != KtTokens.SEMICOLON); + !isSpace(psi.getNode()) && + psi.getNode() + .getElementType() != KtTokens.SEMICOLON); String text = nodeRangeText(getNodeOrNull(first), getNodeOrNull(last)); TypeTree reference = TypeTree.build(text, '`'); @@ -2689,7 +2824,8 @@ private J visitNamedFunction0(KtNamedFunction function, ExecutionContext data) { if (ktParameters.isEmpty()) { params = JContainer.build(prefix(function.getValueParameterList()), singletonList(padRight(new J.Empty(randomId(), - prefix(function.getValueParameterList().getRightParenthesis()), + prefix(function.getValueParameterList() + .getRightParenthesis()), Markers.EMPTY), Space.EMPTY) ), Markers.EMPTY @@ -2700,19 +2836,20 @@ private J visitNamedFunction0(KtNamedFunction function, ExecutionContext data) { if (function.getReceiverTypeReference() != null) { markers = markers.addIfAbsent(new Extension(randomId())); - Expression receiver = convertToExpression(function.getReceiverTypeReference().accept(this, data)); + Expression receiver = convertToExpression(function.getReceiverTypeReference() + .accept(this, data)); JRightPadded infixReceiver = JRightPadded.build( - new J.VariableDeclarations.NamedVariable( - randomId(), - Space.EMPTY, - Markers.EMPTY.addIfAbsent(new Extension(randomId())), - createIdentifier("", Space.EMPTY, null, null), - emptyList(), - padLeft(Space.EMPTY, receiver), - null - ) - ) - .withAfter(suffix(function.getReceiverTypeReference())); + new J.VariableDeclarations.NamedVariable( + randomId(), + Space.EMPTY, + Markers.EMPTY.addIfAbsent(new Extension(randomId())), + createIdentifier("", Space.EMPTY, null, null), + emptyList(), + padLeft(Space.EMPTY, receiver), + null + ) + ) + .withAfter(suffix(function.getReceiverTypeReference())); J.VariableDeclarations implicitParam = new J.VariableDeclarations( randomId(), @@ -2725,31 +2862,39 @@ private J visitNamedFunction0(KtNamedFunction function, ExecutionContext data) { emptyList(), singletonList(infixReceiver) ); - implicitParam = implicitParam.withMarkers(implicitParam.getMarkers().addIfAbsent(new TypeReferencePrefix(randomId(), Space.EMPTY))); + implicitParam = implicitParam.withMarkers(implicitParam.getMarkers() + .addIfAbsent(new TypeReferencePrefix(randomId(), Space.EMPTY))); - List> newStatements = new ArrayList<>(params.getElements().size() + 1); + List> newStatements = new ArrayList<>(params.getElements() + .size() + 1); newStatements.add(JRightPadded.build(implicitParam)); - newStatements.addAll(params.getPadding().getElements()); - params = params.getPadding().withElements(newStatements); + newStatements.addAll(params.getPadding() + .getElements()); + params = params.getPadding() + .withElements(newStatements); } if (function.getTypeReference() != null) { markers = markers.addIfAbsent(new TypeReferencePrefix(randomId(), prefix(function.getColon()))); - returnTypeExpression = (TypeTree) function.getTypeReference().accept(this, data); + returnTypeExpression = (TypeTree) function.getTypeReference() + .accept(this, data); } K.TypeConstraints typeConstraints = null; if (function.getTypeConstraintList() != null) { - typeConstraints = (K.TypeConstraints) function.getTypeConstraintList().accept(this, data); - PsiElement whereKeyword = requireNonNull(function.getNode().findChildByType(KtTokens.WHERE_KEYWORD)).getPsi(); + typeConstraints = (K.TypeConstraints) function.getTypeConstraintList() + .accept(this, data); + PsiElement whereKeyword = requireNonNull(function.getNode() + .findChildByType(KtTokens.WHERE_KEYWORD)).getPsi(); typeConstraints = typeConstraints.withConstraints(ListUtils.mapFirst(typeConstraints.getConstraints(), constraint -> constraint.withPrefix(suffix(whereKeyword)))) - .withPrefix(prefix(whereKeyword)); + .withPrefix(prefix(whereKeyword)); } J.Block body; if (function.getBodyBlockExpression() != null) { - body = function.getBodyBlockExpression().accept(this, data) - .withPrefix(prefix(function.getBodyBlockExpression())); + body = function.getBodyBlockExpression() + .accept(this, data) + .withPrefix(prefix(function.getBodyBlockExpression())); } else if (function.getBodyExpression() != null) { body = convertToBlock(function.getBodyExpression(), data).withPrefix(prefix(function.getEqualsToken())); } else { @@ -2790,7 +2935,8 @@ private List> mapTypeParameters(KtTypeParameterLis @Override public J visitObjectLiteralExpression(KtObjectLiteralExpression expression, ExecutionContext data) { - J j = expression.getObjectDeclaration().accept(this, data); + J j = expression.getObjectDeclaration() + .accept(this, data); return j.withPrefix(merge(deepPrefix(expression), j.getPrefix())); } @@ -2827,9 +2973,11 @@ public J visitObjectDeclaration(KtObjectDeclaration declaration, ExecutionContex emptyList(), Space.EMPTY ); - body = body.withMarkers(body.getMarkers().addIfAbsent(new OmitBraces(randomId()))); + body = body.withMarkers(body.getMarkers() + .addIfAbsent(new OmitBraces(randomId()))); } else { - body = (J.Block) declaration.getBody().accept(this, data); + body = (J.Block) declaration.getBody() + .accept(this, data); } if (declaration.getObjectKeyword() != null) { @@ -2877,7 +3025,8 @@ public J visitObjectDeclaration(KtObjectDeclaration declaration, ExecutionContex randomId(), deepPrefix(directive), Markers.EMPTY, - (Expression) directive.getPackageNameExpression().accept(this, data), + (Expression) directive.getPackageNameExpression() + .accept(this, data), emptyList() ); } @@ -2897,7 +3046,9 @@ public J visitPrefixExpression(KtPrefixExpression expression, ExecutionContext d deepPrefix(expression), Markers.EMPTY, padLeft(prefix(expression.getOperationReference()), type), - expression.getBaseExpression().accept(this, data).withPrefix(suffix(expression.getOperationReference())), + expression.getBaseExpression() + .accept(this, data) + .withPrefix(suffix(expression.getOperationReference())), javaType )); } @@ -2913,7 +3064,8 @@ public J visitPostfixExpression(KtPostfixExpression expression, ExecutionContext type = ((JavaType.Variable) type).getType(); } J j = convertToExpression(requireNonNull(expression.getBaseExpression()).accept(this, data)); - IElementType referencedNameElementType = expression.getOperationReference().getReferencedNameElementType(); + IElementType referencedNameElementType = expression.getOperationReference() + .getReferencedNameElementType(); if (referencedNameElementType == KtTokens.EXCLEXCL) { j = mapType(new K.Unary(randomId(), deepPrefix(expression), Markers.EMPTY, padLeft(prefix(expression.getOperationReference()), K.Unary.Type.NotNull), (Expression) j, type)); } else if (referencedNameElementType == KtTokens.PLUSPLUS) { @@ -2951,7 +3103,9 @@ public J visitProperty(KtProperty property, ExecutionContext data) { // Receiver if (property.getReceiverTypeReference() != null) { - Expression receiverExp = convertToExpression(property.getReceiverTypeReference().accept(this, data).withPrefix(prefix(property.getReceiverTypeReference()))); + Expression receiverExp = convertToExpression(property.getReceiverTypeReference() + .accept(this, data) + .withPrefix(prefix(property.getReceiverTypeReference()))); receiver = padRight(receiverExp, suffix(property.getReceiverTypeReference())); markers = markers.addIfAbsent(new Extension(randomId())); } @@ -2959,11 +3113,14 @@ public J visitProperty(KtProperty property, ExecutionContext data) { JLeftPadded initializer = null; if (property.getInitializer() != null) { initializer = padLeft(prefix(property.getEqualsToken()), - convertToExpression(property.getInitializer().accept(this, data) - .withPrefix(prefix(property.getInitializer())))); + convertToExpression(property.getInitializer() + .accept(this, data) + .withPrefix(prefix(property.getInitializer())))); } else if (property.getDelegate() != null) { - Space afterByKeyword = prefix(property.getDelegate().getExpression()); - Expression initializerExp = convertToExpression(property.getDelegate().accept(this, data)).withPrefix(afterByKeyword); + Space afterByKeyword = prefix(property.getDelegate() + .getExpression()); + Expression initializerExp = convertToExpression(property.getDelegate() + .accept(this, data)).withPrefix(afterByKeyword); initializer = padLeft(prefix(property.getDelegate()), initializerExp); markers = markers.addIfAbsent(new By(randomId())); } @@ -3000,10 +3157,12 @@ public J visitProperty(KtProperty property, ExecutionContext data) { ); if (property.getTypeConstraintList() != null) { - typeConstraints = (K.TypeConstraints) property.getTypeConstraintList().accept(this, data); - PsiElement whereKeyword = requireNonNull(property.getNode().findChildByType(KtTokens.WHERE_KEYWORD)).getPsi(); + typeConstraints = (K.TypeConstraints) property.getTypeConstraintList() + .accept(this, data); + PsiElement whereKeyword = requireNonNull(property.getNode() + .findChildByType(KtTokens.WHERE_KEYWORD)).getPsi(); typeConstraints = typeConstraints.withConstraints(ListUtils.mapFirst(typeConstraints.getConstraints(), constraint -> constraint.withPrefix(suffix(whereKeyword)))) - .withPrefix(prefix(whereKeyword)); + .withPrefix(prefix(whereKeyword)); } List ktPropertyAccessors = property.getAccessors(); @@ -3055,7 +3214,8 @@ private List mapModifiers(@Nullable KtModifierList modifierList, // don't use iterator of `PsiTreeUtil.firstChild` and `getNextSibling`, since it could skip one layer, example test "paramAnnotation" // also don't use `modifierList.getChildren()` since it could miss some element - for (Iterator it = PsiUtilsKt.getAllChildren(modifierList).iterator(); it.hasNext(); ) { + for (Iterator it = PsiUtilsKt.getAllChildren(modifierList) + .iterator(); it.hasNext(); ) { PsiElement child = it.next(); if (isSpace(child.getNode())) { continue; @@ -3063,7 +3223,8 @@ private List mapModifiers(@Nullable KtModifierList modifierList, boolean isAnnotationEntry = child instanceof KtAnnotationEntry; boolean isAnnotation = child instanceof KtAnnotation; - boolean isKeyword = child instanceof LeafPsiElement && child.getNode().getElementType() instanceof KtModifierKeywordToken; + boolean isKeyword = child instanceof LeafPsiElement && child.getNode() + .getElementType() instanceof KtModifierKeywordToken; if (isAnnotationEntry) { KtAnnotationEntry ktAnnotationEntry = (KtAnnotationEntry) child; @@ -3101,8 +3262,9 @@ public J visitPropertyDelegate(KtPropertyDelegate delegate, ExecutionContext dat throw new UnsupportedOperationException("TODO"); } // Markers initMarkers = Markers.EMPTY.addIfAbsent(new By(randomId())); - return delegate.getExpression().accept(this, data) - .withPrefix(deepPrefix(delegate)); + return delegate.getExpression() + .accept(this, data) + .withPrefix(deepPrefix(delegate)); } @Override @@ -3116,12 +3278,14 @@ public J visitSimpleNameExpression(KtSimpleNameExpression expression, ExecutionC @Override public J visitStringTemplateExpression(KtStringTemplateExpression expression, ExecutionContext data) { KtStringTemplateEntry[] entries = expression.getEntries(); - boolean hasStringTemplateEntry = Arrays.stream(entries).anyMatch(x -> - x instanceof KtBlockStringTemplateEntry || - x instanceof KtSimpleNameStringTemplateEntry); + boolean hasStringTemplateEntry = Arrays.stream(entries) + .anyMatch(x -> + x instanceof KtBlockStringTemplateEntry || + x instanceof KtSimpleNameStringTemplateEntry); if (hasStringTemplateEntry) { - String delimiter = expression.getFirstChild().getText(); + String delimiter = expression.getFirstChild() + .getText(); List values = new ArrayList<>(entries.length); for (KtStringTemplateEntry entry : entries) { @@ -3139,8 +3303,9 @@ public J visitStringTemplateExpression(KtStringTemplateExpression expression, Ex } StringBuilder valueSb = new StringBuilder(); - Arrays.stream(entries).forEach(entry -> valueSb.append(maybeAdjustCRLF(entry)) - ); + Arrays.stream(entries) + .forEach(entry -> valueSb.append(maybeAdjustCRLF(entry)) + ); String valueSource = getString(expression, valueSb); @@ -3159,8 +3324,10 @@ private static String getString(KtStringTemplateExpression expression, StringBui PsiElement openQuote = expression.getFirstChild(); PsiElement closingQuota = expression.getLastChild(); if (openQuote == null || closingQuota == null || - openQuote.getNode().getElementType() != KtTokens.OPEN_QUOTE || - closingQuota.getNode().getElementType() != KtTokens.CLOSING_QUOTE) { + openQuote.getNode() + .getElementType() != KtTokens.OPEN_QUOTE || + closingQuota.getNode() + .getElementType() != KtTokens.CLOSING_QUOTE) { throw new UnsupportedOperationException("This should never happen"); } @@ -3208,7 +3375,8 @@ public J visitTypeReference(KtTypeReference typeReference, ExecutionContext data } else if (!modifiers.isEmpty()) { PsiElement first = findFirstNonSpaceChild(typeReference); if (first != null) { - if (first.getNode().getElementType() != KtTokens.LPAR) { + if (first.getNode() + .getElementType() != KtTokens.LPAR) { modifiers = ListUtils.mapFirst(modifiers, mod -> mod.withPrefix(prefix(typeReference))); consumedSpaces.add(findFirstPrefixSpace(typeReference)); } else { @@ -3223,11 +3391,15 @@ public J visitTypeReference(KtTypeReference typeReference, ExecutionContext data if (j instanceof K.FunctionType && typeReference.getModifierList() != null) { K.FunctionType functionType = (K.FunctionType) j; - functionType = functionType.withModifiers(modifiers).withLeadingAnnotations(leadingAnnotations); + functionType = functionType.withModifiers(modifiers) + .withLeadingAnnotations(leadingAnnotations); if (functionType.getReceiver() != null) { functionType = functionType.withReceiver( - functionType.getReceiver().withElement(functionType.getReceiver().getElement().withPrefix(functionType.getPrefix())) + functionType.getReceiver() + .withElement(functionType.getReceiver() + .getElement() + .withPrefix(functionType.getPrefix())) ); functionType = functionType.withPrefix(Space.EMPTY); @@ -3266,7 +3438,8 @@ public J visitTypeReference(KtTypeReference typeReference, ExecutionContext data Pair parenPair = parenPairs.pop(); PsiElement lPAR = allChildren.get(parenPair.getFirst()); PsiElement rPAR = allChildren.get(parenPair.getSecond()); - TypeTree typeTree = j instanceof K.FunctionType ? ((K.FunctionType) j).withReturnType(((K.FunctionType) j).getReturnType().withAfter(Space.EMPTY)) : (TypeTree) j; + TypeTree typeTree = j instanceof K.FunctionType ? ((K.FunctionType) j).withReturnType(((K.FunctionType) j).getReturnType() + .withAfter(Space.EMPTY)) : (TypeTree) j; j = new J.ParenthesizedTypeTree(randomId(), Space.EMPTY, Markers.EMPTY, @@ -3289,7 +3462,8 @@ public J visitUserType(KtUserType type, ExecutionContext data) { NameTree nameTree = name; if (type.getQualifier() != null) { - Expression select = convertToExpression(type.getQualifier().accept(this, data)).withPrefix(prefix(type.getQualifier())); + Expression select = convertToExpression(type.getQualifier() + .accept(this, data)).withPrefix(prefix(type.getQualifier())); nameTree = mapType(new J.FieldAccess(randomId(), Space.EMPTY, Markers.EMPTY, select, padLeft(suffix(type.getQualifier()), name), name.getType())); } @@ -3427,13 +3601,16 @@ private J.MethodInvocation mapFunctionCall(KtBinaryExpression expression, Execut .addIfAbsent(new Infix(randomId())) .addIfAbsent(new Extension(randomId())); - Expression selectExp = convertToExpression(requireNonNull(expression.getLeft()).accept(this, data).withPrefix(prefix(expression.getLeft()))); + Expression selectExp = convertToExpression(requireNonNull(expression.getLeft()).accept(this, data) + .withPrefix(prefix(expression.getLeft()))); JRightPadded select = padRight(selectExp, Space.EMPTY); - J.Identifier name = (J.Identifier) expression.getOperationReference().accept(this, data); // createIdentifier(operation, Space.EMPTY, methodInvocationType(expression)); + J.Identifier name = (J.Identifier) expression.getOperationReference() + .accept(this, data); // createIdentifier(operation, Space.EMPTY, methodInvocationType(expression)); List> expressions = new ArrayList<>(1); Markers paramMarkers = markers.addIfAbsent(new OmitParentheses(randomId())); - Expression rightExp = convertToExpression(requireNonNull(expression.getRight()).accept(this, data).withPrefix(prefix(expression.getRight()))); + Expression rightExp = convertToExpression(requireNonNull(expression.getRight()).accept(this, data) + .withPrefix(prefix(expression.getRight()))); JRightPadded padded = padRight(rightExp, suffix(expression.getRight())); expressions.add(padded); JContainer args = JContainer.build(Space.EMPTY, expressions, paramMarkers); @@ -3464,7 +3641,8 @@ private J.ControlParentheses buildIfCondition(KtIfExpression express private JRightPadded buildIfThenPart(KtIfExpression expression) { // TODO: fix NPE. return padRight(convertToStatement(requireNonNull(expression.getThen()).accept(this, executionContext)) - .withPrefix(prefix(expression.getThen().getParent())), + .withPrefix(prefix(expression.getThen() + .getParent())), Space.EMPTY); } @@ -3477,7 +3655,8 @@ private JRightPadded buildIfThenPart(KtIfExpression expression) { randomId(), prefix(expression.getElseKeyword()), Markers.EMPTY, - padRight(convertToStatement(expression.getElse().accept(this, executionContext)) + padRight(convertToStatement(expression.getElse() + .accept(this, executionContext)) .withPrefix(suffix(expression.getElseKeyword())), Space.EMPTY) ); } @@ -3537,9 +3716,13 @@ private J2 mapType(J2 tree) { private J.Annotation mapType(J.Annotation tree) { J.Annotation a = tree; - if (isNotFullyQualified(tree.getAnnotationType().getType())) { - if (a.getAnnotationType().getType() instanceof JavaType.Method) { - a = a.withAnnotationType(a.getAnnotationType().withType(((JavaType.Method) a.getAnnotationType().getType()).getReturnType())); + if (isNotFullyQualified(tree.getAnnotationType() + .getType())) { + if (a.getAnnotationType() + .getType() instanceof JavaType.Method) { + a = a.withAnnotationType(a.getAnnotationType() + .withType(((JavaType.Method) a.getAnnotationType() + .getType()).getReturnType())); } } return a; @@ -3593,17 +3776,20 @@ private J.FieldAccess mapType(J.FieldAccess tree) { } private J.MethodDeclaration mapType(J.MethodDeclaration tree) { - return tree.withName(tree.getName().withType(tree.getMethodType())); + return tree.withName(tree.getName() + .withType(tree.getMethodType())); } private J.MethodInvocation mapType(J.MethodInvocation tree) { - return tree.withName(tree.getName().withType(tree.getMethodType())); + return tree.withName(tree.getName() + .withType(tree.getMethodType())); } private J.NewClass mapType(J.NewClass tree) { J.NewClass n = tree; if (n.getClazz() instanceof J.Identifier) { - if (n.getClazz().getType() instanceof JavaType.Parameterized) { + if (n.getClazz() + .getType() instanceof JavaType.Parameterized) { J.Identifier clazz = (J.Identifier) n.getClazz(); n = n.withClazz(clazz.withType(((JavaType.Parameterized) clazz.getType()).getType())); } @@ -3620,8 +3806,11 @@ private J.ParameterizedType mapType(J.ParameterizedType tree) { } } } - if (p.getClazz() != null && p.getClazz().getType() instanceof JavaType.Parameterized) { - p = p.withClazz(p.getClazz().withType(((JavaType.Parameterized) p.getClazz().getType()).getType())); + if (p.getClazz() != null && p.getClazz() + .getType() instanceof JavaType.Parameterized) { + p = p.withClazz(p.getClazz() + .withType(((JavaType.Parameterized) p.getClazz() + .getType()).getType())); } return p; } @@ -3681,7 +3870,8 @@ private J.Identifier createIdentifier(PsiElement name, @Nullable JavaType type) } private J.Identifier createIdentifier(PsiElement name, @Nullable JavaType type, @Nullable Set consumedSpaces) { - return createIdentifier(name.getNode().getText(), prefix(name, consumedSpaces), type); + return createIdentifier(name.getNode() + .getText(), prefix(name, consumedSpaces), type); } private J.Identifier createIdentifier(String name, Space prefix, @@ -3712,7 +3902,8 @@ private J.Identifier createIdentifier(String name, Space prefix, } private static J.Identifier addPrefixInFront(J.Identifier id, Space prefix) { - if (!id.getAnnotations().isEmpty()) { + if (!id.getAnnotations() + .isEmpty()) { id = id.withAnnotations(ListUtils.mapFirst(id.getAnnotations(), anno -> anno.withPrefix(merge(prefix, anno.getPrefix())))); } else { id = id.withPrefix(merge(prefix, id.getPrefix())); @@ -3737,7 +3928,7 @@ private J.Block convertToBlock(KtExpression ktExpression, ExecutionContext data) randomId(), Space.EMPTY, Markers.EMPTY.addIfAbsent(new OmitBraces(randomId())) - .addIfAbsent(new SingleExpressionBlock(randomId())), + .addIfAbsent(new SingleExpressionBlock(randomId())), JRightPadded.build(false), singletonList(JRightPadded.build(return_)), Space.EMPTY @@ -3831,7 +4022,8 @@ private Space prefix(@Nullable PsiElement element, @Nullable Set con private static List getAllChildren(PsiElement psiElement) { List allChildren = new ArrayList<>(); - Iterator iterator = PsiUtilsKt.getAllChildren(psiElement).iterator(); + Iterator iterator = PsiUtilsKt.getAllChildren(psiElement) + .iterator(); while (iterator.hasNext()) { PsiElement it = iterator.next(); allChildren.add(it); @@ -3849,7 +4041,8 @@ private static List getAllChildren(PsiElement psiElement) { return null; } - while (pre.getPrevSibling() != null && isSpace(pre.getPrevSibling().getNode())) { + while (pre.getPrevSibling() != null && isSpace(pre.getPrevSibling() + .getNode())) { pre = pre.getPrevSibling(); } @@ -3861,7 +4054,8 @@ private static List getAllChildren(PsiElement psiElement) { return null; } - Iterator iterator = PsiUtilsKt.getAllChildren(element).iterator(); + Iterator iterator = PsiUtilsKt.getAllChildren(element) + .iterator(); PsiElement first = iterator.next(); if (first != null) { @@ -3934,10 +4128,10 @@ private Space prefixAndInfix(@Nullable PsiElement element, @Nullable Set mapAnnotations(List ktAnnotationEntries, ExecutionContext data) { return ktAnnotationEntries.stream() - .map(annotation -> (J.Annotation) annotation.accept(this, data)) - .collect(toList()); + .map(annotation -> (J.Annotation) annotation.accept(this, data)) + .collect(toList()); } private J mapDestructuringDeclaration(KtDestructuringDeclaration ktDestructuringDeclaration, ExecutionContext data) { @@ -4104,10 +4298,12 @@ private List> mapParameters(@Nullable KtParameterList li if (superTypeListEntry instanceof KtSuperTypeCallEntry) { KtSuperTypeCallEntry superTypeCallEntry = (KtSuperTypeCallEntry) superTypeListEntry; - TypeTree typeTree = (TypeTree) superTypeCallEntry.getCalleeExpression().accept(this, data); + TypeTree typeTree = (TypeTree) superTypeCallEntry.getCalleeExpression() + .accept(this, data); JContainer args; - if (!superTypeCallEntry.getValueArguments().isEmpty()) { + if (!superTypeCallEntry.getValueArguments() + .isEmpty()) { args = mapValueArguments(superTypeCallEntry.getValueArgumentList(), data); } else { KtValueArgumentList ktArgList = superTypeCallEntry.getValueArgumentList(); @@ -4119,7 +4315,8 @@ private List> mapParameters(@Nullable KtParameterList li } if (i == 0) { - if (typeTree instanceof J.Identifier && !((J.Identifier) typeTree).getAnnotations().isEmpty()) { + if (typeTree instanceof J.Identifier && !((J.Identifier) typeTree).getAnnotations() + .isEmpty()) { J.Identifier ident = (J.Identifier) typeTree; typeTree = ident.withAnnotations(ListUtils.mapFirst(ident.getAnnotations(), a -> a.withPrefix(prefix(superTypeListEntry.getParent())))); } else { @@ -4136,11 +4333,12 @@ private List> mapParameters(@Nullable KtParameterList li ); superTypes.add(padRight(delegationCall, suffix(superTypeCallEntry))); } else if (superTypeListEntry instanceof KtSuperTypeEntry || - superTypeListEntry instanceof KtDelegatedSuperTypeEntry) { + superTypeListEntry instanceof KtDelegatedSuperTypeEntry) { TypeTree typeTree = (TypeTree) superTypeListEntry.accept(this, data); if (i == 0) { - if (typeTree instanceof J.Identifier && !((J.Identifier) typeTree).getAnnotations().isEmpty()) { + if (typeTree instanceof J.Identifier && !((J.Identifier) typeTree).getAnnotations() + .isEmpty()) { J.Identifier ident = (J.Identifier) typeTree; typeTree = ident.withAnnotations(ListUtils.mapFirst(ident.getAnnotations(), a -> a.withPrefix(prefix(superTypeListEntry.getParent())))); } else { @@ -4167,7 +4365,8 @@ private JContainer mapValueArgumentsMaybeWithTrailingLambda(@Nullabl List> expressions = new ArrayList<>(ktValueArguments.size()); Markers markers = Markers.EMPTY; - if (valueArgumentList != null && valueArgumentList.getArguments().isEmpty()) { + if (valueArgumentList != null && valueArgumentList.getArguments() + .isEmpty()) { Expression arg = new J.Empty(randomId(), prefix(valueArgumentList.getRightParenthesis()), Markers.EMPTY); expressions.add(padRight(arg, Space.EMPTY)); } @@ -4177,7 +4376,8 @@ private JContainer mapValueArgumentsMaybeWithTrailingLambda(@Nullabl Expression expr = convertToExpression(ktValueArgument.accept(this, data)); Markers rpMarkers = Markers.EMPTY; - if (valueArgumentList != null && i == valueArgumentList.getArguments().size() - 1) { + if (valueArgumentList != null && i == valueArgumentList.getArguments() + .size() - 1) { PsiElement maybeTrailingComma = findTrailingComma(ktValueArgument); if (maybeTrailingComma != null) { rpMarkers = rpMarkers.addIfAbsent(new TrailingComma(randomId(), suffix(maybeTrailingComma))); @@ -4223,11 +4423,12 @@ private Space toSpace(@Nullable PsiElement element) { return Space.EMPTY; } - IElementType elementType = element.getNode().getElementType(); + IElementType elementType = element.getNode() + .getElementType(); if (elementType == KtTokens.WHITE_SPACE) { return Space.build(maybeAdjustCRLF(element), emptyList()); } else if (elementType == KtTokens.EOL_COMMENT || - elementType == KtTokens.BLOCK_COMMENT) { + elementType == KtTokens.BLOCK_COMMENT) { String nodeText = maybeAdjustCRLF(element); boolean isBlockComment = ((PsiComment) element).getTokenType() == KtTokens.BLOCK_COMMENT; String comment = isBlockComment ? nodeText.substring(2, nodeText.length() - 2) : nodeText.substring(2); @@ -4264,7 +4465,8 @@ private String maybeAdjustCRLF(PsiElement element) { private Space kdocToSpace(KDoc kDoc) { StringBuilder sb = new StringBuilder(); - Iterator iterator = PsiUtilsKt.getAllChildren(kDoc).iterator(); + Iterator iterator = PsiUtilsKt.getAllChildren(kDoc) + .iterator(); while (iterator.hasNext()) { PsiElement it = iterator.next(); String text = it.getText(); @@ -4286,7 +4488,8 @@ private Space kdocToSpace(KDoc kDoc) { private String KDocSectionToString(KDocSection kDocSection) { StringBuilder sb = new StringBuilder(); - Iterator iterator = PsiUtilsKt.getAllChildren(kDocSection).iterator(); + Iterator iterator = PsiUtilsKt.getAllChildren(kDocSection) + .iterator(); while (iterator.hasNext()) { PsiElement it = iterator.next(); String text = it.getText(); @@ -4335,7 +4538,8 @@ public static Space merge(@Nullable Space s1, @Nullable Space s2) { return s1; } - if (s1.getComments().isEmpty()) { + if (s1.getComments() + .isEmpty()) { return Space.build(s1.getWhitespace() + s2.getWhitespace(), s2.getComments()); } else { List newComments = ListUtils.mapLast(s1.getComments(), c -> c.withSuffix(c.getSuffix() + s2.getWhitespace())); @@ -4345,7 +4549,8 @@ public static Space merge(@Nullable Space s1, @Nullable Space s2) { } private static J.Identifier mergePrefix(Space prefix, J.Identifier id) { - return id.getAnnotations().isEmpty() ? id.withPrefix(merge(prefix, id.getPrefix())) : + return id.getAnnotations() + .isEmpty() ? id.withPrefix(merge(prefix, id.getPrefix())) : id.withAnnotations(ListUtils.mapFirst(id.getAnnotations(), ann -> ann.withPrefix(merge(prefix, ann.getPrefix())))); } @@ -4427,7 +4632,8 @@ private static Set preConsumedInfix(PsiElement element) { private @Nullable PsiElement findTrailingComma(PsiElement element) { PsiElement nextSibling = element.getNextSibling(); while (nextSibling != null) { - if (nextSibling.getNode().getElementType() == KtTokens.COMMA) { + if (nextSibling.getNode() + .getElementType() == KtTokens.COMMA) { return nextSibling; } nextSibling = nextSibling.getNextSibling();