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:
committed by
Ilya Kirillov
parent
58f2348647
commit
4da7d11364
Vendored
+15
-1
@@ -4,6 +4,8 @@ import org.jetbrains.annotations.Nullable;
|
|||||||
|
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import kotlinApi.KotlinClassWithProperties;
|
import kotlinApi.KotlinClassWithProperties;
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
public @interface Anon1 {
|
public @interface Anon1 {
|
||||||
String[] value();
|
String[] value();
|
||||||
@@ -127,4 +129,16 @@ public class JavaClass {
|
|||||||
|
|
||||||
public @interface SpecialExternal {
|
public @interface SpecialExternal {
|
||||||
String[] names(); //array is used
|
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
|
package org.jetbrains.kotlin.nj2k
|
||||||
|
|
||||||
|
import com.intellij.codeInsight.AnnotationTargetUtil
|
||||||
import com.intellij.lang.jvm.JvmModifier
|
import com.intellij.lang.jvm.JvmModifier
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.JavaTokenType.SUPER_KEYWORD
|
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.*
|
||||||
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
|
import org.jetbrains.kotlin.nj2k.tree.JKLiteralExpression.LiteralType.*
|
||||||
import org.jetbrains.kotlin.nj2k.types.*
|
import org.jetbrains.kotlin.nj2k.types.*
|
||||||
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
import org.jetbrains.kotlin.psi.psiUtil.collectDescendantsOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
@@ -720,7 +720,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
|
|
||||||
fun PsiField.toJK(): JKField {
|
fun PsiField.toJK(): JKField {
|
||||||
return JKField(
|
return JKField(
|
||||||
JKTypeElement(type.toJK()).withFormattingFrom(typeElement),
|
JKTypeElement(type.toJK(), typeElement.annotationList()).withFormattingFrom(typeElement),
|
||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
with(expressionTreeMapper) { initializer.toJK() },
|
with(expressionTreeMapper) { initializer.toJK() },
|
||||||
annotationList(this),
|
annotationList(this),
|
||||||
@@ -741,12 +741,16 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
when {
|
when {
|
||||||
annotation !is PsiAnnotation -> null
|
annotation !is PsiAnnotation -> null
|
||||||
annotation.qualifiedName == DEPRECATED_ANNOTAION_FQ_NAME && deprecatedAnnotation != null -> null
|
annotation.qualifiedName == DEPRECATED_ANNOTAION_FQ_NAME && deprecatedAnnotation != null -> null
|
||||||
|
AnnotationTargetUtil.isTypeAnnotation(annotation) -> null
|
||||||
else -> annotation.toJK()
|
else -> annotation.toJK()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return JKAnnotationList(plainAnnotations + listOfNotNull(deprecatedAnnotation))
|
return JKAnnotationList(plainAnnotations + listOfNotNull(deprecatedAnnotation))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun PsiTypeElement?.annotationList(): JKAnnotationList {
|
||||||
|
return JKAnnotationList(this?.applicableAnnotations?.map { it.toJK() }.orEmpty())
|
||||||
|
}
|
||||||
|
|
||||||
fun PsiAnnotation.toJK(): JKAnnotation =
|
fun PsiAnnotation.toJK(): JKAnnotation =
|
||||||
JKAnnotation(
|
JKAnnotation(
|
||||||
@@ -814,7 +818,8 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
JKTypeElement(
|
JKTypeElement(
|
||||||
returnType?.toJK()
|
returnType?.toJK()
|
||||||
?: JKJavaVoidType.takeIf { isConstructor }
|
?: JKJavaVoidType.takeIf { isConstructor }
|
||||||
?: JKNoType),
|
?: JKNoType,
|
||||||
|
returnTypeElement.annotationList()),
|
||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
parameterList.parameters.map { it.toJK().withLineBreaksFrom(it) },
|
parameterList.parameters.map { it.toJK().withLineBreaksFrom(it) },
|
||||||
body?.toJK() ?: JKBodyStub,
|
body?.toJK() ?: JKBodyStub,
|
||||||
@@ -839,8 +844,8 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
fun PsiParameter.toJK(): JKParameter {
|
fun PsiParameter.toJK(): JKParameter {
|
||||||
val rawType = type.toJK()
|
val rawType = type.toJK()
|
||||||
val type =
|
val type =
|
||||||
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElement(rawType.type)
|
if (isVarArgs && rawType is JKJavaArrayType) JKTypeElement(rawType.type, typeElement.annotationList())
|
||||||
else rawType.asTypeElement()
|
else rawType.asTypeElement(typeElement.annotationList())
|
||||||
return JKParameter(
|
return JKParameter(
|
||||||
type,
|
type,
|
||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
@@ -862,9 +867,9 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fun PsiLocalVariable.toJK(): JKLocalVariable =
|
fun PsiLocalVariable.toJK(): JKLocalVariable {
|
||||||
JKLocalVariable(
|
return JKLocalVariable(
|
||||||
JKTypeElement(type.toJK()).withFormattingFrom(typeElement),
|
JKTypeElement(type.toJK(), typeElement.annotationList()).withFormattingFrom(typeElement),
|
||||||
nameIdentifier.toJK(),
|
nameIdentifier.toJK(),
|
||||||
with(expressionTreeMapper) { initializer.toJK() },
|
with(expressionTreeMapper) { initializer.toJK() },
|
||||||
JKMutabilityModifierElement(
|
JKMutabilityModifierElement(
|
||||||
@@ -878,6 +883,7 @@ class JavaToJKTreeBuilder constructor(
|
|||||||
}.also {
|
}.also {
|
||||||
it.withFormattingFrom(this)
|
it.withFormattingFrom(this)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun PsiStatement?.toJK(): JKStatement {
|
fun PsiStatement?.toJK(): JKStatement {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
|
|||||||
@@ -599,6 +599,7 @@ internal class JKCodeBuilder(context: NewJ2kConverterContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun visitTypeElementRaw(typeElement: JKTypeElement) {
|
override fun visitTypeElementRaw(typeElement: JKTypeElement) {
|
||||||
|
typeElement.annotationList.accept(this)
|
||||||
printer.renderType(typeElement.type, typeElement)
|
printer.renderType(typeElement.type, typeElement)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -27,8 +27,9 @@ class JKFile(
|
|||||||
var declarationList by children(declarationList)
|
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 fun accept(visitor: JKVisitor) = visitor.visitTypeElement(this)
|
||||||
|
override var annotationList: JKAnnotationList by child(annotationList)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class JKBlock : JKTreeElement() {
|
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.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||||
|
|
||||||
fun JKType.asTypeElement() =
|
fun JKType.asTypeElement(annotationList: JKAnnotationList = JKAnnotationList()) =
|
||||||
JKTypeElement(this)
|
JKTypeElement(this, annotationList)
|
||||||
|
|
||||||
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
|
fun JKClassSymbol.asType(nullability: Nullability = Nullability.Default): JKClassType =
|
||||||
JKClassType(this, emptyList(), nullability)
|
JKClassType(this, emptyList(), nullability)
|
||||||
|
|||||||
@@ -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;
|
||||||
|
}
|
||||||
@@ -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
|
||||||
|
}
|
||||||
+5
@@ -135,6 +135,11 @@ public class NewJavaToKotlinConverterSingleFileTestGenerated extends AbstractNew
|
|||||||
public void testSuppressWarnings() throws Exception {
|
public void testSuppressWarnings() throws Exception {
|
||||||
runTest("nj2k/testData/newJ2k/annotations/suppressWarnings.java");
|
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")
|
@TestMetadata("nj2k/testData/newJ2k/anonymousBlock")
|
||||||
|
|||||||
Reference in New Issue
Block a user