New J2K: Add support of deprecated annotation && fix annotations

This commit is contained in:
Ilya Kirillov
2019-01-16 14:25:24 +03:00
committed by Ilya Kirillov
parent 3990e1d223
commit 9eaa961a2a
8 changed files with 61 additions and 3 deletions
@@ -16,15 +16,18 @@
package org.jetbrains.kotlin.j2k
import com.intellij.lang.jvm.JvmAnnotatedElement
import com.intellij.psi.*
import com.intellij.psi.JavaTokenType.SUPER_KEYWORD
import com.intellij.psi.JavaTokenType.THIS_KEYWORD
import com.intellij.psi.impl.source.tree.ChildRole
import com.intellij.psi.impl.source.tree.java.*
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.util.InheritanceUtil
import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
import org.jetbrains.kotlin.idea.j2k.content
import org.jetbrains.kotlin.j2k.ast.Nullability
import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.*
@@ -392,6 +395,7 @@ class JavaToJKTreeBuilder(
classKind,
typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
createClassBody(),
annotationList(),
modifiers(),
visibility(),
modality()
@@ -512,7 +516,7 @@ class JavaToJKTreeBuilder(
with(expressionTreeMapper) { typeElement?.toJK() } ?: JKTypeElementImpl(JKNoTypeImpl),
JKNameIdentifierImpl(name),
with(expressionTreeMapper) { initializer.toJK() },
JKAnnotationListImpl(annotations.map { it.toJK() }),
annotationList(),
modifiers(),
visibility(),
modality(),
@@ -523,6 +527,16 @@ class JavaToJKTreeBuilder(
}
}
fun <T> T.annotationList(): JKAnnotationList where T : JvmAnnotatedElement, T: PsiDocCommentOwner {
val plainAnnotations = annotations.map { it.toJK() }
val deprecatedAnnotation = docComment?.deprecatedAnnotation() ?: return JKAnnotationListImpl(plainAnnotations)
return JKAnnotationListImpl(
plainAnnotations.mapNotNull { annotation ->
if (annotation.classSymbol.fqName == "java.lang.Deprecated") null else annotation
} + deprecatedAnnotation
)
}
fun PsiAnnotation.toJK(): JKAnnotation =
JKAnnotationImpl(
symbolProvider.provideSymbol(nameReferenceElement!!),
@@ -531,6 +545,16 @@ class JavaToJKTreeBuilder(
}
)
fun PsiDocComment.deprecatedAnnotation(): JKAnnotation? =
findTagByName("deprecated")?.let { tag ->
JKAnnotationImpl(
symbolProvider.provideByFqName("kotlin.Deprecated"),
JKExpressionListImpl(
stringLiteral(tag.content(), symbolProvider)
)
)
}
fun PsiMethod.toJK(): JKJavaMethod {
return JKJavaMethodImpl(
@@ -543,7 +567,7 @@ class JavaToJKTreeBuilder(
parameterList.parameters.map { it.toJK() },
body?.toJK() ?: JKBodyStub,
typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
JKAnnotationListImpl(),//TODO get real annotations
annotationList(),
throwsList.referencedTypes.map { JKTypeElementImpl(it.toJK(symbolProvider)) },
modifiers(),
visibility(),
@@ -173,6 +173,10 @@ class NewCodeBuilder {
}
override fun visitClass(klass: JKClass) {
klass.annotationList.accept(this)
if (klass.annotationList.annotations.isNotEmpty()) {
printer.println()
}
renderModifiersList(klass)
builder.append(" ")
printer.print(classKindString(klass.classKind))
@@ -688,6 +692,10 @@ class NewCodeBuilder {
}
override fun visitKtConstructor(ktConstructor: JKKtConstructor) {
ktConstructor.annotationList.accept(this)
if (ktConstructor.annotationList.annotations.isNotEmpty()) {
printer.println()
}
renderModifiersList(ktConstructor)
printer.print(" constructor")
renderParameterList(ktConstructor.parameters)
@@ -38,6 +38,7 @@ class ClassToObjectPromotionConversion(private val context: ConversionContext) :
companion.classBody.also {
it.handleDeclarationsModifiers()
},
JKAnnotationListImpl(),
element.extraModifiers,
element.visibility,
Modality.FINAL
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.annotationByFqName
import org.jetbrains.kotlin.j2k.jvmAnnotation
import org.jetbrains.kotlin.j2k.tree.*
@@ -20,6 +21,13 @@ class JavaModifiersConversion(private val context: ConversionContext) : Recursiv
}
}
}
if (element is JKModalityOwner && element is JKAnnotationListOwner) {
val overrideAnnotation = element.annotationList.annotationByFqName("java.lang.Override")
if (overrideAnnotation != null) {
element.annotationList.annotations -= overrideAnnotation
//TODO change modality to OVERRIDE???
}
}
if (element is JKExtraModifiersOwner && element is JKAnnotationListOwner) {
if (ExtraModifier.VOLATILE in element.extraModifiers) {
element.extraModifiers -= ExtraModifier.VOLATILE
@@ -44,6 +44,7 @@ class StaticsToCompanionExtractConversion : RecursiveApplicableConversionBase()
JKClass.ClassKind.COMPANION,
JKTypeParameterListImpl(),
JKClassBodyImpl(),
JKAnnotationListImpl(),
emptyList(),
Visibility.PUBLIC,
Modality.FINAL
@@ -243,6 +243,19 @@ fun throwAnnotation(throws: List<JKType>, symbolProvider: JKSymbolProvider) =
)
)
fun JKAnnotationList.annotationByFqName(fqName: String): JKAnnotation? =
annotations.firstOrNull { it.classSymbol.fqName == fqName }
fun stringLiteral(content: String, symbolProvider: JKSymbolProvider): JKExpression {
val lines = content.split('\n')
return lines.mapIndexed { i, line ->
val newlineSeparator = if (i == lines.size - 1) "" else "\\n"
JKKtLiteralExpressionImpl("\"$line$newlineSeparator\"", JKLiteralExpression.LiteralType.STRING)
}.reduce { acc: JKExpression, literalExpression: JKKtLiteralExpression ->
kotlinBinaryExpression(acc, literalExpression, JKKtSingleValueOperatorToken(KtTokens.PLUS), symbolProvider)!!
}
}
fun JKVariable.findUsages(scope: JKTreeElement, context: ConversionContext): List<JKFieldAccessExpression> {
val symbol = context.symbolProvider.provideUniverseSymbol(this)
val usages = mutableListOf<JKFieldAccessExpression>()
@@ -51,6 +51,7 @@ class JKClassImpl(
override var classKind: JKClass.ClassKind,
typeParameterList: JKTypeParameterList,
classBody: JKClassBody,
annotationList: JKAnnotationList,
override var extraModifiers: List<ExtraModifier>,
override var visibility: Visibility,
override var modality: Modality
@@ -61,6 +62,7 @@ class JKClassImpl(
override val inheritance by child(inheritance)
override var typeParameterList: JKTypeParameterList by child(typeParameterList)
override var classBody: JKClassBody by child(classBody)
override var annotationList: JKAnnotationList by child(annotationList)
}
class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase(), PsiOwner by PsiOwnerImpl() {
@@ -50,7 +50,8 @@ interface JKFile : JKTreeElement, JKBranchElement {
var declarationList: List<JKDeclaration>
}
interface JKClass : JKDeclaration, JKVisibilityOwner, JKExtraModifiersOwner, JKModalityOwner, JKTypeParameterListOwner, JKBranchElement {
interface JKClass : JKDeclaration, JKVisibilityOwner, JKExtraModifiersOwner, JKModalityOwner, JKTypeParameterListOwner, JKAnnotationListOwner,
JKBranchElement {
val name: JKNameIdentifier
val inheritance: JKInheritanceInfo