KT-30643 J2K: wrong position of TYPE_USE annotation (#2543)

New J2K: fix wrong position of TYPE_USE annotation

#KT-30643 Fixed
This commit is contained in:
Toshiaki Kameyama
2019-10-08 22:21:27 +09:00
committed by Ilya Kirillov
parent 58f2348647
commit 4da7d11364
8 changed files with 104 additions and 12 deletions
+15 -1
View File
@@ -4,6 +4,8 @@ import org.jetbrains.annotations.Nullable;
import java.util.Set;
import kotlinApi.KotlinClassWithProperties;
import java.lang.annotation.ElementType;
import java.lang.annotation.Target;
public @interface Anon1 {
String[] value();
@@ -127,4 +129,16 @@ public class JavaClass {
public @interface SpecialExternal {
String[] names(); //array is used
}
}
@Target(ElementType.TYPE_USE)
public @interface TypeUseAnon1 {
}
@Target({ElementType.TYPE_USE})
public @interface TypeUseAnon2 {
}
@Target({ElementType.TYPE_USE, ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER})
public @interface TypeUseAnon3 {
}
@@ -16,6 +16,7 @@
package org.jetbrains.kotlin.nj2k
import com.intellij.codeInsight.AnnotationTargetUtil
import com.intellij.lang.jvm.JvmModifier
import com.intellij.psi.*
import com.intellij.psi.JavaTokenType.SUPER_KEYWORD
@@ -44,7 +45,6 @@ import org.jetbrains.kotlin.nj2k.symbols.*
import org.jetbrains.kotlin.nj2k.tree.*
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
import org.jetbrains.kotlin.nj2k.types.*
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
@@ -720,7 +720,7 @@ class JavaToJKTreeBuilder constructor(
fun PsiField.toJK(): JKField {
return JKField(
JKTypeElement(type.toJK()).withFormattingFrom(typeElement),
JKTypeElement(type.toJK(), typeElement.annotationList()).withFormattingFrom(typeElement),
nameIdentifier.toJK(),
with(expressionTreeMapper) { initializer.toJK() },
annotationList(this),
@@ -741,12 +741,16 @@ class JavaToJKTreeBuilder constructor(
when {
annotation !is PsiAnnotation -> null
annotation.qualifiedName == DEPRECATED_ANNOTAION_FQ_NAME && deprecatedAnnotation != null -> null
AnnotationTargetUtil.isTypeAnnotation(annotation) -> null
else -> annotation.toJK()
}
}
return JKAnnotationList(plainAnnotations + listOfNotNull(deprecatedAnnotation))
}
fun PsiTypeElement?.annotationList(): JKAnnotationList {
return JKAnnotationList(this?.applicableAnnotations?.map { it.toJK() }.orEmpty())
}
fun PsiAnnotation.toJK(): JKAnnotation =
JKAnnotation(
@@ -814,7 +818,8 @@ class JavaToJKTreeBuilder constructor(
JKTypeElement(
returnType?.toJK()
?: JKJavaVoidType.takeIf { isConstructor }
?: JKNoType),
?: JKNoType,
returnTypeElement.annotationList()),
nameIdentifier.toJK(),
parameterList.parameters.map { it.toJK().withLineBreaksFrom(it) },
body?.toJK() ?: JKBodyStub,
@@ -839,8 +844,8 @@ class JavaToJKTreeBuilder constructor(
fun PsiParameter.toJK(): JKParameter {
val rawType = type.toJK()
val type =
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElement(rawType.type)
else rawType.asTypeElement()
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElement(rawType.type, typeElement.annotationList())
else rawType.asTypeElement(typeElement.annotationList())
return JKParameter(
type,
nameIdentifier.toJK(),
@@ -862,9 +867,9 @@ class JavaToJKTreeBuilder constructor(
}
fun PsiLocalVariable.toJK(): JKLocalVariable =
JKLocalVariable(
JKTypeElement(type.toJK()).withFormattingFrom(typeElement),
fun PsiLocalVariable.toJK(): JKLocalVariable {
return JKLocalVariable(
JKTypeElement(type.toJK(), typeElement.annotationList()).withFormattingFrom(typeElement),
nameIdentifier.toJK(),
with(expressionTreeMapper) { initializer.toJK() },
JKMutabilityModifierElement(
@@ -878,6 +883,7 @@ class JavaToJKTreeBuilder constructor(
}.also {
it.withFormattingFrom(this)
}
}
fun PsiStatement?.toJK(): JKStatement {
return when (this) {
@@ -599,6 +599,7 @@ internal class JKCodeBuilder(context: NewJ2kConverterContext) {
}
override fun visitTypeElementRaw(typeElement: JKTypeElement) {
typeElement.annotationList.accept(this)
printer.renderType(typeElement.type, typeElement)
}
@@ -27,8 +27,9 @@ class JKFile(
var declarationList by children(declarationList)
}
class JKTypeElement(var type: JKType) : JKTreeElement() {
class JKTypeElement(var type: JKType, annotationList: JKAnnotationList = JKAnnotationList()) : JKTreeElement(), JKAnnotationListOwner {
override fun accept(visitor: JKVisitor) = visitor.visitTypeElement(this)
override var annotationList: JKAnnotationList by child(annotationList)
}
abstract class JKBlock : JKTreeElement() {
@@ -24,8 +24,8 @@ import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
fun JKType.asTypeElement() =
JKTypeElement(this)
fun JKType.asTypeElement(annotationList: JKAnnotationList = JKAnnotationList()) =
JKTypeElement(this, annotationList)
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
JKClassType(this, emptyList(), nullability)
+28
View File
@@ -0,0 +1,28 @@
import javaApi.Anon5
import javaApi.TypeUseAnon1
import javaApi.TypeUseAnon2
import javaApi.TypeUseAnon3
public class TEST1 {
public @Anon5(1) @TypeUseAnon1 String foo(@Anon5(2) @TypeUseAnon1 Object o) {
@Anon5(3) @TypeUseAnon1 String baz = "";
return "";
}
@Anon5(4) @TypeUseAnon1 String bar;
}
public class TEST2 {
public @Anon5(1) @TypeUseAnon2 String foo(@Anon5(2) @TypeUseAnon2 Object o) {
@Anon5(3) @TypeUseAnon2 String baz = "";
return "";
}
@Anon5(4) @TypeUseAnon2 String bar;
}
public class TEST3 {
public @Anon5(1) @TypeUseAnon3 String foo(@Anon5(2) @TypeUseAnon3 Object o) {
@Anon5(3) @TypeUseAnon3 String baz = "";
return "";
}
@Anon5(4) @TypeUseAnon3 String bar;
}
+37
View File
@@ -0,0 +1,37 @@
import javaApi.Anon5
import javaApi.TypeUseAnon1
import javaApi.TypeUseAnon2
import javaApi.TypeUseAnon3
class TEST1 {
@Anon5(1)
fun foo(@Anon5(2) o: @TypeUseAnon1 Any?): @TypeUseAnon1 String? {
@Anon5(3) val baz = ""
return ""
}
@Anon5(4)
internal var bar: @TypeUseAnon1 String? = null
}
class TEST2 {
@Anon5(1)
fun foo(@Anon5(2) o: @TypeUseAnon2 Any?): @TypeUseAnon2 String? {
@Anon5(3) val baz = ""
return ""
}
@Anon5(4)
internal var bar: @TypeUseAnon2 String? = null
}
class TEST3 {
@Anon5(1)
fun foo(@Anon5(2) o: @TypeUseAnon3 Any?): @TypeUseAnon3 String? {
@Anon5(3) val baz = ""
return ""
}
@Anon5(4)
internal var bar: @TypeUseAnon3 String? = null
}
@@ -135,6 +135,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
public void testSuppressWarnings() throws Exception {
runTest("nj2k/testData/newJ2k/annotations/suppressWarnings.java");
}
@TestMetadata("typeUseAnnotation.java")
public void testTypeUseAnnotation() throws Exception {
runTest("nj2k/testData/newJ2k/annotations/typeUseAnnotation.java");
}
}
@TestMetadata("nj2k/testData/newJ2k/anonymousBlock")