Kapt: Add APT wrappers for PSI elements
(cherry picked from commit 1214513)
This commit is contained in:
committed by
Yan Zhulanow
parent
89c39b9762
commit
cc12a6c228
+17
@@ -0,0 +1,17 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<module type="JAVA_MODULE" version="4">
|
||||
<component name="NewModuleRootManager" inherit-compiler-output="true">
|
||||
<exclude-output />
|
||||
<content url="file://$MODULE_DIR$">
|
||||
<sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
|
||||
</content>
|
||||
<orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
|
||||
<orderEntry type="sourceFolder" forTests="false" />
|
||||
<orderEntry type="library" name="intellij-core" level="project" />
|
||||
<orderEntry type="library" name="asm" level="project" />
|
||||
<orderEntry type="module" module-name="light-classes" />
|
||||
<orderEntry type="module" module-name="frontend" />
|
||||
<orderEntry type="module" module-name="annotation-processing" />
|
||||
<orderEntry type="library" name="kotlin-runtime" level="project" />
|
||||
</component>
|
||||
</module>
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiClass
|
||||
import org.jetbrains.kotlin.java.model.elements.JeAnnotationMirror
|
||||
import org.jetbrains.kotlin.java.model.internal.createAnnotation
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.Element
|
||||
import java.lang.reflect.Array as RArray
|
||||
|
||||
interface JeAnnotationOwner : Element {
|
||||
val annotationOwner: PsiAnnotationOwner?
|
||||
|
||||
override fun getAnnotationMirrors() = annotationOwner?.annotations?.map { JeAnnotationMirror(it) } ?: emptyList()
|
||||
|
||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>): A? {
|
||||
val annotationFqName = annotationClass.canonicalName
|
||||
|
||||
val annotation = annotationOwner?.annotations
|
||||
?.firstOrNull { it.qualifiedName == annotationFqName } ?: return null
|
||||
val annotationDeclaration = annotation.nameReferenceElement?.resolve() as? PsiClass ?: return null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return createAnnotation(annotation, annotationDeclaration, annotationClass) as? A
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <A : Annotation?> getAnnotationsByType(annotationType: Class<A>): Array<A> {
|
||||
return RArray.newInstance(annotationType, 0) as Array<A>
|
||||
}
|
||||
}
|
||||
|
||||
interface JeNoAnnotations : Element {
|
||||
override fun getAnnotationMirrors() = emptyList<AnnotationMirror>()
|
||||
|
||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>?): Nothing? {
|
||||
return null
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <A : Annotation?> getAnnotationsByType(annotationType: Class<A>): Array<A> {
|
||||
return RArray.newInstance(annotationType, 0) as Array<A>
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.elements.*
|
||||
|
||||
object JeConverter {
|
||||
fun convert(psi: PsiElement?): JeElement? = when (psi) {
|
||||
null -> null
|
||||
is PsiPackage -> JePackageElement(psi)
|
||||
is PsiClass -> JeTypeElement(psi)
|
||||
is PsiVariable -> JeVariableElement(psi)
|
||||
is PsiMethod -> JeMethodExecutableElement(psi)
|
||||
is PsiClassInitializer -> JeClassInitializerExecutableElement(psi)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.psi.PsiElement
|
||||
import javax.lang.model.element.Element
|
||||
|
||||
abstract class JeElement : Element {
|
||||
abstract val psi: PsiElement
|
||||
}
|
||||
+26
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.internal.getJavaModifiers
|
||||
import javax.lang.model.element.Element
|
||||
|
||||
interface JeModifierListOwner : Element {
|
||||
val psi: PsiModifierListOwner
|
||||
override fun getModifiers() = psi.getJavaModifiers()
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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
|
||||
|
||||
import javax.lang.model.element.Name
|
||||
|
||||
fun JeName(name: String?) = name?.let { JeName(it) } ?: JeName.EMPTY
|
||||
|
||||
class JeName(val name: String) : Name, CharSequence by name {
|
||||
override fun contentEquals(cs: CharSequence?) = cs?.toString() == name
|
||||
|
||||
override fun toString() = name
|
||||
|
||||
companion object {
|
||||
val EMPTY = JeName("")
|
||||
val INIT = JeName("<init>")
|
||||
val CLINIT = JeName("<clinit>")
|
||||
}
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.PsiAnnotation
|
||||
import com.intellij.psi.PsiAnnotationMethod
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredErrorType
|
||||
import org.jetbrains.kotlin.java.model.types.JeDeclaredType
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.ExecutableElement
|
||||
import javax.lang.model.type.DeclaredType
|
||||
|
||||
class JeAnnotationMirror(val psi: PsiAnnotation) : AnnotationMirror {
|
||||
override fun getAnnotationType(): DeclaredType? {
|
||||
val psiClass = resolveAnnotationClass() ?: return JeDeclaredErrorType
|
||||
return JeDeclaredType(PsiTypesUtil.getClassType(psiClass), psiClass)
|
||||
}
|
||||
|
||||
override fun getElementValues(): Map<out ExecutableElement, AnnotationValue> {
|
||||
val annotationClass = resolveAnnotationClass() ?: return emptyMap()
|
||||
|
||||
return mutableMapOf<ExecutableElement, AnnotationValue>().apply {
|
||||
for (attribute in psi.parameterList.attributes) {
|
||||
val attributeValue = attribute.value ?: continue
|
||||
val method = annotationClass.methods.firstOrNull {
|
||||
it is PsiAnnotationMethod && it.name == attribute.name
|
||||
} ?: return emptyMap()
|
||||
put(JeMethodExecutableElement(method), JeAnnotationValue(attributeValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun getAllElementValues(): Map<out ExecutableElement, AnnotationValue> {
|
||||
val annotationClass = resolveAnnotationClass() ?: return emptyMap()
|
||||
|
||||
return mutableMapOf<ExecutableElement, AnnotationValue>().apply {
|
||||
for (method in annotationClass.methods) {
|
||||
method as? PsiAnnotationMethod ?: continue
|
||||
val attributeValue = psi.findAttributeValue(method.name) ?: method.defaultValue ?: continue
|
||||
put(JeMethodExecutableElement(method), JeAnnotationValue(attributeValue))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun resolveAnnotationClass() = psi.nameReferenceElement?.resolve() as? PsiClass
|
||||
}
|
||||
+92
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.AnnotationValue
|
||||
import javax.lang.model.element.AnnotationValueVisitor
|
||||
|
||||
fun JeAnnotationValue(psi: PsiAnnotationMemberValue): AnnotationValue = when (psi) {
|
||||
is PsiLiteral -> JeLiteralAnnotationValue(psi)
|
||||
is PsiAnnotation -> JeAnnotationAnnotationValue(psi)
|
||||
is PsiArrayInitializerMemberValue -> JeArrayAnnotationValue(psi)
|
||||
is PsiClassObjectAccessExpression -> JeTypeAnnotationValue(psi)
|
||||
is PsiReferenceExpression -> {
|
||||
// TODO check static final field -> primitive, reference to enum value
|
||||
val element = psi.resolve()
|
||||
if (element is PsiEnumConstant) {
|
||||
JeEnumValueAnnotationValue(element)
|
||||
}
|
||||
else {
|
||||
JeErrorAnnotationValue(psi)
|
||||
}
|
||||
}
|
||||
is PsiExpression -> JeExpressionAnnotationValue(psi)
|
||||
else -> throw AssertionError("Unsupported annotation element value: $psi")
|
||||
}
|
||||
|
||||
private 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 {
|
||||
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 {
|
||||
override fun getValue() = psi.operand.type.toJeType()
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitType(value, p)
|
||||
}
|
||||
|
||||
private 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) {
|
||||
is String -> v.visitString(value, p)
|
||||
is Int -> v.visitInt(value, p)
|
||||
is Boolean -> v.visitBoolean(value, p)
|
||||
is Char -> v.visitChar(value, p)
|
||||
is Byte -> v.visitByte(value, p)
|
||||
is Short -> v.visitShort(value, p)
|
||||
is Long -> v.visitLong(value, p)
|
||||
is Float -> v.visitFloat(value, p)
|
||||
is Double -> v.visitDouble(value, p)
|
||||
else -> throw AssertionError("Bad annotation element value: $value")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private class JeLiteralAnnotationValue(val psi: PsiLiteral) : JePrimitiveAnnotationValue() {
|
||||
override fun getValue() = psi.value
|
||||
}
|
||||
|
||||
private class JeExpressionAnnotationValue(val psi: PsiExpression) : JePrimitiveAnnotationValue() {
|
||||
override fun getValue() = JavaPsiFacade.getInstance(psi.project).constantEvaluationHelper.computeConstantExpression(psi)
|
||||
}
|
||||
|
||||
private 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 {
|
||||
override fun <R : Any?, P : Any?> accept(v: AnnotationValueVisitor<R, P>, p: P) = v.visitString(psi.text, p)
|
||||
override fun getValue() = null
|
||||
}
|
||||
+71
@@ -0,0 +1,71 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.PsiClassInitializer
|
||||
import com.intellij.psi.PsiModifier
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.types.JeClassInitializerExecutableTypeMirror
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeClassInitializerExecutableElement(override val psi: PsiClassInitializer) : JeElement(),
|
||||
ExecutableElement, JeNoAnnotations, JeModifierListOwner
|
||||
{
|
||||
val isStaticInitializer = psi.hasModifierProperty(PsiModifier.STATIC)
|
||||
|
||||
override fun getEnclosingElement() = psi.containingClass?.let { JeTypeElement(it) }
|
||||
|
||||
override fun getSimpleName() = if (isStaticInitializer) JeName.CLINIT else JeName.EMPTY
|
||||
|
||||
override fun getThrownTypes() = emptyList<TypeMirror>()
|
||||
|
||||
override fun getTypeParameters() = emptyList<TypeParameterElement>()
|
||||
|
||||
override fun getParameters() = emptyList<VariableElement>()
|
||||
|
||||
override fun getDefaultValue() = null
|
||||
|
||||
override fun getReturnType() = JeNoneType
|
||||
|
||||
override fun getReceiverType() = JeNoneType
|
||||
|
||||
override fun isVarArgs() = false
|
||||
|
||||
override fun isDefault() = false
|
||||
|
||||
override fun getKind() = if (isStaticInitializer) ElementKind.STATIC_INIT else ElementKind.INSTANCE_INIT
|
||||
|
||||
override fun asType() = JeClassInitializerExecutableTypeMirror(psi)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
return psi == (other as JeClassInitializerExecutableElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.containingClass?.qualifiedName
|
||||
?.let { it + if (isStaticInitializer) ".<clinit>" else ".<instinit>" } ?: "<unnamed>"
|
||||
}
|
||||
+102
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.PsiAnnotationMethod
|
||||
import com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiModifier
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.types.JeMethodExecutableTypeMirror
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeMethodExecutableElement(override val psi: PsiMethod) : JeElement(), ExecutableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getEnclosingElement() = psi.containingClass?.let { JeTypeElement(it) }
|
||||
|
||||
override fun getSimpleName(): JeName {
|
||||
if (psi.isConstructor) return JeName.INIT
|
||||
return JeName(psi.name)
|
||||
}
|
||||
|
||||
override fun getThrownTypes() = psi.throwsList.referencedTypes.map { it.toJeType() }
|
||||
|
||||
override fun getTypeParameters() = psi.typeParameters.map { JeTypeParameterElement(it, this) }
|
||||
|
||||
override fun getParameters() = psi.parameterList.parameters.map { JeVariableElement(it) }
|
||||
|
||||
override fun getDefaultValue(): AnnotationValue? {
|
||||
val annotationMethod = psi as? PsiAnnotationMethod ?: return null
|
||||
val defaultValue = annotationMethod.defaultValue ?: return null
|
||||
return JeAnnotationValue(defaultValue)
|
||||
}
|
||||
|
||||
override fun getReturnType() = psi.returnType?.let { it.toJeType() } ?: JeNoneType
|
||||
|
||||
override fun getReceiverType() = psi.getReceiverTypeMirror()
|
||||
|
||||
override fun isVarArgs() = psi.isVarArgs
|
||||
|
||||
override fun isDefault() = psi.hasModifierProperty(PsiModifier.DEFAULT)
|
||||
|
||||
override fun getKind() = when {
|
||||
psi.isConstructor -> ElementKind.CONSTRUCTOR
|
||||
else -> ElementKind.METHOD
|
||||
}
|
||||
|
||||
override fun asType() = JeMethodExecutableTypeMirror(psi)
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
return psi == (other as JeMethodExecutableElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.name
|
||||
}
|
||||
|
||||
fun PsiMethod.getReceiverTypeMirror(): TypeMirror {
|
||||
if (hasModifierProperty(PsiModifier.STATIC)) return JeNoneType
|
||||
|
||||
if (isConstructor) {
|
||||
val containingClass = containingClass
|
||||
if (containingClass != null && !containingClass.hasModifierProperty(PsiModifier.STATIC)) {
|
||||
containingClass.containingClass?.let {
|
||||
return PsiTypesUtil.getClassType(it).toJeType()
|
||||
}
|
||||
}
|
||||
|
||||
return JeNoneType
|
||||
}
|
||||
|
||||
val containingClass = containingClass ?: return JeNoneType
|
||||
return PsiTypesUtil.getClassType(containingClass).toJeType()
|
||||
|
||||
}
|
||||
+55
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.PsiPackage
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.JeModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.JeName
|
||||
import org.jetbrains.kotlin.java.model.JeNoAnnotations
|
||||
import org.jetbrains.kotlin.java.model.types.JePackageTypeMirror
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.PackageElement
|
||||
|
||||
class JePackageElement(override val psi: PsiPackage) : JeElement(), PackageElement, JeModifierListOwner, JeNoAnnotations {
|
||||
override fun getEnclosingElement() = null
|
||||
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getKind() = ElementKind.PACKAGE
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitPackage(this, p)
|
||||
|
||||
override fun isUnnamed() = false
|
||||
|
||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||
|
||||
override fun getEnclosedElements() = psi.classes.map { JeTypeElement(it) }
|
||||
|
||||
override fun asType() = JePackageTypeMirror
|
||||
override fun equals(other: Any?): Boolean{
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
return psi == (other as JePackageElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.qualifiedName
|
||||
}
|
||||
+96
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.*
|
||||
import com.intellij.psi.util.ClassUtil
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.types.JeNoneType
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.*
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
class JeTypeElement(override val psi: PsiClass) : JeElement(), TypeElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
override fun getEnclosingElement(): Element? {
|
||||
psi.containingClass?.let { return JeTypeElement(it) }
|
||||
val javaFile = psi.containingFile as? PsiJavaFile ?: return null
|
||||
return JavaPsiFacade.getInstance(psi.project).findPackage(javaFile.packageName)?.let { JePackageElement(it) }
|
||||
}
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getQualifiedName() = JeName(psi.qualifiedName)
|
||||
|
||||
override fun getSuperclass(): TypeMirror {
|
||||
val superClass = psi.superClass ?: return JeNoneType
|
||||
return PsiTypesUtil.getClassType(superClass).toJeType()
|
||||
}
|
||||
|
||||
override fun getInterfaces() = psi.interfaces.map { PsiTypesUtil.getClassType(it).toJeType() }
|
||||
|
||||
override fun getTypeParameters() = psi.typeParameters.map { JeTypeParameterElement(it, this) }
|
||||
|
||||
override fun getNestingKind() = when {
|
||||
ClassUtil.isTopLevelClass(psi) -> NestingKind.TOP_LEVEL
|
||||
psi.parent is PsiClass -> NestingKind.MEMBER
|
||||
psi is PsiAnonymousClass -> NestingKind.ANONYMOUS
|
||||
else -> NestingKind.LOCAL
|
||||
}
|
||||
|
||||
override fun getEnclosedElements(): List<Element> {
|
||||
val declarations = mutableListOf<Element>()
|
||||
psi.initializers.forEach { declarations += JeClassInitializerExecutableElement(it) }
|
||||
psi.fields.forEach { declarations += JeVariableElement(it) }
|
||||
psi.methods.forEach { declarations += JeMethodExecutableElement(it) }
|
||||
psi.innerClasses.forEach { declarations += JeTypeElement(it) }
|
||||
return declarations
|
||||
}
|
||||
|
||||
fun getAllMembers(): List<Element> {
|
||||
val declarations = mutableListOf<Element>()
|
||||
psi.constructors.forEach { declarations += JeMethodExecutableElement(it) }
|
||||
psi.fields.forEach { declarations += JeVariableElement(it) }
|
||||
psi.methods.forEach { declarations += JeMethodExecutableElement(it) }
|
||||
return declarations
|
||||
}
|
||||
|
||||
override fun getKind() = when {
|
||||
psi.isEnum -> ElementKind.ENUM
|
||||
psi.isAnnotationType -> ElementKind.ANNOTATION_TYPE
|
||||
psi.isInterface -> ElementKind.INTERFACE
|
||||
else -> ElementKind.CLASS
|
||||
}
|
||||
|
||||
override fun asType() = PsiTypesUtil.getClassType(psi).toJeType()
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitType(this, p)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
return psi == (other as JeTypeElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.qualifiedName ?: psi.superClass?.qualifiedName ?: "<unnamed>"
|
||||
}
|
||||
+65
@@ -0,0 +1,65 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.PsiAnnotationOwner
|
||||
import com.intellij.psi.PsiTypeParameter
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.JeAnnotationOwner
|
||||
import org.jetbrains.kotlin.java.model.JeElement
|
||||
import org.jetbrains.kotlin.java.model.JeModifierListOwner
|
||||
import org.jetbrains.kotlin.java.model.JeName
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.TypeParameterElement
|
||||
|
||||
class JeTypeParameterElement(
|
||||
override val psi: PsiTypeParameter,
|
||||
val parent: JeElement?
|
||||
) : JeElement(), TypeParameterElement, JeAnnotationOwner, JeModifierListOwner {
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getEnclosingElement() = parent
|
||||
|
||||
override fun getKind() = ElementKind.TYPE_PARAMETER
|
||||
|
||||
override fun asType() = PsiTypesUtil.getClassType(psi).toJeType()
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitTypeParameter(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
|
||||
override fun getBounds() = psi.superTypes.map { it.toJeType() }
|
||||
|
||||
override fun getGenericElement() = parent
|
||||
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
return psi == (other as JeTypeParameterElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.name ?: "T"
|
||||
}
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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 com.intellij.psi.*
|
||||
import com.intellij.psi.util.PsiTreeUtil
|
||||
import org.jetbrains.kotlin.java.model.*
|
||||
import org.jetbrains.kotlin.java.model.types.toJeType
|
||||
import javax.lang.model.element.Element
|
||||
import javax.lang.model.element.ElementKind
|
||||
import javax.lang.model.element.ElementVisitor
|
||||
import javax.lang.model.element.VariableElement
|
||||
|
||||
class JeVariableElement(override val psi: PsiVariable) : JeElement(), VariableElement, JeModifierListOwner, JeAnnotationOwner {
|
||||
override fun getSimpleName() = JeName(psi.name)
|
||||
|
||||
override fun getEnclosingElement(): JeTypeElement? {
|
||||
val containingClass = (psi as? PsiMember)?.containingClass ?: PsiTreeUtil.getParentOfType(psi, PsiClass::class.java)
|
||||
return containingClass?.let { JeTypeElement(it) }
|
||||
}
|
||||
|
||||
override fun getConstantValue(): Any? {
|
||||
val initializer = psi.initializer ?: return null
|
||||
val evaluationHelper = JavaPsiFacade.getInstance(psi.project).constantEvaluationHelper
|
||||
return evaluationHelper.computeConstantExpression(initializer)
|
||||
}
|
||||
|
||||
override fun getKind() = when (psi) {
|
||||
is PsiField -> ElementKind.FIELD
|
||||
is PsiParameter -> ElementKind.PARAMETER
|
||||
else -> ElementKind.LOCAL_VARIABLE
|
||||
}
|
||||
|
||||
override fun asType() = psi.type.toJeType()
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: ElementVisitor<R, P>, p: P) = v.visitVariable(this, p)
|
||||
|
||||
override fun getEnclosedElements() = emptyList<Element>()
|
||||
override val annotationOwner: PsiAnnotationOwner?
|
||||
get() = psi.modifierList
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
return psi == (other as JeVariableElement).psi
|
||||
}
|
||||
|
||||
override fun hashCode() = psi.hashCode()
|
||||
|
||||
override fun toString() = psi.name ?: "<unnamed>"
|
||||
}
|
||||
+272
@@ -0,0 +1,272 @@
|
||||
/*
|
||||
* 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.internal
|
||||
|
||||
import com.intellij.psi.*
|
||||
import org.jetbrains.kotlin.asJava.KtLightAnnotation
|
||||
import org.jetbrains.org.objectweb.asm.ClassWriter
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes.*
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
import java.net.URL
|
||||
import java.net.URLClassLoader
|
||||
|
||||
internal fun createAnnotation(
|
||||
annotation: PsiAnnotation,
|
||||
annotationDeclaration: PsiClass,
|
||||
annotationClass: Class<*>
|
||||
): Annotation? {
|
||||
val qualifiedName = annotationDeclaration.qualifiedName ?: return null
|
||||
val implQualifiedName = "stub." + qualifiedName + ".Impl" + Integer.toHexString(annotation.text.hashCode())
|
||||
|
||||
val annotationInternalName = annotationDeclaration.getInternalName()
|
||||
val implInternalName = implQualifiedName.replace('.', '/')
|
||||
|
||||
val bytes = createAnnotationImplementationClass(annotation, annotationDeclaration, annotationInternalName, implInternalName)
|
||||
return loadClass(implQualifiedName, bytes, annotationClass)?.newInstance() as? Annotation
|
||||
}
|
||||
|
||||
private fun createAnnotationImplementationClass(
|
||||
annotation: PsiAnnotation,
|
||||
annotationDeclaration: PsiClass,
|
||||
annotationInternalName: String,
|
||||
implInternalName: String
|
||||
): ByteArray {
|
||||
return ClassWriter(ClassWriter.COMPUTE_FRAMES or ClassWriter.COMPUTE_MAXS).apply {
|
||||
visit(V1_6, ACC_SUPER or ACC_PUBLIC, implInternalName, null, "java/lang/Object", arrayOf(annotationInternalName))
|
||||
|
||||
with(visitMethod(ACC_PUBLIC, "<init>", "()V", null, null)) {
|
||||
visitCode()
|
||||
visitVarInsn(ALOAD, 0)
|
||||
visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "<init>", "()V", false)
|
||||
visitInsn(RETURN)
|
||||
visitMaxs(-1, -1)
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
with(visitMethod(ACC_PUBLIC, "annotationType", "()Ljava/lang/Class;",
|
||||
"()Ljava/lang/Class<+Ljava/lang/annotation/Annotation;>;", null)) {
|
||||
visitCode()
|
||||
visitLdcInsn(Type.getType("L$annotationInternalName;"))
|
||||
visitInsn(ARETURN)
|
||||
visitMaxs(-1, -1)
|
||||
visitEnd()
|
||||
}
|
||||
|
||||
if (annotationDeclaration.allMethods.isNotEmpty()) {
|
||||
val evaluator = JavaPsiFacade.getInstance(annotation.project).constantEvaluationHelper
|
||||
|
||||
for (method in annotationDeclaration.methods) {
|
||||
if (method !is PsiAnnotationMethod) continue
|
||||
|
||||
if (method.returnType == null) continue
|
||||
val returnType = method.returnType!!
|
||||
|
||||
val value = annotation.findAttributeValue(method.name) ?: method.defaultValue
|
||||
|
||||
when (returnType) {
|
||||
PsiType.VOID -> unexpectedType("void")
|
||||
PsiType.NULL -> unexpectedType("null")
|
||||
is PsiClassType -> {
|
||||
val resolvedClass = returnType.resolve()
|
||||
val resolvedQualifiedName = resolvedClass?.qualifiedName
|
||||
if (resolvedQualifiedName == "java.lang.String") {
|
||||
writeStringMethod(method, calculateConstantValue(value, evaluator))
|
||||
}
|
||||
else if (resolvedClass != null && resolvedClass.isEnum) {
|
||||
writeEnumMethod(method, resolvedClass, value)
|
||||
}
|
||||
else {
|
||||
unexpectedType("$resolvedQualifiedName")
|
||||
}
|
||||
}
|
||||
is PsiPrimitiveType -> writeLiteralMethod(method, calculateConstantValue(value, evaluator))
|
||||
is PsiArrayType -> writeArrayMethod(method, value, evaluator)
|
||||
else -> unexpectedType(returnType)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
visitEnd()
|
||||
}.toByteArray()
|
||||
}
|
||||
|
||||
private fun ClassWriter.writeEnumMethod(method: PsiAnnotationMethod, enumClass: PsiClass, value: PsiAnnotationMemberValue?) {
|
||||
val enumInternalName = enumClass.getInternalName()
|
||||
val enumConstant = (value?.originalElement as? PsiReference)?.resolve() as? PsiEnumConstant ?: return
|
||||
|
||||
val mv = visitMethod(ACC_PUBLIC, method.name, "()L$enumInternalName;", null, null)
|
||||
|
||||
with (InstructionAdapter(mv)) {
|
||||
visitCode()
|
||||
|
||||
getstatic(enumInternalName, enumConstant.name!!, "L$enumInternalName;")
|
||||
visitInsn(ARETURN)
|
||||
|
||||
visitMaxs(-1 ,-1)
|
||||
visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassWriter.writeStringMethod(method: PsiAnnotationMethod, value: Any?) {
|
||||
val stringValue = (value as? String) ?: null
|
||||
|
||||
val mv = visitMethod(ACC_PUBLIC, method.name, "()Ljava/lang/String;", null, null)
|
||||
|
||||
with (InstructionAdapter(mv)) {
|
||||
visitCode()
|
||||
|
||||
if (stringValue != null) {
|
||||
visitLdcInsn(stringValue)
|
||||
} else {
|
||||
visitInsn(ACONST_NULL)
|
||||
}
|
||||
visitInsn(ARETURN)
|
||||
|
||||
visitMaxs(-1 ,-1)
|
||||
visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
private fun ClassWriter.writeArrayMethod(
|
||||
method: PsiAnnotationMethod,
|
||||
value: PsiAnnotationMemberValue?,
|
||||
evaluator: PsiConstantEvaluationHelper
|
||||
) {
|
||||
val componentType = (method.returnType as? PsiArrayType)?.componentType ?: return
|
||||
val componentAsmType = componentType.toAsmType() ?: return
|
||||
|
||||
val initializers = (value as? PsiArrayInitializerMemberValue)?.initializers ?: emptyArray()
|
||||
|
||||
val mv = visitMethod(ACC_PUBLIC, method.name, "()[" + componentAsmType.descriptor, null, null)
|
||||
|
||||
with (InstructionAdapter(mv)) {
|
||||
visitCode()
|
||||
|
||||
iconst(initializers.size)
|
||||
newarray(componentAsmType)
|
||||
|
||||
initializers.forEachIndexed { index, value ->
|
||||
val valueObject = calculateConstantValue(value, evaluator)
|
||||
|
||||
dup()
|
||||
iconst(index)
|
||||
putValue(componentAsmType, valueObject)
|
||||
astore(componentAsmType)
|
||||
}
|
||||
|
||||
visitInsn(ARETURN)
|
||||
visitMaxs(-1, -1)
|
||||
visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
private fun calculateConstantValue(value: PsiAnnotationMemberValue?, evaluator: PsiConstantEvaluationHelper) = when (value) {
|
||||
is PsiLiteral -> value.value
|
||||
is KtLightAnnotation.LightExpressionValue<*> -> value.getConstantValue()
|
||||
is PsiExpression -> evaluator.computeConstantExpression(value)
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun InstructionAdapter.putValue(type: Type, value: Any?) = when (type) {
|
||||
Type.DOUBLE_TYPE -> dconst(doubleValue(value))
|
||||
Type.FLOAT_TYPE -> fconst(floatValue(value))
|
||||
Type.LONG_TYPE -> lconst(longValue(value))
|
||||
Type.BYTE_TYPE, Type.SHORT_TYPE, Type.INT_TYPE, Type.CHAR_TYPE, Type.BOOLEAN_TYPE -> iconst(type.castValue(value))
|
||||
else -> aconst(value)
|
||||
}
|
||||
|
||||
private fun ClassWriter.writeLiteralMethod(method: PsiAnnotationMethod, value: Any?) {
|
||||
val returnType = method.returnType ?: return
|
||||
val asmType = returnType.toAsmType() ?: return
|
||||
|
||||
val mv = visitMethod(ACC_PUBLIC, method.name, "()" + asmType.descriptor, null, null)
|
||||
with (InstructionAdapter(mv)) {
|
||||
visitCode()
|
||||
|
||||
putValue(asmType, value)
|
||||
areturn(asmType)
|
||||
|
||||
visitMaxs(-1, -1)
|
||||
visitEnd()
|
||||
}
|
||||
}
|
||||
|
||||
private fun PsiType.toAsmType(): Type? = when (this) {
|
||||
PsiType.BYTE -> Type.BYTE_TYPE
|
||||
PsiType.SHORT -> Type.SHORT_TYPE
|
||||
PsiType.INT -> Type.INT_TYPE
|
||||
PsiType.CHAR -> Type.CHAR_TYPE
|
||||
PsiType.BOOLEAN -> Type.BOOLEAN_TYPE
|
||||
PsiType.LONG -> Type.LONG_TYPE
|
||||
PsiType.FLOAT -> Type.FLOAT_TYPE
|
||||
PsiType.DOUBLE -> Type.DOUBLE_TYPE
|
||||
is PsiClassType -> resolve()?.let { Type.getObjectType(it.getInternalName()) }
|
||||
else -> null
|
||||
}
|
||||
|
||||
private fun Type.castValue(value: Any?): Int = when (this) {
|
||||
Type.BYTE_TYPE -> byteValue(value)
|
||||
Type.SHORT_TYPE -> shortValue(value)
|
||||
Type.INT_TYPE -> intValue(value)
|
||||
Type.CHAR_TYPE -> charValue(value)
|
||||
Type.BOOLEAN_TYPE -> booleanValue(value)
|
||||
else -> unexpectedType(this)
|
||||
}
|
||||
|
||||
private fun PsiClass.getInternalName(): String {
|
||||
val containingClass = this.containingClass
|
||||
return if (containingClass != null) {
|
||||
containingClass.getInternalName() + "$" + this.name
|
||||
} else {
|
||||
qualifiedName?.replace('.', '/') ?: error("Invalid class name ($this)")
|
||||
}
|
||||
}
|
||||
|
||||
private fun byteValue(value: Any?): Int = (value as? Number)?.toByte()?.toInt() ?: 0
|
||||
private fun intValue(value: Any?): Int = (value as? Number)?.toInt() ?: 0
|
||||
private fun shortValue(value: Any?): Int = (value as? Number)?.toShort()?.toInt() ?: 0
|
||||
private fun booleanValue(value: Any?): Int = if (value == true) 1 else 0
|
||||
private fun charValue(value: Any?): Int = (value as? Char)?.toInt() ?: 0.toChar().toInt()
|
||||
|
||||
private fun longValue(value: Any?): Long = (value as? Number)?.toLong() ?: 0
|
||||
private fun floatValue(value: Any?): Float = (value as? Number)?.toFloat() ?: 0f
|
||||
private fun doubleValue(value: Any?): Double = (value as? Number)?.toDouble() ?: 0.0
|
||||
|
||||
private fun loadClass(fqName: String, bytes: ByteArray, annotationClass: Class<*>): Class<*>? {
|
||||
class ByteClassLoader(
|
||||
urls: Array<out URL>?,
|
||||
parent: ClassLoader?,
|
||||
val extraClasses: MutableMap<String, ByteArray>,
|
||||
predefinedClasses: List<Class<*>>
|
||||
) : URLClassLoader(urls, parent) {
|
||||
private val predefinedClasses = predefinedClasses.associateBy { it.canonicalName }
|
||||
|
||||
override fun findClass(name: String): Class<*>? {
|
||||
return extraClasses.remove(name)?.let {
|
||||
defineClass(name, it, 0, it.size)
|
||||
} ?: predefinedClasses[name] ?: super.findClass(name)
|
||||
}
|
||||
}
|
||||
|
||||
val classLoader = ByteClassLoader(emptyArray(), annotationClass.classLoader, hashMapOf(fqName to bytes), listOf())
|
||||
return Class.forName(fqName, false, classLoader)
|
||||
}
|
||||
|
||||
private fun unexpectedType(type: String): Nothing = error("Unexpected type: $type")
|
||||
private fun unexpectedType(type: PsiType): Nothing = unexpectedType(type.presentableText)
|
||||
private fun unexpectedType(type: Type): Nothing = unexpectedType(type.descriptor)
|
||||
+45
@@ -0,0 +1,45 @@
|
||||
/*
|
||||
* 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.internal
|
||||
|
||||
import com.intellij.psi.PsiModifier.*
|
||||
import com.intellij.psi.PsiModifierList
|
||||
import com.intellij.psi.PsiModifierListOwner
|
||||
import javax.lang.model.element.Modifier
|
||||
|
||||
private fun PsiModifierList.getJavaModifiers(): Set<Modifier> {
|
||||
fun MutableSet<Modifier>.check(modifier: String, javaModifier: Modifier) {
|
||||
if (hasModifierProperty(modifier)) this += javaModifier
|
||||
}
|
||||
|
||||
return mutableSetOf<Modifier>().apply {
|
||||
check(PUBLIC, Modifier.PUBLIC)
|
||||
check(PROTECTED, Modifier.PROTECTED)
|
||||
check(PRIVATE, Modifier.PRIVATE)
|
||||
check(STATIC, Modifier.STATIC)
|
||||
check(ABSTRACT, Modifier.ABSTRACT)
|
||||
check(FINAL, Modifier.FINAL)
|
||||
check(NATIVE, Modifier.NATIVE)
|
||||
check(SYNCHRONIZED, Modifier.SYNCHRONIZED)
|
||||
check(STRICTFP, Modifier.STRICTFP)
|
||||
check(TRANSIENT, Modifier.TRANSIENT)
|
||||
check(VOLATILE, Modifier.VOLATILE)
|
||||
check(DEFAULT, Modifier.DEFAULT)
|
||||
}
|
||||
}
|
||||
|
||||
fun PsiModifierListOwner.getJavaModifiers() = modifierList?.getJavaModifiers() ?: emptySet()
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiType
|
||||
|
||||
abstract class JeAbstractType : JeTypeBase() {
|
||||
abstract val psiType: PsiType
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
other as JeAbstractType
|
||||
|
||||
if (kind != other.kind) return false
|
||||
if (psiType != other.psiType) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int{
|
||||
var result = kind.hashCode()
|
||||
result = 31 * result + psiType.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiArrayType
|
||||
import javax.lang.model.type.ArrayType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeArrayType(override val psiType: PsiArrayType) : JeAbstractType(), ArrayType {
|
||||
override fun getKind() = TypeKind.ARRAY
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitArray(this, p)
|
||||
override fun getComponentType() = psiType.componentType.toJeType()
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
if (!super.equals(other)) return false
|
||||
|
||||
return psiType == (other as JeArrayType).psiType
|
||||
}
|
||||
|
||||
override fun hashCode(): Int{
|
||||
var result = super.hashCode()
|
||||
result = 31 * result + psiType.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString() = psiType.getCanonicalText(false)
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiClassInitializer
|
||||
import com.intellij.psi.PsiModifier
|
||||
import javax.lang.model.type.*
|
||||
|
||||
class JeClassInitializerExecutableTypeMirror(val initializer: PsiClassInitializer) : JeTypeBase(), ExecutableType {
|
||||
override fun getKind() = TypeKind.EXECUTABLE
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getReturnType() = CustomJeNoneType(TypeKind.VOID)
|
||||
|
||||
override fun getReceiverType() = JeNoneType
|
||||
|
||||
override fun getThrownTypes() = emptyList<TypeMirror>()
|
||||
|
||||
override fun getParameterTypes() = emptyList<TypeMirror>()
|
||||
|
||||
override fun getTypeVariables() = emptyList<TypeVariable>()
|
||||
|
||||
override fun toString() = (initializer.containingClass?.qualifiedName?.let { it + "." } ?: "") +
|
||||
(if (initializer.hasModifierProperty(PsiModifier.STATIC)) "<clinit>" else "<init>")
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
return initializer == (other as JeClassInitializerExecutableTypeMirror).initializer
|
||||
}
|
||||
|
||||
override fun hashCode() = initializer.hashCode()
|
||||
}
|
||||
+64
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiType
|
||||
import javax.lang.model.element.TypeElement
|
||||
import javax.lang.model.type.DeclaredType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeCompoundDeclaredType(
|
||||
val psiClass: PsiClass,
|
||||
val baseType: TypeElement,
|
||||
val enclosingTypeMirror: TypeMirror?,
|
||||
val typeArgs: List<PsiType>,
|
||||
val typeArgMirrors: List<TypeMirror>
|
||||
) : JeTypeBase(), DeclaredType {
|
||||
override fun getKind() = TypeKind.DECLARED
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitDeclared(this, p)
|
||||
|
||||
override fun getTypeArguments() = typeArgMirrors
|
||||
override fun asElement() = baseType
|
||||
override fun getEnclosingType() = enclosingTypeMirror ?: JeNoneType
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
|
||||
other as JeCompoundDeclaredType
|
||||
|
||||
if (baseType != other.baseType) return false
|
||||
if (enclosingTypeMirror != other.enclosingTypeMirror) return false
|
||||
if (typeArgs != other.typeArgs) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int{
|
||||
var result = baseType.hashCode()
|
||||
result = 31 * result + (enclosingTypeMirror?.hashCode() ?: 0)
|
||||
result = 31 * result + typeArgs.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String {
|
||||
return baseType.toString() + typeArgs.joinToString(prefix = "<", postfix = ">")
|
||||
}
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiClass
|
||||
import com.intellij.psi.PsiClassType
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeElement
|
||||
import javax.lang.model.type.DeclaredType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeDeclaredType(override val psiType: PsiClassType, val psiClass: PsiClass) : JeAbstractType(), DeclaredType {
|
||||
override fun getKind() = TypeKind.DECLARED
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitDeclared(this, p)
|
||||
|
||||
override fun getTypeArguments() = psiType.parameters.map { it.toJeType() }
|
||||
|
||||
override fun asElement() = JeTypeElement(psiClass)
|
||||
|
||||
override fun getEnclosingType(): TypeMirror {
|
||||
val psiClass = psiClass.containingClass ?: return JeNoneType
|
||||
return PsiTypesUtil.getClassType(psiClass).toJeType()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean{
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
if (!super.equals(other)) return false
|
||||
|
||||
return psiType == (other as JeDeclaredType).psiType
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = super.hashCode()
|
||||
result = 31 * result + psiType.hashCode()
|
||||
return result
|
||||
}
|
||||
|
||||
override fun toString(): String = psiType.getCanonicalText(false)
|
||||
}
|
||||
+28
@@ -0,0 +1,28 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiIntersectionType
|
||||
import javax.lang.model.type.IntersectionType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeIntersectionType(override val psiType: PsiIntersectionType) : JeAbstractType(), IntersectionType {
|
||||
override fun getKind() = TypeKind.INTERSECTION
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitIntersection(this, p)
|
||||
override fun getBounds() = psiType.superTypes.map { it.toJeType() }
|
||||
}
|
||||
+63
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiMethod
|
||||
import com.intellij.psi.PsiType
|
||||
import com.intellij.psi.util.MethodSignature
|
||||
import com.intellij.psi.util.PsiTypesUtil
|
||||
import org.jetbrains.kotlin.java.model.elements.getReceiverTypeMirror
|
||||
import javax.lang.model.type.ExecutableType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeMethodExecutableTypeMirror(
|
||||
val method: PsiMethod,
|
||||
val signature: MethodSignature? = null,
|
||||
val returnType: PsiType? = null
|
||||
) : JeTypeBase(), ExecutableType {
|
||||
override fun getKind() = TypeKind.EXECUTABLE
|
||||
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitExecutable(this, p)
|
||||
|
||||
override fun getReturnType() = (returnType ?: method.returnType)?.let { it.toJeType() } ?: CustomJeNoneType(TypeKind.VOID)
|
||||
|
||||
override fun getReceiverType() = method.getReceiverTypeMirror()
|
||||
|
||||
override fun getThrownTypes() = method.throwsList.referencedTypes.map { it.toJeType() }
|
||||
|
||||
override fun getParameterTypes(): List<TypeMirror> {
|
||||
signature?.parameterTypes?.let { types -> return types.map { it.toJeType() } }
|
||||
return method.parameterList.parameters.map { it.type.toJeType() }
|
||||
}
|
||||
|
||||
override fun getTypeVariables(): List<JeTypeVariableType> {
|
||||
val typeParameters = signature?.typeParameters ?: method.typeParameters
|
||||
return typeParameters.map { JeTypeVariableType(PsiTypesUtil.getClassType(it), it) }
|
||||
}
|
||||
|
||||
override fun toString() = (method.containingClass?.qualifiedName?.let { it + "." } ?: "") + method.name
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
return method == (other as JeMethodExecutableTypeMirror).method
|
||||
}
|
||||
|
||||
override fun hashCode() = method.hashCode()
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiType
|
||||
import javax.lang.model.type.NullType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
object JeNullType : JeAbstractType(), NullType {
|
||||
override fun getKind() = TypeKind.NULL
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNull(this, p)
|
||||
override val psiType = PsiType.NULL
|
||||
override fun toString() = "null"
|
||||
}
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiPrimitiveType
|
||||
import com.intellij.psi.PsiType
|
||||
import javax.lang.model.type.PrimitiveType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JePrimitiveType(override val psiType: PsiPrimitiveType) : JeAbstractType(), PrimitiveType {
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitPrimitive(this, p)
|
||||
|
||||
override fun getKind() = when (psiType) {
|
||||
PsiType.BYTE -> TypeKind.BYTE
|
||||
PsiType.CHAR -> TypeKind.CHAR
|
||||
PsiType.DOUBLE -> TypeKind.DOUBLE
|
||||
PsiType.FLOAT -> TypeKind.FLOAT
|
||||
PsiType.INT -> TypeKind.INT
|
||||
PsiType.LONG -> TypeKind.LONG
|
||||
PsiType.SHORT -> TypeKind.SHORT
|
||||
PsiType.BOOLEAN -> TypeKind.BOOLEAN
|
||||
PsiType.VOID -> TypeKind.VOID
|
||||
else -> TypeKind.ERROR
|
||||
}
|
||||
|
||||
override fun toString() = psiType.canonicalText
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
if (!super.equals(other)) return false
|
||||
|
||||
return psiType === (other as JePrimitiveType).psiType
|
||||
}
|
||||
|
||||
override fun hashCode(): Int{
|
||||
var result = super.hashCode()
|
||||
result = 31 * result + psiType.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import javax.lang.model.element.AnnotationMirror
|
||||
import javax.lang.model.type.TypeMirror
|
||||
|
||||
//TODO support type annotations
|
||||
abstract class JeTypeBase : TypeMirror {
|
||||
override fun getAnnotationMirrors() = emptyList<AnnotationMirror>()
|
||||
|
||||
override fun <A : Annotation> getAnnotation(annotationClass: Class<A>?) = null
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun <A : Annotation?> getAnnotationsByType(annotationType: Class<A>): Array<A> {
|
||||
return java.lang.reflect.Array.newInstance(annotationType, 0) as Array<A>
|
||||
}
|
||||
}
|
||||
+46
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import org.jetbrains.kotlin.java.model.JeConverter
|
||||
import org.jetbrains.kotlin.java.model.elements.JeTypeParameterElement
|
||||
import com.intellij.psi.*
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import javax.lang.model.type.TypeVariable
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
|
||||
class JeTypeVariableType(override val psiType: PsiClassType, val parameter: PsiTypeParameter) : JeAbstractType(), TypeVariable {
|
||||
override fun getKind() = TypeKind.TYPEVAR
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitTypeVariable(this, p)
|
||||
|
||||
override fun getLowerBound(): TypeMirror? {
|
||||
//TODO support captured lower bounds
|
||||
return JeNullType
|
||||
}
|
||||
|
||||
override fun getUpperBound(): TypeMirror? {
|
||||
val superTypes = parameter.superTypes
|
||||
return if (superTypes.size == 1) {
|
||||
superTypes.first().toJeType(psiManager)
|
||||
} else {
|
||||
PsiIntersectionType.createIntersection(*superTypes).toJeType(psiManager)
|
||||
}
|
||||
}
|
||||
|
||||
override fun asElement() = JeTypeParameterElement(parameter, JeConverter.convert(parameter.owner))
|
||||
}
|
||||
+50
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import com.intellij.psi.PsiWildcardType
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import javax.lang.model.type.TypeVisitor
|
||||
import javax.lang.model.type.WildcardType
|
||||
|
||||
class JeWildcardType(override val psiType: PsiWildcardType) : JeAbstractType(), WildcardType {
|
||||
override fun getKind() = TypeKind.WILDCARD
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitWildcard(this, p)
|
||||
override fun getSuperBound() = psiType.superBound.toJeType()
|
||||
override fun getExtendsBound() = psiType.extendsBound.toJeType()
|
||||
override fun equals(other: Any?): Boolean{
|
||||
if (this === other) return true
|
||||
if (other?.javaClass != javaClass) return false
|
||||
if (!super.equals(other)) return false
|
||||
|
||||
return psiType == (other as JeWildcardType).psiType
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = super.hashCode()
|
||||
result = 31 * result + psiType.hashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
|
||||
class JeWildcardTypeWithBounds(private val extendsType: TypeMirror, private val superType: TypeMirror) : JeTypeBase(), WildcardType {
|
||||
override fun getKind() = TypeKind.WILDCARD
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitWildcard(this, p)
|
||||
override fun getSuperBound() = superType
|
||||
override fun getExtendsBound() = extendsType
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* 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.types
|
||||
|
||||
import javax.lang.model.type.*
|
||||
|
||||
object JePackageTypeMirror : JeTypeBase(), NoType {
|
||||
override fun getKind() = TypeKind.PACKAGE
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNoType(this, p)
|
||||
}
|
||||
|
||||
object JeNoneType : JeTypeBase(), NoType {
|
||||
override fun getKind() = TypeKind.NONE
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNoType(this, p)
|
||||
}
|
||||
|
||||
object JeVoidType : JeTypeBase(), NoType {
|
||||
override fun getKind() = TypeKind.VOID
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNoType(this, p)
|
||||
}
|
||||
|
||||
class CustomJeNoneType(private val _kind: TypeKind) : JeTypeBase(), NoType {
|
||||
override fun getKind() = _kind
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNoType(this, p)
|
||||
}
|
||||
|
||||
object JeErrorType : JeTypeBase(), NoType {
|
||||
override fun getKind() = TypeKind.ERROR
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNoType(this, p)
|
||||
}
|
||||
|
||||
object JeDeclaredErrorType : JeTypeBase(), DeclaredType, NoType {
|
||||
override fun getKind() = TypeKind.ERROR
|
||||
override fun <R : Any?, P : Any?> accept(v: TypeVisitor<R, P>, p: P) = v.visitNoType(this, p)
|
||||
|
||||
override fun getTypeArguments() = emptyList<TypeMirror>()
|
||||
override fun asElement() = null
|
||||
override fun getEnclosingType() = JeNoneType
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@file:JvmName("JeTypeUtils")
|
||||
package org.jetbrains.kotlin.java.model.types
|
||||
|
||||
import com.intellij.psi.*
|
||||
import javax.lang.model.type.TypeKind
|
||||
import javax.lang.model.type.TypeMirror
|
||||
import java.lang.reflect.Array as RArray
|
||||
|
||||
private val PSI_PRIMITIVES_MAP = listOf(
|
||||
PsiType.BYTE, PsiType.CHAR, PsiType.DOUBLE,
|
||||
PsiType.FLOAT, PsiType.INT, PsiType.LONG,
|
||||
PsiType.SHORT, PsiType.BOOLEAN).associate { it to JePrimitiveType(it) }
|
||||
|
||||
private val TYPE_KIND_TO_PSI_PRIMITIVE_MAP = mapOf(
|
||||
TypeKind.BYTE to PsiType.BYTE,
|
||||
TypeKind.CHAR to PsiType.CHAR,
|
||||
TypeKind.DOUBLE to PsiType.DOUBLE,
|
||||
TypeKind.FLOAT to PsiType.FLOAT,
|
||||
TypeKind.INT to PsiType.INT,
|
||||
TypeKind.LONG to PsiType.LONG,
|
||||
TypeKind.SHORT to PsiType.SHORT,
|
||||
TypeKind.BOOLEAN to PsiType.BOOLEAN)
|
||||
|
||||
fun TypeKind?.toJePrimitiveType() = PSI_PRIMITIVES_MAP[TYPE_KIND_TO_PSI_PRIMITIVE_MAP[this]]
|
||||
|
||||
fun PsiType.toJePrimitiveType() = PSI_PRIMITIVES_MAP[this]
|
||||
|
||||
fun PsiType.toJeType(): TypeMirror = when (this) {
|
||||
PsiType.VOID -> JeVoidType
|
||||
PsiType.NULL -> JeNullType
|
||||
is PsiPrimitiveType -> PSI_PRIMITIVES_MAP[this] ?: JeErrorType
|
||||
is PsiArrayType -> JeArrayType(this)
|
||||
is PsiWildcardType -> JeWildcardType(this)
|
||||
is PsiClassType -> {
|
||||
val resolvedClass = this.resolve()
|
||||
when (resolvedClass) {
|
||||
is PsiTypeParameter -> JeTypeVariableType(this, resolvedClass)
|
||||
is PsiClass -> JeDeclaredType(this, resolvedClass)
|
||||
else -> JeErrorType
|
||||
}
|
||||
}
|
||||
is PsiIntersectionType -> JeIntersectionType(this)
|
||||
else -> JeErrorType
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user