From 5a30966253e9f5ded35b26d2b9fbeeaf7d733e68 Mon Sep 17 00:00:00 2001 From: traceyyoshima Date: Mon, 9 Oct 2023 12:17:11 -0600 Subject: [PATCH 1/2] Fixed variable owner names. Added signature builder tests for top level properties and functions. --- .../org/openrewrite/kotlin/KotlinTypeGoat.kt | 4 +++- .../kotlin/KotlinTypeSignatureBuilder.kt | 2 ++ .../kotlin/KotlinTypeSignatureBuilderTest.java | 18 ++++++++++++++++++ src/test/resources/KotlinTypeGoat.kt | 4 +++- 4 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/main/java/org/openrewrite/kotlin/KotlinTypeGoat.kt b/src/main/java/org/openrewrite/kotlin/KotlinTypeGoat.kt index 01c7ba124..7a5b30c20 100644 --- a/src/main/java/org/openrewrite/kotlin/KotlinTypeGoat.kt +++ b/src/main/java/org/openrewrite/kotlin/KotlinTypeGoat.kt @@ -20,7 +20,9 @@ package org.openrewrite.kotlin import java.lang.Object -// TODO: FIX ME. Files needs to declare fields and methods to assert type mapping. +const val field = 10 +fun function() {} + @AnnotationWithRuntimeRetention @AnnotationWithSourceRetention abstract class KotlinTypeGoat where S: PT, S: C { diff --git a/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt b/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt index 4dc7023ef..dca07a095 100644 --- a/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt +++ b/src/main/kotlin/org/openrewrite/kotlin/KotlinTypeSignatureBuilder.kt @@ -577,6 +577,8 @@ class KotlinTypeSignatureBuilder(private val firSession: FirSession) : JavaTypeS } } else if (ownerSymbol is FirFunctionSymbol<*>) { owner = methodDeclarationSignature(ownerSymbol, null) + } else if (ownerSymbol is FirFileSymbol) { + owner = convertFileNameToFqn(ownerSymbol.fir.name) } else if (ownerSymbol != null) { owner = classSignature(ownerSymbol.fir) } diff --git a/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java b/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java index 46b001852..9db4a54f0 100644 --- a/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java +++ b/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java @@ -159,6 +159,24 @@ public String methodSignature(String methodName) { .getSymbol(), null); } + @Test + void fileField() { + FirProperty firProperty = getCompiledSource().getDeclarations().stream() + .filter(it -> it instanceof FirProperty && "field".equals(((FirProperty) it).getName().asString())) + .map(it -> (FirProperty) it).findFirst().orElseThrow(); + assertThat(signatureBuilder().variableSignature(firProperty.getSymbol(), getCompiledSource().getSymbol())) + .isEqualTo("KotlinTypeGoatKt{name=field,type=kotlin.Int}"); + } + + @Test + void fileFunction() { + FirSimpleFunction function = getCompiledSource().getDeclarations().stream() + .filter(it -> it instanceof FirSimpleFunction && "function".equals(((FirSimpleFunction) it).getName().asString())) + .map(it -> (FirSimpleFunction) it).findFirst().orElseThrow(); + assertThat(signatureBuilder().methodDeclarationSignature(function.getSymbol(), getCompiledSource().getSymbol())) + .isEqualTo("KotlinTypeGoatKt{name=function,return=kotlin.Unit,parameters=[]}"); + } + @Test void constructor() { assertThat(constructorSignature()) diff --git a/src/test/resources/KotlinTypeGoat.kt b/src/test/resources/KotlinTypeGoat.kt index f9cda887f..7bf152c75 100644 --- a/src/test/resources/KotlinTypeGoat.kt +++ b/src/test/resources/KotlinTypeGoat.kt @@ -20,7 +20,9 @@ package org.openrewrite.kotlin import java.lang.Object -// TODO: FIX ME. Files needs to declare fields and methods to assert type mapping. +const val field = 10 +fun function() {} + @AnnotationWithRuntimeRetention @AnnotationWithSourceRetention abstract class KotlinTypeGoat where S: PT, S: C { From 900c6d72dd7066961b440b4a5ace18a270710cd0 Mon Sep 17 00:00:00 2001 From: traceyyoshima Date: Mon, 9 Oct 2023 12:44:07 -0600 Subject: [PATCH 2/2] Added type mapping tests for top level fields and methods. --- .../kotlin/KotlinTypeMappingTest.java | 52 +++++++++++++++---- .../KotlinTypeSignatureBuilderTest.java | 23 +++++--- 2 files changed, 57 insertions(+), 18 deletions(-) diff --git a/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java b/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java index fe032c51f..3a5e77289 100644 --- a/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java +++ b/src/test/java/org/openrewrite/kotlin/KotlinTypeMappingTest.java @@ -15,10 +15,13 @@ */ package org.openrewrite.kotlin; +import org.jetbrains.kotlin.fir.declarations.FirProperty; +import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction; import org.junit.jupiter.api.Nested; import org.junit.jupiter.api.Test; import org.openrewrite.InMemoryExecutionContext; import org.openrewrite.Issue; +import org.openrewrite.Parser; import org.openrewrite.internal.StringUtils; import org.openrewrite.java.MethodMatcher; import org.openrewrite.java.tree.Flag; @@ -28,9 +31,13 @@ import org.openrewrite.kotlin.tree.K; import org.openrewrite.test.RewriteTest; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.nio.file.Paths; import java.util.List; import java.util.concurrent.atomic.AtomicBoolean; +import static java.util.Collections.singletonList; import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; import static org.openrewrite.ExecutionContext.REQUIRE_PRINT_EQUALS_INPUT; @@ -40,26 +47,26 @@ @SuppressWarnings("ConstantConditions") public class KotlinTypeMappingTest { private static final String goat = StringUtils.readFully(KotlinTypeMappingTest.class.getResourceAsStream("/KotlinTypeGoat.kt")); - + private static final K.CompilationUnit cu; private static final K.ClassDeclaration goatClassDeclaration; static { InMemoryExecutionContext ctx = new InMemoryExecutionContext(); ctx.putMessage(REQUIRE_PRINT_EQUALS_INPUT, false); - //noinspection OptionalGetWithoutIsPresent - goatClassDeclaration = requireNonNull(((K.CompilationUnit) KotlinParser.builder() - .logCompilationWarningsAndErrors(true) - .build() - .parse(ctx, goat) - .findFirst() - .get()) + cu = (K.CompilationUnit) KotlinParser.builder() + .logCompilationWarningsAndErrors(true) + .build() + .parseInputs(singletonList(new Parser.Input(Paths.get("KotlinTypeGoat.kt"), () -> new ByteArrayInputStream(goat.getBytes(StandardCharsets.UTF_8)))), null, ctx) + .findFirst() + .orElseThrow(); + + goatClassDeclaration = cu .getStatements() .stream() .filter(K.ClassDeclaration.class::isInstance) .findFirst() .map(K.ClassDeclaration.class::cast) - .orElseThrow() - ); + .orElseThrow(); } private static final JavaType.Parameterized goatType = @@ -128,6 +135,31 @@ void fieldType() { assertThat(property.getSetter().getMethodType().toString().substring(declaringType.toString().length())).isEqualTo("{name=accessor,return=kotlin.Unit,parameters=[kotlin.Int]}"); } + @Test + void fileField() { + J.VariableDeclarations.NamedVariable nv = cu.getStatements().stream() + .filter(it -> it instanceof J.VariableDeclarations) + .flatMap(it -> ((J.VariableDeclarations) it).getVariables().stream()) + .filter(it -> "field".equals(it.getSimpleName())).findFirst().orElseThrow(); + + assertThat(nv.getName().getType().toString()).isEqualTo("kotlin.Int"); + assertThat(nv.getName().getFieldType()).isEqualTo(nv.getVariableType()); + assertThat(nv.getVariableType().toString()) + .isEqualTo("KotlinTypeGoatKt{name=field,type=kotlin.Int}"); + } + + @Test + void fileFunction() { + J.MethodDeclaration md = cu.getStatements().stream() + .filter(it -> it instanceof J.MethodDeclaration) + .map(J.MethodDeclaration.class::cast) + .filter(it -> "function".equals(it.getSimpleName())).findFirst().orElseThrow(); + + assertThat(md.getName().getType()).isEqualTo(md.getMethodType()); + assertThat(md.getMethodType().toString()) + .isEqualTo("KotlinTypeGoatKt{name=function,return=kotlin.Unit,parameters=[]}"); + } + @Test void kotlinAnyHasNoSuperType() { assertThat(goatType.getSupertype().getSupertype()).isNull(); diff --git a/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java b/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java index 9db4a54f0..b7bef395b 100644 --- a/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java +++ b/src/test/java/org/openrewrite/kotlin/KotlinTypeSignatureBuilderTest.java @@ -44,7 +44,7 @@ public class KotlinTypeSignatureBuilderTest { .moduleName("test") .build() .parse(singletonList(new Parser.Input(Paths.get("KotlinTypeGoat.kt"), () -> new ByteArrayInputStream(goat.getBytes(StandardCharsets.UTF_8)))), disposable, - new ParsingExecutionContextView(new InMemoryExecutionContext(Throwable::printStackTrace)));; + new ParsingExecutionContextView(new InMemoryExecutionContext(Throwable::printStackTrace))); @AfterAll static void afterAll() { @@ -63,6 +63,7 @@ private FirFile getCompiledSource() { public String constructorSignature() { return signatureBuilder().methodDeclarationSignature(getCompiledSource().getDeclarations().stream() + .filter(FirRegularClass.class::isInstance) .map(FirRegularClass.class::cast) .flatMap(it -> it.getDeclarations().stream()) .filter(FirConstructor.class::isInstance) @@ -74,6 +75,7 @@ public String constructorSignature() { public Object innerClassSignature(String innerClassSimpleName) { return signatureBuilder().signature(getCompiledSource().getDeclarations().stream() + .filter(FirRegularClass.class::isInstance) .map(FirRegularClass.class::cast) .flatMap(it -> it.getDeclarations().stream()) .filter(FirRegularClass.class::isInstance) @@ -86,6 +88,7 @@ public Object innerClassSignature(String innerClassSimpleName) { public String fieldSignature(String field) { return signatureBuilder().variableSignature(getCompiledSource().getDeclarations().stream() + .filter(FirRegularClass.class::isInstance) .map(FirRegularClass.class::cast) .flatMap(it -> it.getDeclarations().stream()) .filter(FirProperty.class::isInstance) @@ -99,13 +102,14 @@ public String fieldSignature(String field) { @Nullable public FirProperty getProperty(String field) { return getCompiledSource().getDeclarations().stream() - .map(FirRegularClass.class::cast) - .flatMap(it -> it.getDeclarations().stream()) - .filter(FirProperty.class::isInstance) - .map(FirProperty.class::cast) - .filter(it -> field.equals(it.getName().asString())) - .findFirst() - .orElse(null); + .filter(FirRegularClass.class::isInstance) + .map(FirRegularClass.class::cast) + .flatMap(it -> it.getDeclarations().stream()) + .filter(FirProperty.class::isInstance) + .map(FirProperty.class::cast) + .filter(it -> field.equals(it.getName().asString())) + .findFirst() + .orElse(null); } public String fieldPropertyGetterSignature(String field) { @@ -126,6 +130,7 @@ public String fieldPropertySetterSignature(String field) { public Object firstMethodParameterSignature(String methodName) { return signatureBuilder().signature(getCompiledSource().getDeclarations().stream() + .filter(FirRegularClass.class::isInstance) .map(FirRegularClass.class::cast) .flatMap(it -> it.getDeclarations().stream()) .filter(FirSimpleFunction.class::isInstance) @@ -140,6 +145,7 @@ public Object firstMethodParameterSignature(String methodName) { public Object lastClassTypeParameter() { return signatureBuilder().signature(getCompiledSource().getDeclarations().stream() + .filter(FirRegularClass.class::isInstance) .map(FirRegularClass.class::cast) .findFirst() .orElseThrow() @@ -149,6 +155,7 @@ public Object lastClassTypeParameter() { public String methodSignature(String methodName) { return signatureBuilder().methodDeclarationSignature(getCompiledSource().getDeclarations().stream() + .filter(FirRegularClass.class::isInstance) .map(FirRegularClass.class::cast) .flatMap(it -> it.getDeclarations().stream()) .filter(FirSimpleFunction.class::isInstance)