From fefa0baeeef6339b5ccd37f5aafb9d0858b1461b Mon Sep 17 00:00:00 2001 From: Alexey Sedunov Date: Tue, 1 Mar 2016 20:01:44 +0300 Subject: [PATCH] Light Classes: Generate light wrappers for annotation entries --- .../CliLightClassGenerationSupport.kt | 4 +- .../kotlin/asJava/KtLightAnnotation.kt | 53 +++++++++++ .../jetbrains/kotlin/asJava/KtLightClass.kt | 2 +- .../KtLightClassForExplicitDeclaration.kt | 6 +- .../{KtLightElement.kt => KtLightElements.kt} | 7 +- .../jetbrains/kotlin/asJava/KtLightField.kt | 6 +- .../jetbrains/kotlin/asJava/KtLightMethod.kt | 6 +- .../kotlin/asJava/KtLightModifierList.kt | 39 -------- ...tLightModifierListWithExplicitModifiers.kt | 95 +++++++++++++++++++ .../kotlin/asJava/KtLightParameter.java | 4 +- .../kotlin/asJava/KtLightTypeParameter.java | 2 +- .../kotlin/asJava/KtWrappingLightClass.java | 4 +- .../asJava/LightClassGenerationSupport.java | 4 +- .../kotlin/asJava/LightElementOrigin.kt | 6 +- .../kotlin/asJava/lightClassUtils.kt | 7 ++ .../ExtraAnnotations.annotations.txt | 2 +- .../org/jetbrains/kotlin/utils/collections.kt | 7 ++ .../resolve/IDELightClassGenerationSupport.kt | 5 +- .../idea/KotlinQuickDocumentationProvider.kt | 4 +- 19 files changed, 202 insertions(+), 61 deletions(-) create mode 100644 compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightAnnotation.kt rename compiler/light-classes/src/org/jetbrains/kotlin/asJava/{KtLightElement.kt => KtLightElements.kt} (80%) delete mode 100644 compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierList.kt create mode 100644 compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierListWithExplicitModifiers.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt index 4abeecd7275..4208e501587 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/CliLightClassGenerationSupport.kt @@ -137,8 +137,8 @@ class CliLightClassGenerationSupport(project: Project) : LightClassGenerationSup return KtLightClassForExplicitDeclaration.create(classOrObject) } - override fun resolveClassToDescriptor(classOrObject: KtClassOrObject): ClassDescriptor? { - return bindingContext.get(BindingContext.CLASS, classOrObject) + override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? { + return bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, declaration) } override fun getFacadeClasses(facadeFqName: FqName, scope: GlobalSearchScope): Collection { diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightAnnotation.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightAnnotation.kt new file mode 100644 index 00000000000..896678810eb --- /dev/null +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightAnnotation.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.asJava + +import com.intellij.openapi.util.TextRange +import com.intellij.psi.PsiAnnotation +import com.intellij.psi.PsiAnnotationOwner +import com.intellij.psi.PsiElement +import com.intellij.util.IncorrectOperationException +import org.jetbrains.kotlin.psi.KtAnnotationEntry + +class KtLightAnnotation( + private val delegate: PsiAnnotation, + private val originalElement: KtAnnotationEntry, + private val owner: PsiAnnotationOwner +) : PsiAnnotation by delegate, KtLightElement { + override fun getDelegate() = delegate + override fun getOrigin() = originalElement + + override fun getName() = null + override fun setName(newName: String) = throw IncorrectOperationException() + + override fun getOwner() = owner + + override fun getText() = originalElement.text ?: "" + override fun getTextRange() = originalElement.textRange ?: TextRange.EMPTY_RANGE + + override fun getParent() = owner as? PsiElement + + override fun toString() = "@$qualifiedName" + + override fun equals(other: Any?): Boolean { + if (this === other) return true + if (other?.javaClass != javaClass) return false + return originalElement == (other as KtLightAnnotation).originalElement + } + + override fun hashCode() = originalElement.hashCode() +} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClass.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClass.kt index 1a979d1712e..24496456774 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClass.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClass.kt @@ -20,6 +20,6 @@ import com.intellij.psi.PsiClass; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtClassOrObject -interface KtLightClass : PsiClass, KtLightElement { +interface KtLightClass : PsiClass, KtLightDeclaration { fun getFqName(): FqName } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt index 74695d937db..53347a78c5f 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightClassForExplicitDeclaration.kt @@ -19,10 +19,12 @@ package org.jetbrains.kotlin.asJava import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.util.Comparing import com.intellij.openapi.util.Key +import com.intellij.openapi.util.TextRange import com.intellij.psi.* import com.intellij.psi.impl.DebugUtil import com.intellij.psi.impl.java.stubs.PsiJavaFileStub import com.intellij.psi.impl.light.LightClass +import com.intellij.psi.impl.light.LightIdentifier import com.intellij.psi.impl.light.LightMethod import com.intellij.psi.scope.PsiScopeProcessor import com.intellij.psi.search.SearchScope @@ -170,7 +172,7 @@ open class KtLightClassForExplicitDeclaration( private fun getJavaFileStub(): PsiJavaFileStub = getLightClassData().javaFileStub protected fun getDescriptor(): ClassDescriptor? { - return LightClassGenerationSupport.getInstance(project).resolveClassToDescriptor(classOrObject) + return LightClassGenerationSupport.getInstance(project).resolveToDescriptor(classOrObject) as? ClassDescriptor } private fun getLightClassData(): OutermostKotlinClassLightClassData { @@ -262,7 +264,7 @@ open class KtLightClassForExplicitDeclaration( override fun getQualifiedName(): String = classFqName.asString() private val _modifierList : PsiModifierList by lazy { - object : KtLightModifierList(this.manager, computeModifiers()) { + object : KtLightModifierListWithExplicitModifiers(this@KtLightClassForExplicitDeclaration, computeModifiers()) { override val delegate: PsiAnnotationOwner get() = this@KtLightClassForExplicitDeclaration.getDelegate().modifierList!! } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightElement.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightElements.kt similarity index 80% rename from compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightElement.kt rename to compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightElements.kt index 7f81613de84..423adf94230 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightElement.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightElements.kt @@ -16,12 +16,15 @@ package org.jetbrains.kotlin.asJava -import org.jetbrains.kotlin.psi.KtDeclaration import com.intellij.psi.PsiElement import com.intellij.psi.PsiNamedElement +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.psi.KtElement -interface KtLightElement : PsiNamedElement { +interface KtLightElement : PsiNamedElement { fun getOrigin(): T? fun getDelegate(): D } + +interface KtLightDeclaration: KtLightElement \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightField.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightField.kt index 306c77887c5..6b5183d276b 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightField.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightField.kt @@ -26,7 +26,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtEnumEntry -interface KtLightField : PsiField, KtLightElement +interface KtLightField : PsiField, KtLightDeclaration // Copied from com.intellij.psi.impl.light.LightField sealed class KtLightFieldImpl( @@ -65,7 +65,9 @@ sealed class KtLightFieldImpl( @Throws(IncorrectOperationException::class) override fun setName(@NonNls name: String) = throw IncorrectOperationException("Not supported") - override fun getModifierList() = delegate.modifierList + private val _modifierList by lazy { delegate.modifierList?.let { KtLightModifierList(it, this) } } + + override fun getModifierList() = _modifierList override fun hasModifierProperty(@NonNls name: String) = delegate.hasModifierProperty(name) diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt index d3db80bfb28..9c02a69bf35 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightMethod.kt @@ -27,7 +27,7 @@ import org.jetbrains.kotlin.idea.KotlinLanguage import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind -interface KtLightMethod : PsiMethod, KtLightElement { +interface KtLightMethod : PsiMethod, KtLightDeclaration { val isDelegated: Boolean } @@ -108,6 +108,10 @@ sealed class KtLightMethodImpl( throw IncorrectOperationException(JavaCoreBundle.message("psi.error.attempt.to.edit.class.file")) } + private val _modifierList by lazy { KtLightModifierList(delegate.modifierList, this) } + + override fun getModifierList() = _modifierList + override fun getParameterList() = paramsList.value override fun getTypeParameterList() = typeParamsList.value diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierList.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierList.kt deleted file mode 100644 index 9476247b867..00000000000 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierList.kt +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2010-2015 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.asJava - -import com.intellij.psi.PsiAnnotation -import com.intellij.psi.PsiAnnotationOwner -import com.intellij.psi.PsiManager -import com.intellij.psi.impl.light.LightModifierList -import org.jetbrains.annotations.NonNls -import org.jetbrains.kotlin.idea.KotlinLanguage - -abstract class KtLightModifierList( - psiManager: PsiManager, - modifiers: Array -) : LightModifierList(psiManager, KotlinLanguage.INSTANCE, *modifiers) { - abstract val delegate: PsiAnnotationOwner - - override fun getAnnotations() = delegate.annotations - - override fun getApplicableAnnotations() = delegate.applicableAnnotations - - override fun findAnnotation(@NonNls qualifiedName: String) = delegate.findAnnotation(qualifiedName) - - override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName) -} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierListWithExplicitModifiers.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierListWithExplicitModifiers.kt new file mode 100644 index 00000000000..08c042770a3 --- /dev/null +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightModifierListWithExplicitModifiers.kt @@ -0,0 +1,95 @@ +/* + * Copyright 2010-2015 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.asJava + +import com.intellij.psi.* +import com.intellij.psi.impl.light.LightModifierList +import com.intellij.psi.util.CachedValue +import com.intellij.psi.util.CachedValueProvider +import com.intellij.psi.util.CachedValuesManager +import com.intellij.psi.util.PsiModificationTracker +import org.jetbrains.annotations.NonNls +import org.jetbrains.kotlin.idea.KotlinLanguage +import org.jetbrains.kotlin.psi.KtAnnotationEntry +import org.jetbrains.kotlin.psi.KtDeclaration +import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe +import org.jetbrains.kotlin.resolve.source.getPsi +import org.jetbrains.kotlin.utils.indexOfFirst + +abstract class KtLightModifierListWithExplicitModifiers( + private val owner: KtLightElement<*, *>, + modifiers: Array +) : LightModifierList(owner.manager, KotlinLanguage.INSTANCE, *modifiers) { + abstract val delegate: PsiAnnotationOwner + + private val _annotations by lazy { computeAnnotations(this, delegate) } + + override fun getParent() = owner + + override fun getAnnotations(): Array = _annotations.value + + override fun getApplicableAnnotations() = delegate.applicableAnnotations + + override fun findAnnotation(@NonNls qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName } + + override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName) +} + +class KtLightModifierList( + private val delegate: PsiModifierList, + private val owner: PsiModifierListOwner +): PsiModifierList by delegate { + private val _annotations by lazy { computeAnnotations(this, delegate) } + + override fun getAnnotations(): Array = _annotations.value + + override fun findAnnotation(@NonNls qualifiedName: String) = annotations.firstOrNull { it.qualifiedName == qualifiedName } + + override fun addAnnotation(@NonNls qualifiedName: String) = delegate.addAnnotation(qualifiedName) + + override fun getParent() = owner +} + +internal fun computeAnnotations(lightElement: PsiModifierList, + delegate: PsiAnnotationOwner): CachedValue> { + val cacheManager = CachedValuesManager.getManager(lightElement.project) + return cacheManager.createCachedValue>( + { + val declaration = (lightElement.parent as? KtLightElement<*, *>)?.getOrigin() as? KtDeclaration + val descriptor = declaration?.let { LightClassGenerationSupport.getInstance(lightElement.project).resolveToDescriptor(it) } + val ktAnnotations = descriptor?.annotations?.getAllAnnotations() ?: emptyList() + var nextIndex = 0 + val result = delegate.annotations + .map { clsAnnotation -> + val currentIndex = ktAnnotations.indexOfFirst(nextIndex) { + it.annotation.type.constructor.declarationDescriptor?.fqNameUnsafe?.asString() == clsAnnotation.qualifiedName + } + if (currentIndex >= 0) { + nextIndex = currentIndex + 1 + val ktAnnotation = ktAnnotations[currentIndex] + val entry = ktAnnotation.annotation.source.getPsi() as? KtAnnotationEntry ?: return@map clsAnnotation + KtLightAnnotation(clsAnnotation, entry, lightElement) + } + else clsAnnotation + } + .toTypedArray() + + CachedValueProvider.Result.create(result, PsiModificationTracker.OUT_OF_CODE_BLOCK_MODIFICATION_COUNT) + }, + false + ) +} diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightParameter.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightParameter.java index 93b7d4d145c..f93690eb18c 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightParameter.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtLightParameter.java @@ -31,7 +31,7 @@ import org.jetbrains.kotlin.psi.psiUtil.KtPsiUtilKt; import java.util.List; -public class KtLightParameter extends LightParameter implements KtLightElement { +public class KtLightParameter extends LightParameter implements KtLightDeclaration { private static String getName(PsiParameter delegate, int index) { String name = delegate.getName(); return name != null ? name : "p" + index; @@ -49,7 +49,7 @@ public class KtLightParameter extends LightParameter implements KtLightElement { + extends AbstractLightClass implements PsiTypeParameter, KtLightDeclaration { private final PsiTypeParameterListOwner owner; private final int index; private final String name; diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtWrappingLightClass.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtWrappingLightClass.java index 45949055090..76833b52992 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtWrappingLightClass.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/KtWrappingLightClass.java @@ -123,7 +123,9 @@ public abstract class KtWrappingLightClass extends AbstractLightClass implements @Override public PsiField fun(PsiField field) { LightMemberOrigin origin = ClsWrapperStubPsiFactory.getMemberOrigin(field); - return KtLightFieldImpl.Factory.create(origin != null ? origin.getOriginalElement() : null, field, KtWrappingLightClass.this); + return KtLightFieldImpl.Factory.create(origin != null ? origin.getOriginalElement() : null, + field, + KtWrappingLightClass.this); } }); } diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.java b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.java index 5f2b3d59fa1..fec95f17d92 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.java +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightClassGenerationSupport.java @@ -23,8 +23,10 @@ import com.intellij.psi.search.GlobalSearchScope; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import org.jetbrains.kotlin.descriptors.ClassDescriptor; +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.name.FqName; import org.jetbrains.kotlin.psi.KtClassOrObject; +import org.jetbrains.kotlin.psi.KtDeclaration; import org.jetbrains.kotlin.psi.KtFile; import java.util.Collection; @@ -68,7 +70,7 @@ public abstract class LightClassGenerationSupport { public abstract KtLightClass getLightClass(@NotNull KtClassOrObject classOrObject); @Nullable - public abstract ClassDescriptor resolveClassToDescriptor(@NotNull KtClassOrObject classOrObject); + public abstract DeclarationDescriptor resolveToDescriptor(@NotNull KtDeclaration declaration); @NotNull public abstract Collection getFacadeClasses(@NotNull FqName facadeFqName, @NotNull GlobalSearchScope scope); diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightElementOrigin.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightElementOrigin.kt index eac3ff4072a..adfbbec2fac 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightElementOrigin.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/LightElementOrigin.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.asJava import com.intellij.psi.PsiElement +import org.jetbrains.kotlin.psi.KtAnnotationEntry import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOrigin import org.jetbrains.kotlin.resolve.jvm.diagnostics.JvmDeclarationOriginKind @@ -40,18 +41,19 @@ fun JvmDeclarationOrigin.toLightMemberOrigin(): LightElementOrigin { val originalElement = element return when (originalElement) { is KtDeclaration -> LightMemberOrigin(originalElement, originKind) + is KtAnnotationEntry -> DefaultLightElementOrigin(originalElement) else -> LightElementOrigin.None } } data class LightMemberOrigin(override val originalElement: KtDeclaration, override val originKind: JvmDeclarationOriginKind) : LightElementOrigin -data class LightClassOrigin(override val originalElement: PsiElement?) : LightElementOrigin { +data class DefaultLightElementOrigin(override val originalElement: PsiElement?) : LightElementOrigin { override val originKind: JvmDeclarationOriginKind? get() = null } fun PsiElement?.toLightClassOrigin(): LightElementOrigin { - return if (this != null) LightClassOrigin(this) else LightElementOrigin.None + return if (this != null) DefaultLightElementOrigin(this) else LightElementOrigin.None } fun LightMemberOrigin.copy() = LightMemberOrigin(originalElement.copy() as KtDeclaration, originKind) \ No newline at end of file diff --git a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt index 201a42add2c..f9133c018c6 100644 --- a/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt +++ b/compiler/light-classes/src/org/jetbrains/kotlin/asJava/lightClassUtils.kt @@ -23,6 +23,7 @@ import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType +import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration import org.jetbrains.kotlin.utils.addToStdlib.singletonList import org.jetbrains.kotlin.utils.addToStdlib.singletonOrEmptyList @@ -126,3 +127,9 @@ private fun isNonAbstractMember(member: KtDeclaration?): Boolean { private val DEFAULT_IMPLS_CLASS_NAME = Name.identifier(JvmAbi.DEFAULT_IMPLS_CLASS_NAME) fun FqName.defaultImplsChild() = child(DEFAULT_IMPLS_CLASS_NAME) + +fun KtAnnotationEntry.toLightAnnotation(): PsiAnnotation? { + val ktDeclaration = getStrictParentOfType()?.parent as? KtDeclaration ?: return null + val lightElement = ktDeclaration.toLightElements().firstOrNull() as? PsiModifierListOwner ?: return null + return lightElement.modifierList?.annotations?.firstOrNull { it is KtLightAnnotation && it.getOrigin() == this } +} \ No newline at end of file diff --git a/compiler/testData/asJava/annotations/ExtraAnnotations.annotations.txt b/compiler/testData/asJava/annotations/ExtraAnnotations.annotations.txt index 0cf4e1eb42e..56948cf6878 100644 --- a/compiler/testData/asJava/annotations/ExtraAnnotations.annotations.txt +++ b/compiler/testData/asJava/annotations/ExtraAnnotations.annotations.txt @@ -1 +1 @@ -@Foo(s = "...") +@Foo("...") diff --git a/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt b/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt index 572be58990e..c5ed3067b6c 100644 --- a/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt +++ b/core/util.runtime/src/org/jetbrains/kotlin/utils/collections.kt @@ -80,3 +80,10 @@ fun Collection.toReadOnlyList(): List = fun T?.singletonOrEmptyList(): List = if (this != null) listOf(this) else emptyList() + +fun List.indexOfFirst(startFrom: Int, predicate: (T) -> Boolean): Int { + for (index in startFrom..lastIndex) { + if (predicate(this[index])) return index + } + return -1 +} \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt index 3b406db6813..6321289e656 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/IDELightClassGenerationSupport.kt @@ -29,6 +29,7 @@ import com.intellij.psi.search.GlobalSearchScope import com.intellij.psi.util.PsiTreeUtil import org.jetbrains.kotlin.asJava.* import org.jetbrains.kotlin.descriptors.ClassDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName import org.jetbrains.kotlin.idea.decompiler.classFile.KtClsFile @@ -192,9 +193,9 @@ class IDELightClassGenerationSupport(private val project: Project) : LightClassG return KotlinFileFacadeFqNameIndex.INSTANCE.get(facadeFqName.asString(), project, scope) } - override fun resolveClassToDescriptor(classOrObject: KtClassOrObject): ClassDescriptor? { + override fun resolveToDescriptor(declaration: KtDeclaration): DeclarationDescriptor? { try { - return classOrObject.resolveToDescriptor() as ClassDescriptor + return declaration.resolveToDescriptor() } catch (e: NoDescriptorForDeclarationException) { return null diff --git a/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt b/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt index ba49784c1ad..1a69acb132a 100644 --- a/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/KotlinQuickDocumentationProvider.kt @@ -22,7 +22,7 @@ import com.intellij.openapi.diagnostic.Logger import com.intellij.openapi.util.text.StringUtil import com.intellij.psi.PsiElement import com.intellij.psi.PsiManager -import org.jetbrains.kotlin.asJava.KtLightElement +import org.jetbrains.kotlin.asJava.KtLightDeclaration import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor @@ -92,7 +92,7 @@ class KotlinQuickDocumentationProvider : AbstractDocumentationProvider() { if (element is KtDeclaration) { return renderKotlinDeclaration(element, quickNavigation) } - else if (element is KtLightElement<*, *>) { + else if (element is KtLightDeclaration<*, *>) { val origin = element.getOrigin() ?: return null return renderKotlinDeclaration(origin, quickNavigation) }