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 package org.jetbrains.kotlin.j2k
import com.intellij.lang.jvm.JvmAnnotatedElement
import com.intellij.psi.* import com.intellij.psi.*
import com.intellij.psi.JavaTokenType.SUPER_KEYWORD import com.intellij.psi.JavaTokenType.SUPER_KEYWORD
import com.intellij.psi.JavaTokenType.THIS_KEYWORD import com.intellij.psi.JavaTokenType.THIS_KEYWORD
import com.intellij.psi.impl.source.tree.ChildRole import com.intellij.psi.impl.source.tree.ChildRole
import com.intellij.psi.impl.source.tree.java.* 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.InheritanceUtil
import com.intellij.psi.util.PsiUtil import com.intellij.psi.util.PsiUtil
import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade import org.jetbrains.kotlin.asJava.classes.KtLightClassForFacade
import org.jetbrains.kotlin.asJava.elements.KtLightMethod 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.ast.Nullability
import org.jetbrains.kotlin.j2k.tree.* import org.jetbrains.kotlin.j2k.tree.*
import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.* import org.jetbrains.kotlin.j2k.tree.JKLiteralExpression.LiteralType.*
@@ -392,6 +395,7 @@ class JavaToJKTreeBuilder(
classKind, classKind,
typeParameterList?.toJK() ?: JKTypeParameterListImpl(), typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
createClassBody(), createClassBody(),
annotationList(),
modifiers(), modifiers(),
visibility(), visibility(),
modality() modality()
@@ -512,7 +516,7 @@ class JavaToJKTreeBuilder(
with(expressionTreeMapper) { typeElement?.toJK() } ?: JKTypeElementImpl(JKNoTypeImpl), with(expressionTreeMapper) { typeElement?.toJK() } ?: JKTypeElementImpl(JKNoTypeImpl),
JKNameIdentifierImpl(name), JKNameIdentifierImpl(name),
with(expressionTreeMapper) { initializer.toJK() }, with(expressionTreeMapper) { initializer.toJK() },
JKAnnotationListImpl(annotations.map { it.toJK() }), annotationList(),
modifiers(), modifiers(),
visibility(), visibility(),
modality(), 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 = fun PsiAnnotation.toJK(): JKAnnotation =
JKAnnotationImpl( JKAnnotationImpl(
symbolProvider.provideSymbol(nameReferenceElement!!), 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 { fun PsiMethod.toJK(): JKJavaMethod {
return JKJavaMethodImpl( return JKJavaMethodImpl(
@@ -543,7 +567,7 @@ class JavaToJKTreeBuilder(
parameterList.parameters.map { it.toJK() }, parameterList.parameters.map { it.toJK() },
body?.toJK() ?: JKBodyStub, body?.toJK() ?: JKBodyStub,
typeParameterList?.toJK() ?: JKTypeParameterListImpl(), typeParameterList?.toJK() ?: JKTypeParameterListImpl(),
JKAnnotationListImpl(),//TODO get real annotations annotationList(),
throwsList.referencedTypes.map { JKTypeElementImpl(it.toJK(symbolProvider)) }, throwsList.referencedTypes.map { JKTypeElementImpl(it.toJK(symbolProvider)) },
modifiers(), modifiers(),
visibility(), visibility(),
@@ -173,6 +173,10 @@ class NewCodeBuilder {
} }
override fun visitClass(klass: JKClass) { override fun visitClass(klass: JKClass) {
klass.annotationList.accept(this)
if (klass.annotationList.annotations.isNotEmpty()) {
printer.println()
}
renderModifiersList(klass) renderModifiersList(klass)
builder.append(" ") builder.append(" ")
printer.print(classKindString(klass.classKind)) printer.print(classKindString(klass.classKind))
@@ -688,6 +692,10 @@ class NewCodeBuilder {
} }
override fun visitKtConstructor(ktConstructor: JKKtConstructor) { override fun visitKtConstructor(ktConstructor: JKKtConstructor) {
ktConstructor.annotationList.accept(this)
if (ktConstructor.annotationList.annotations.isNotEmpty()) {
printer.println()
}
renderModifiersList(ktConstructor) renderModifiersList(ktConstructor)
printer.print(" constructor") printer.print(" constructor")
renderParameterList(ktConstructor.parameters) renderParameterList(ktConstructor.parameters)
@@ -38,6 +38,7 @@ class ClassToObjectPromotionConversion(private val context: ConversionContext) :
companion.classBody.also { companion.classBody.also {
it.handleDeclarationsModifiers() it.handleDeclarationsModifiers()
}, },
JKAnnotationListImpl(),
element.extraModifiers, element.extraModifiers,
element.visibility, element.visibility,
Modality.FINAL Modality.FINAL
@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.j2k.conversions package org.jetbrains.kotlin.j2k.conversions
import org.jetbrains.kotlin.j2k.ConversionContext import org.jetbrains.kotlin.j2k.ConversionContext
import org.jetbrains.kotlin.j2k.annotationByFqName
import org.jetbrains.kotlin.j2k.jvmAnnotation import org.jetbrains.kotlin.j2k.jvmAnnotation
import org.jetbrains.kotlin.j2k.tree.* 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 (element is JKExtraModifiersOwner && element is JKAnnotationListOwner) {
if (ExtraModifier.VOLATILE in element.extraModifiers) { if (ExtraModifier.VOLATILE in element.extraModifiers) {
element.extraModifiers -= ExtraModifier.VOLATILE element.extraModifiers -= ExtraModifier.VOLATILE
@@ -44,6 +44,7 @@ class StaticsToCompanionExtractConversion : RecursiveApplicableConversionBase()
JKClass.ClassKind.COMPANION, JKClass.ClassKind.COMPANION,
JKTypeParameterListImpl(), JKTypeParameterListImpl(),
JKClassBodyImpl(), JKClassBodyImpl(),
JKAnnotationListImpl(),
emptyList(), emptyList(),
Visibility.PUBLIC, Visibility.PUBLIC,
Modality.FINAL 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> { fun JKVariable.findUsages(scope: JKTreeElement, context: ConversionContext): List<JKFieldAccessExpression> {
val symbol = context.symbolProvider.provideUniverseSymbol(this) val symbol = context.symbolProvider.provideUniverseSymbol(this)
val usages = mutableListOf<JKFieldAccessExpression>() val usages = mutableListOf<JKFieldAccessExpression>()
@@ -51,6 +51,7 @@ class JKClassImpl(
override var classKind: JKClass.ClassKind, override var classKind: JKClass.ClassKind,
typeParameterList: JKTypeParameterList, typeParameterList: JKTypeParameterList,
classBody: JKClassBody, classBody: JKClassBody,
annotationList: JKAnnotationList,
override var extraModifiers: List<ExtraModifier>, override var extraModifiers: List<ExtraModifier>,
override var visibility: Visibility, override var visibility: Visibility,
override var modality: Modality override var modality: Modality
@@ -61,6 +62,7 @@ class JKClassImpl(
override val inheritance by child(inheritance) override val inheritance by child(inheritance)
override var typeParameterList: JKTypeParameterList by child(typeParameterList) override var typeParameterList: JKTypeParameterList by child(typeParameterList)
override var classBody: JKClassBody by child(classBody) 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() { class JKNameIdentifierImpl(override val value: String) : JKNameIdentifier, JKElementBase(), PsiOwner by PsiOwnerImpl() {
@@ -50,7 +50,8 @@ interface JKFile : JKTreeElement, JKBranchElement {
var declarationList: List<JKDeclaration> 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 name: JKNameIdentifier
val inheritance: JKInheritanceInfo val inheritance: JKInheritanceInfo