mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-04-16 15:52:18 +00:00
Kapt: add JeElementRenderer
This commit is contained in:
committed by
Yan Zhulanow
parent
649b93833c
commit
3eecf78307
@@ -71,7 +71,7 @@ class KotlinElements(val javaPsiFacade: JavaPsiFacade, val scope: GlobalSearchSc
|
||||
override fun getBinaryName(type: TypeElement) = JeName((type as JeTypeElement).psi.qualifiedName)
|
||||
|
||||
//TODO
|
||||
override fun getDocComment(e: Element?) = ""
|
||||
override fun getDocComment(e: Element?) = null
|
||||
|
||||
override fun isDeprecated(e: Element?): Boolean {
|
||||
return (e as? JeAnnotationOwner)?.annotationOwner?.findAnnotation("java.lang.Deprecated") != null
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.types.*
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class DefaultJeElementRenderer : JeElementRenderer {
|
||||
override fun render(element: JeElement): String {
|
||||
return when (element) {
|
||||
is JePackageElement -> buildString {
|
||||
appendln("package ${element.qualifiedName}").appendln()
|
||||
element.enclosedElements.forEach { appendln(render(it).withMargin()).appendln() }
|
||||
}
|
||||
is JeTypeElement -> buildString {
|
||||
val classType = when (element.kind) {
|
||||
ElementKind.ANNOTATION_TYPE -> "@interface"
|
||||
ElementKind.INTERFACE -> "interface"
|
||||
ElementKind.ENUM -> "enum"
|
||||
ElementKind.CLASS -> "class"
|
||||
else -> throw IllegalStateException("Invalid class type: ${element.kind}")
|
||||
}
|
||||
appendln(renderModifiers(element) + classType + ' ' + element.simpleName + " {")
|
||||
appendln(element.enclosedElements.joinToString(LINE_SEPARATOR.repeat(2)) { render(it).withMargin() })
|
||||
append("}")
|
||||
}
|
||||
is JeVariableElement -> renderModifiers(element) + renderType(element.asType()) + " " + element.simpleName
|
||||
is JeMethodExecutableElement -> buildString {
|
||||
append(renderModifiers(element) + renderType(element.returnType, noneAsVoid = true) + " " + element.simpleName)
|
||||
append(element.parameters.joinToString(prefix = "(", postfix = ")") { renderType(it.asType()) + " " + it.simpleName })
|
||||
}
|
||||
is JeClassInitializerExecutableElement -> renderModifiers(element) + "{}"
|
||||
else -> throw IllegalArgumentException("Unsupported element: $element")
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderType(type: TypeMirror, noneAsVoid: Boolean = false): String {
|
||||
return when (type) {
|
||||
is JeNullType -> "null"
|
||||
is JeVoidType -> "void"
|
||||
is JeErrorType -> "<ERROR>"
|
||||
is JeNoneType -> if (noneAsVoid) "void" else throw IllegalArgumentException("Unexpected 'none' type")
|
||||
is JePsiType -> type.psiType.getCanonicalText(false)
|
||||
else -> throw IllegalArgumentException("Unsupported type: $type")
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderModifiers(element: Element): String {
|
||||
val renderedAnnotations = renderAnnotations(element)
|
||||
val modifiers = element.modifiers
|
||||
|
||||
return if (modifiers.isEmpty())
|
||||
renderedAnnotations
|
||||
else
|
||||
renderedAnnotations + modifiers.map { it.name.toLowerCase() }.joinToString(" ", postfix = " ")
|
||||
}
|
||||
|
||||
private fun renderAnnotations(element: Element): String {
|
||||
val annotations = element.annotationMirrors
|
||||
if (annotations.isEmpty()) return ""
|
||||
return annotations.joinToString(LINE_SEPARATOR, postfix = LINE_SEPARATOR) { renderAnnotation(it) }
|
||||
}
|
||||
|
||||
private fun renderAnnotation(anno: AnnotationMirror): String {
|
||||
val name = "@" + renderType(anno.annotationType)
|
||||
val args = anno.elementValues
|
||||
if (args.isEmpty()) return name
|
||||
|
||||
return name + args
|
||||
.map { it.key.simpleName.toString() + " = " + renderAnnotationValue(it.value) }
|
||||
.joinToString(prefix = "(", postfix = ")")
|
||||
}
|
||||
|
||||
private fun renderAnnotationValue(value: AnnotationValue): String {
|
||||
return when (value) {
|
||||
is JeAnnotationAnnotationValue -> renderAnnotation(value.value)
|
||||
is JeArrayAnnotationValue -> value.value.joinToString(prefix = "{ ", postfix = " }") { renderAnnotationValue(it) }
|
||||
is JeEnumValueAnnotationValue -> value.value.simpleName.toString()
|
||||
is JeErrorAnnotationValue -> "<ERROR>"
|
||||
is JeExpressionAnnotationValue, is JeLiteralAnnotationValue -> value.value?.let { renderConstantValue(it) } ?: "null"
|
||||
is JeTypeAnnotationValue -> renderType(value.value) + ".class"
|
||||
else -> throw IllegalArgumentException("Unsupported annotation value: $value")
|
||||
}
|
||||
}
|
||||
|
||||
private fun renderConstantValue(value: Any?): String {
|
||||
return when (value) {
|
||||
null -> "null"
|
||||
is String -> "\"" + value.replace("\"", "\\\"") + "\""
|
||||
else -> value.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun String.withMargin() = lines().map { MARGIN + it }.joinToString(LINE_SEPARATOR)
|
||||
|
||||
private companion object {
|
||||
val MARGIN = " "
|
||||
val LINE_SEPARATOR: String = System.getProperty("line.separator")
|
||||
}
|
||||
}
|
||||
@@ -40,22 +40,22 @@ fun JeAnnotationValue(psi: PsiAnnotationMemberValue): AnnotationValue = when (ps
|
||||
else -> throw AssertionError("Unsupported annotation element value: $psi")
|
||||
}
|
||||
|
||||
private class JeAnnotationAnnotationValue(val psi: PsiAnnotation) : AnnotationValue {
|
||||
internal class JeAnnotationAnnotationValue(val psi: PsiAnnotation) : AnnotationValue {
|
||||
override fun getValue() = JeAnnotationMirror(psi)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitAnnotation(value, p)
|
||||
}
|
||||
|
||||
private class JeEnumValueAnnotationValue(val psi: PsiEnumConstant) : AnnotationValue {
|
||||
internal class JeEnumValueAnnotationValue(val psi: PsiEnumConstant) : AnnotationValue {
|
||||
override fun getValue() = JeVariableElement(psi)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitEnumConstant(value, p)
|
||||
}
|
||||
|
||||
private class JeTypeAnnotationValue(val psi: PsiClassObjectAccessExpression) : AnnotationValue {
|
||||
internal class JeTypeAnnotationValue(val psi: PsiClassObjectAccessExpression) : AnnotationValue {
|
||||
override fun getValue() = psi.operand.type.toJeType(psi.manager)
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitType(value, p)
|
||||
}
|
||||
|
||||
private abstract class JePrimitiveAnnotationValue : AnnotationValue {
|
||||
internal abstract class JePrimitiveAnnotationValue : AnnotationValue {
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P): R {
|
||||
val value = this.value
|
||||
return when (value) {
|
||||
@@ -73,20 +73,20 @@ private abstract class JePrimitiveAnnotationValue : AnnotationValue {
|
||||
}
|
||||
}
|
||||
|
||||
private class JeLiteralAnnotationValue(val psi: PsiLiteral) : JePrimitiveAnnotationValue() {
|
||||
internal class JeLiteralAnnotationValue(val psi: PsiLiteral) : JePrimitiveAnnotationValue() {
|
||||
override fun getValue() = psi.value
|
||||
}
|
||||
|
||||
private class JeExpressionAnnotationValue(val psi: PsiExpression) : JePrimitiveAnnotationValue() {
|
||||
internal class JeExpressionAnnotationValue(val psi: PsiExpression) : JePrimitiveAnnotationValue() {
|
||||
override fun getValue() = JavaPsiFacade.getInstance(psi.project).constantEvaluationHelper.computeConstantExpression(psi)
|
||||
}
|
||||
|
||||
private class JeArrayAnnotationValue(val psi: PsiArrayInitializerMemberValue) : AnnotationValue {
|
||||
internal class JeArrayAnnotationValue(val psi: PsiArrayInitializerMemberValue) : AnnotationValue {
|
||||
override fun getValue() = psi.initializers.map { JeAnnotationValue(it) }
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitArray(value, p)
|
||||
}
|
||||
|
||||
private class JeErrorAnnotationValue(val psi: PsiElement) : AnnotationValue {
|
||||
internal class JeErrorAnnotationValue(val psi: PsiElement) : AnnotationValue {
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitString(psi.text, p)
|
||||
override fun getValue() = null
|
||||
}
|
||||
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright 2010-2016 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.jetbrains.kotlin.java.model.elements
|
||||
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
|
||||
interface JeElementRenderer {
|
||||
fun render(element: JeElement): String
|
||||
}
|
||||
@@ -55,8 +55,8 @@ class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAn
|
||||
else -> NestingKind.LOCAL
|
||||
}
|
||||
|
||||
override fun getEnclosedElements(): List<Element> {
|
||||
val declarations = mutableListOf<Element>()
|
||||
override fun getEnclosedElements(): List<JeElement> {
|
||||
val declarations = mutableListOf<JeElement>()
|
||||
psi.initializers.forEach { declarations += JeClassInitializerExecutableElement(it) }
|
||||
psi.fields.forEach { declarations += JeVariableElement(it) }
|
||||
psi.methods.forEach { declarations += JeMethodExecutableElement(it) }
|
||||
|
||||
Reference in New Issue
Block a user