diff --git a/plugins/java-model-wrappers/java-model-wrappers.iml b/plugins/java-model-wrappers/java-model-wrappers.iml
new file mode 100755
index 00000000000..3ebc8d39248
--- /dev/null
+++ b/plugins/java-model-wrappers/java-model-wrappers.iml
@@ -0,0 +1,17 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt
new file mode 100644
index 00000000000..7adb4e02233
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeAnnotationOwner.kt
@@ -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 getAnnotation(annotationClass: Class): 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 getAnnotationsByType(annotationType: Class): Array {
+ return RArray.newInstance(annotationType, 0) as Array
+ }
+}
+
+interface JeNoAnnotations : Element {
+ override fun getAnnotationMirrors() = emptyList()
+
+ override fun getAnnotation(annotationClass: Class?): Nothing? {
+ return null
+ }
+
+ @Suppress("UNCHECKED_CAST")
+ override fun getAnnotationsByType(annotationType: Class): Array {
+ return RArray.newInstance(annotationType, 0) as Array
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt
new file mode 100644
index 00000000000..3f236dc54c8
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeConverter.kt
@@ -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
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeElement.kt
new file mode 100644
index 00000000000..8ddcbac797f
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeElement.kt
@@ -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
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeModifierListOwner.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeModifierListOwner.kt
new file mode 100644
index 00000000000..22b24c52436
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeModifierListOwner.kt
@@ -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()
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeName.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeName.kt
new file mode 100644
index 00000000000..472675535cb
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/JeName.kt
@@ -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("")
+ val CLINIT = JeName("")
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt
new file mode 100644
index 00000000000..76c9b8f69cf
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationMirror.kt
@@ -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 {
+ val annotationClass = resolveAnnotationClass() ?: return emptyMap()
+
+ return mutableMapOf().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 {
+ val annotationClass = resolveAnnotationClass() ?: return emptyMap()
+
+ return mutableMapOf().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
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationValue.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationValue.kt
new file mode 100644
index 00000000000..dd3e7d19d12
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeAnnotationValue.kt
@@ -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 accept(v: AnnotationValueVisitor, p: P) = v.visitAnnotation(value, p)
+}
+
+private class JeEnumValueAnnotationValue(val psi: PsiEnumConstant) : AnnotationValue {
+ override fun getValue() = JeVariableElement(psi)
+ override fun accept(v: AnnotationValueVisitor, p: P) = v.visitEnumConstant(value, p)
+}
+
+private class JeTypeAnnotationValue(val psi: PsiClassObjectAccessExpression) : AnnotationValue {
+ override fun getValue() = psi.operand.type.toJeType()
+ override fun accept(v: AnnotationValueVisitor, p: P) = v.visitType(value, p)
+}
+
+private abstract class JePrimitiveAnnotationValue : AnnotationValue {
+ override fun accept(v: AnnotationValueVisitor, 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 accept(v: AnnotationValueVisitor, p: P) = v.visitArray(value, p)
+}
+
+private class JeErrorAnnotationValue(val psi: PsiElement) : AnnotationValue {
+ override fun accept(v: AnnotationValueVisitor, p: P) = v.visitString(psi.text, p)
+ override fun getValue() = null
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt
new file mode 100644
index 00000000000..720498b9899
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeClassInitializerExecutableElement.kt
@@ -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()
+
+ override fun getTypeParameters() = emptyList()
+
+ override fun getParameters() = emptyList()
+
+ 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 accept(v: ElementVisitor, p: P) = v.visitExecutable(this, p)
+
+ override fun getEnclosedElements() = emptyList()
+
+ 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) "." else "." } ?: ""
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt
new file mode 100644
index 00000000000..ca6220d14e6
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeMethodExecutableElement.kt
@@ -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 accept(v: ElementVisitor, p: P) = v.visitExecutable(this, p)
+
+ override fun getEnclosedElements() = emptyList()
+
+ 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()
+
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt
new file mode 100644
index 00000000000..31b79e09cf4
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JePackageElement.kt
@@ -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 accept(v: ElementVisitor, 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
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt
new file mode 100644
index 00000000000..d03f1a867a0
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeElement.kt
@@ -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 {
+ val declarations = mutableListOf()
+ 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 {
+ val declarations = mutableListOf()
+ 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 accept(v: ElementVisitor, 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 ?: ""
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt
new file mode 100644
index 00000000000..b4556b7805a
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeTypeParameterElement.kt
@@ -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 accept(v: ElementVisitor, p: P) = v.visitTypeParameter(this, p)
+
+ override fun getEnclosedElements() = emptyList()
+
+ 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"
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt
new file mode 100644
index 00000000000..8aa287b81e8
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/elements/JeVariableElement.kt
@@ -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 accept(v: ElementVisitor, p: P) = v.visitVariable(this, p)
+
+ override fun getEnclosedElements() = emptyList()
+ 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 ?: ""
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/annotationStubFactory.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/annotationStubFactory.kt
new file mode 100644
index 00000000000..e712b450525
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/annotationStubFactory.kt
@@ -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, "", "()V", null, null)) {
+ visitCode()
+ visitVarInsn(ALOAD, 0)
+ visitMethodInsn(INVOKESPECIAL, "java/lang/Object", "", "()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?,
+ parent: ClassLoader?,
+ val extraClasses: MutableMap,
+ predefinedClasses: List>
+ ) : 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)
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt
new file mode 100644
index 00000000000..42386072568
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/internal/internalUtil.kt
@@ -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 {
+ fun MutableSet.check(modifier: String, javaModifier: Modifier) {
+ if (hasModifierProperty(modifier)) this += javaModifier
+ }
+
+ return mutableSetOf().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()
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeAbstractType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeAbstractType.kt
new file mode 100644
index 00000000000..06d5d810dbf
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeAbstractType.kt
@@ -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
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt
new file mode 100644
index 00000000000..1b9fe40614c
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeArrayType.kt
@@ -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 accept(v: TypeVisitor, 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)
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt
new file mode 100644
index 00000000000..1be14a4b091
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeClassInitializerExecutableTypeMirror.kt
@@ -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 accept(v: TypeVisitor, p: P) = v.visitExecutable(this, p)
+
+ override fun getReturnType() = CustomJeNoneType(TypeKind.VOID)
+
+ override fun getReceiverType() = JeNoneType
+
+ override fun getThrownTypes() = emptyList()
+
+ override fun getParameterTypes() = emptyList()
+
+ override fun getTypeVariables() = emptyList()
+
+ override fun toString() = (initializer.containingClass?.qualifiedName?.let { it + "." } ?: "") +
+ (if (initializer.hasModifierProperty(PsiModifier.STATIC)) "" else "")
+
+ 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()
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeCompoundDeclaredType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeCompoundDeclaredType.kt
new file mode 100644
index 00000000000..35ba98f5bdb
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeCompoundDeclaredType.kt
@@ -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,
+ val typeArgMirrors: List
+) : JeTypeBase(), DeclaredType {
+ override fun getKind() = TypeKind.DECLARED
+ override fun accept(v: TypeVisitor, 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 = ">")
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt
new file mode 100644
index 00000000000..41895661d01
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeDeclaredType.kt
@@ -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 accept(v: TypeVisitor, 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)
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt
new file mode 100644
index 00000000000..bf4cc7270e2
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeIntersectionType.kt
@@ -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 accept(v: TypeVisitor, p: P) = v.visitIntersection(this, p)
+ override fun getBounds() = psiType.superTypes.map { it.toJeType() }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt
new file mode 100644
index 00000000000..6e9c90a7fbb
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeMethodExecutableTypeMirror.kt
@@ -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 accept(v: TypeVisitor, 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 {
+ signature?.parameterTypes?.let { types -> return types.map { it.toJeType() } }
+ return method.parameterList.parameters.map { it.type.toJeType() }
+ }
+
+ override fun getTypeVariables(): List {
+ 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()
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeNullType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeNullType.kt
new file mode 100644
index 00000000000..d1e7ccce2d7
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeNullType.kt
@@ -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 accept(v: TypeVisitor, p: P) = v.visitNull(this, p)
+ override val psiType = PsiType.NULL
+ override fun toString() = "null"
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt
new file mode 100644
index 00000000000..c40d4d13a64
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JePrimitiveType.kt
@@ -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 accept(v: TypeVisitor, 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
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeBase.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeBase.kt
new file mode 100644
index 00000000000..e9aa8fd2456
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeBase.kt
@@ -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()
+
+ override fun getAnnotation(annotationClass: Class?) = null
+
+ @Suppress("UNCHECKED_CAST")
+ override fun getAnnotationsByType(annotationType: Class): Array {
+ return java.lang.reflect.Array.newInstance(annotationType, 0) as Array
+ }
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt
new file mode 100644
index 00000000000..2a5e14a7b52
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeTypeVariableType.kt
@@ -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 accept(v: TypeVisitor, 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))
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt
new file mode 100644
index 00000000000..711197c2f97
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/JeWildcardType.kt
@@ -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 accept(v: TypeVisitor, 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 accept(v: TypeVisitor, p: P) = v.visitWildcard(this, p)
+ override fun getSuperBound() = superType
+ override fun getExtendsBound() = extendsType
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/noTypes.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/noTypes.kt
new file mode 100644
index 00000000000..f67227112ba
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/noTypes.kt
@@ -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 accept(v: TypeVisitor, p: P) = v.visitNoType(this, p)
+}
+
+object JeNoneType : JeTypeBase(), NoType {
+ override fun getKind() = TypeKind.NONE
+ override fun accept(v: TypeVisitor, p: P) = v.visitNoType(this, p)
+}
+
+object JeVoidType : JeTypeBase(), NoType {
+ override fun getKind() = TypeKind.VOID
+ override fun accept(v: TypeVisitor, p: P) = v.visitNoType(this, p)
+}
+
+class CustomJeNoneType(private val _kind: TypeKind) : JeTypeBase(), NoType {
+ override fun getKind() = _kind
+ override fun accept(v: TypeVisitor, p: P) = v.visitNoType(this, p)
+}
+
+object JeErrorType : JeTypeBase(), NoType {
+ override fun getKind() = TypeKind.ERROR
+ override fun accept(v: TypeVisitor, p: P) = v.visitNoType(this, p)
+}
+
+object JeDeclaredErrorType : JeTypeBase(), DeclaredType, NoType {
+ override fun getKind() = TypeKind.ERROR
+ override fun accept(v: TypeVisitor, p: P) = v.visitNoType(this, p)
+
+ override fun getTypeArguments() = emptyList()
+ override fun asElement() = null
+ override fun getEnclosingType() = JeNoneType
+}
\ No newline at end of file
diff --git a/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt
new file mode 100644
index 00000000000..ace1e4ada1f
--- /dev/null
+++ b/plugins/java-model-wrappers/src/org/jetbrains/kotlin/java/model/types/types.kt
@@ -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
+}
+