[FIR IDE] Move refactoring and minor bugfixing for modality, jvmname, etc.
This commit is contained in:
+2
-28
@@ -8,24 +8,15 @@ package org.jetbrains.kotlin.idea.caches.resolve
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.psi.PsiManager
|
import com.intellij.psi.PsiManager
|
||||||
import com.intellij.psi.search.GlobalSearchScope
|
import com.intellij.psi.search.GlobalSearchScope
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
|
||||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
|
|
||||||
import org.jetbrains.kotlin.idea.asJava.FirLightClassForFacade
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassForFacade
|
||||||
import org.jetbrains.kotlin.idea.asJava.FirLightClassForSymbol
|
import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightClass
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
|
||||||
import org.jetbrains.kotlin.idea.util.ifTrue
|
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
import org.jetbrains.kotlin.psi.KtEnumEntry
|
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
|
||||||
import org.jetbrains.kotlin.psi.KtScript
|
import org.jetbrains.kotlin.psi.KtScript
|
||||||
|
|
||||||
class IDEKotlinAsJavaFirSupport(project: Project) : IDEKotlinAsJavaSupport(project) {
|
class IDEKotlinAsJavaFirSupport(project: Project) : IDEKotlinAsJavaSupport(project) {
|
||||||
|
|
||||||
|
|
||||||
//TODO Make caching
|
//TODO Make caching
|
||||||
override fun createLightClassForFacade(manager: PsiManager, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClass? {
|
override fun createLightClassForFacade(manager: PsiManager, facadeClassFqName: FqName, searchScope: GlobalSearchScope): KtLightClass? {
|
||||||
val sources = findFilesForFacade(facadeClassFqName, searchScope)
|
val sources = findFilesForFacade(facadeClassFqName, searchScope)
|
||||||
@@ -38,23 +29,6 @@ class IDEKotlinAsJavaFirSupport(project: Project) : IDEKotlinAsJavaSupport(proje
|
|||||||
|
|
||||||
override fun createLightClassForScript(script: KtScript): KtLightClass? = null
|
override fun createLightClassForScript(script: KtScript): KtLightClass? = null
|
||||||
|
|
||||||
private fun KtClassOrObject.isSupportedByFitLightClasses() =
|
|
||||||
containingFile.let { it is KtFile && !it.isCompiled } &&
|
|
||||||
!isLocal /*TODO*/ &&
|
|
||||||
this !is KtEnumEntry /*TODO*/ &&
|
|
||||||
!shouldNotBeVisibleAsLightClass()
|
|
||||||
|
|
||||||
override fun createLightClassForSourceDeclaration(classOrObject: KtClassOrObject): KtLightClass? =
|
override fun createLightClassForSourceDeclaration(classOrObject: KtClassOrObject): KtLightClass? =
|
||||||
classOrObject.isSupportedByFitLightClasses().ifTrue {
|
getOrCreateFirLightClass(classOrObject)
|
||||||
CachedValuesManager.getCachedValue(classOrObject) {
|
|
||||||
CachedValueProvider.Result
|
|
||||||
.create(
|
|
||||||
FirLightClassForSymbol(
|
|
||||||
analyze(classOrObject) { classOrObject.getClassOrObjectSymbol() },
|
|
||||||
classOrObject.manager
|
|
||||||
),
|
|
||||||
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
-2
@@ -18,8 +18,6 @@ abstract class KtEnumEntrySymbol : KtVariableLikeSymbol(), KtSymbolWithDeclarati
|
|||||||
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
|
final override val symbolKind: KtSymbolKind get() = KtSymbolKind.MEMBER
|
||||||
abstract val containingEnumClassIdIfNonLocal: ClassId?
|
abstract val containingEnumClassIdIfNonLocal: ClassId?
|
||||||
|
|
||||||
abstract val hasBody: Boolean
|
|
||||||
|
|
||||||
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
|
abstract override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,11 +12,12 @@ import com.intellij.psi.scope.PsiScopeProcessor
|
|||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||||
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
import org.jetbrains.kotlin.asJava.elements.FakeFileForLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightClass
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
|
||||||
class FirFakeFileImpl(private val classOrObject: KtClassOrObject, ktClass: KtLightClass) : FakeFileForLightClass(
|
class FirFakeFileImpl(private val classOrObject: KtClassOrObject, ktClass: KtLightClass) : FakeFileForLightClass(
|
||||||
classOrObject.containingKtFile,
|
classOrObject.containingKtFile,
|
||||||
{ if (classOrObject.isTopLevel()) ktClass else FirLightClassForSymbol.create(getOutermostClassOrObject(classOrObject))!! },
|
{ if (classOrObject.isTopLevel()) ktClass else getOrCreateFirLightClass(getOutermostClassOrObject(classOrObject))!! },
|
||||||
{ null }
|
{ null }
|
||||||
) {
|
) {
|
||||||
|
|
||||||
|
|||||||
+3
@@ -66,6 +66,9 @@ internal fun KtAnnotatedSymbol.isHiddenByDeprecation(annotationUseSiteTarget: An
|
|||||||
internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean =
|
internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean =
|
||||||
hasAnnotation("kotlin/jvm/JvmField", null)
|
hasAnnotation("kotlin/jvm/JvmField", null)
|
||||||
|
|
||||||
|
internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
|
||||||
|
hasAnnotation("kotlin/PublishedApi", annotationUseSiteTarget)
|
||||||
|
|
||||||
internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean =
|
internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean =
|
||||||
hasAnnotation("kotlin/jvm/JvmOverloads", null)
|
hasAnnotation("kotlin/jvm/JvmOverloads", null)
|
||||||
|
|
||||||
|
|||||||
-267
@@ -1,267 +0,0 @@
|
|||||||
/*
|
|
||||||
* 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.idea.asJava
|
|
||||||
|
|
||||||
import com.intellij.navigation.ItemPresentation
|
|
||||||
import com.intellij.navigation.ItemPresentationProviders
|
|
||||||
import com.intellij.openapi.util.Pair
|
|
||||||
import com.intellij.psi.*
|
|
||||||
import com.intellij.psi.impl.PsiClassImplUtil
|
|
||||||
import com.intellij.psi.impl.PsiImplUtil
|
|
||||||
import com.intellij.psi.impl.light.LightElement
|
|
||||||
import com.intellij.psi.impl.source.PsiExtensibleClass
|
|
||||||
import com.intellij.psi.javadoc.PsiDocComment
|
|
||||||
import com.intellij.psi.scope.PsiScopeProcessor
|
|
||||||
import com.intellij.psi.util.PsiUtil
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache.Companion.processDeclarationsInEnum
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_BASE
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol
|
|
||||||
import java.util.*
|
|
||||||
|
|
||||||
abstract class FirLightClassBase protected constructor(manager: PsiManager) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass,
|
|
||||||
KtLightClass, PsiExtensibleClass {
|
|
||||||
|
|
||||||
override val clsDelegate: PsiClass
|
|
||||||
get() = invalidAccess()
|
|
||||||
|
|
||||||
protected open val myInnersCache = KotlinClassInnerStuffCache(
|
|
||||||
myClass = this,
|
|
||||||
externalDependencies = listOf(KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker)
|
|
||||||
)
|
|
||||||
|
|
||||||
override fun getFields(): Array<PsiField> = myInnersCache.fields
|
|
||||||
|
|
||||||
override fun getMethods(): Array<PsiMethod> = myInnersCache.methods
|
|
||||||
|
|
||||||
override fun getConstructors(): Array<PsiMethod> = myInnersCache.constructors
|
|
||||||
|
|
||||||
override fun getInnerClasses(): Array<out PsiClass> = myInnersCache.innerClasses
|
|
||||||
|
|
||||||
override fun getAllFields(): Array<PsiField> = PsiClassImplUtil.getAllFields(this)
|
|
||||||
|
|
||||||
override fun getAllMethods(): Array<PsiMethod> = PsiClassImplUtil.getAllMethods(this)
|
|
||||||
|
|
||||||
override fun getAllInnerClasses(): Array<PsiClass> = PsiClassImplUtil.getAllInnerClasses(this)
|
|
||||||
|
|
||||||
override fun findFieldByName(name: String, checkBases: Boolean) =
|
|
||||||
myInnersCache.findFieldByName(name, checkBases)
|
|
||||||
|
|
||||||
override fun findMethodsByName(name: String, checkBases: Boolean): Array<PsiMethod> =
|
|
||||||
myInnersCache.findMethodsByName(name, checkBases)
|
|
||||||
|
|
||||||
override fun findInnerClassByName(name: String, checkBases: Boolean): PsiClass? =
|
|
||||||
myInnersCache.findInnerClassByName(name, checkBases)
|
|
||||||
|
|
||||||
override fun processDeclarations(
|
|
||||||
processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement
|
|
||||||
): Boolean {
|
|
||||||
|
|
||||||
if (isEnum && !processDeclarationsInEnum(processor, state, myInnersCache)) return false
|
|
||||||
|
|
||||||
return PsiClassImplUtil.processDeclarationsInClass(
|
|
||||||
this,
|
|
||||||
processor,
|
|
||||||
state,
|
|
||||||
null,
|
|
||||||
lastParent,
|
|
||||||
place,
|
|
||||||
PsiUtil.getLanguageLevel(place),
|
|
||||||
false
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getText(): String = kotlinOrigin?.text ?: ""
|
|
||||||
|
|
||||||
override fun getLanguage(): KotlinLanguage = KotlinLanguage.INSTANCE
|
|
||||||
|
|
||||||
override fun getPresentation(): ItemPresentation? =
|
|
||||||
ItemPresentationProviders.getItemPresentation(this)
|
|
||||||
|
|
||||||
abstract override fun equals(other: Any?): Boolean
|
|
||||||
|
|
||||||
abstract override fun hashCode(): Int
|
|
||||||
|
|
||||||
override fun getContext(): PsiElement = parent
|
|
||||||
|
|
||||||
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
|
||||||
PsiClassImplUtil.isClassEquivalentTo(this, another)
|
|
||||||
|
|
||||||
override fun getDocComment(): PsiDocComment? = null
|
|
||||||
|
|
||||||
override fun hasTypeParameters(): Boolean = PsiImplUtil.hasTypeParameters(this)
|
|
||||||
|
|
||||||
override fun getExtendsListTypes(): Array<PsiClassType?> =
|
|
||||||
PsiClassImplUtil.getExtendsListTypes(this)
|
|
||||||
|
|
||||||
override fun getImplementsListTypes(): Array<PsiClassType?> =
|
|
||||||
PsiClassImplUtil.getImplementsListTypes(this)
|
|
||||||
|
|
||||||
override fun findMethodBySignature(patternMethod: PsiMethod?, checkBases: Boolean): PsiMethod? =
|
|
||||||
patternMethod?.let { PsiClassImplUtil.findMethodBySignature(this, it, checkBases) }
|
|
||||||
|
|
||||||
override fun findMethodsBySignature(patternMethod: PsiMethod?, checkBases: Boolean): Array<PsiMethod?> =
|
|
||||||
patternMethod?.let { PsiClassImplUtil.findMethodsBySignature(this, it, checkBases) } ?: emptyArray()
|
|
||||||
|
|
||||||
override fun findMethodsAndTheirSubstitutorsByName(
|
|
||||||
@NonNls name: String?,
|
|
||||||
checkBases: Boolean
|
|
||||||
): List<Pair<PsiMethod?, PsiSubstitutor?>?> =
|
|
||||||
PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases)
|
|
||||||
|
|
||||||
override fun getAllMethodsAndTheirSubstitutors(): List<Pair<PsiMethod?, PsiSubstitutor?>?> {
|
|
||||||
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD)
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract override fun copy(): PsiElement
|
|
||||||
|
|
||||||
override fun accept(visitor: PsiElementVisitor) {
|
|
||||||
if (visitor is JavaElementVisitor) {
|
|
||||||
visitor.visitClass(this)
|
|
||||||
} else {
|
|
||||||
visitor.visitElement(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun createMethods(declarations: Sequence<KtCallableSymbol>, isTopLevel: Boolean, result: MutableList<KtLightMethod>) {
|
|
||||||
var methodIndex = METHOD_INDEX_BASE
|
|
||||||
for (declaration in declarations) {
|
|
||||||
|
|
||||||
if (declaration is KtFunctionSymbol && declaration.isInline) continue
|
|
||||||
|
|
||||||
if (declaration is KtAnnotatedSymbol && declaration.hasJvmSyntheticAnnotation(annotationUseSiteTarget = null)) continue
|
|
||||||
|
|
||||||
if (declaration is KtAnnotatedSymbol && declaration.isHiddenByDeprecation(annotationUseSiteTarget = null)) continue
|
|
||||||
|
|
||||||
when (declaration) {
|
|
||||||
is KtFunctionSymbol -> {
|
|
||||||
result.add(
|
|
||||||
FirLightSimpleMethodForSymbol(
|
|
||||||
functionSymbol = declaration,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
containingClass = this@FirLightClassBase,
|
|
||||||
isTopLevel = isTopLevel,
|
|
||||||
methodIndex = methodIndex++
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
if (declaration.hasJvmOverloadsAnnotation()) {
|
|
||||||
val skipMask = BitSet(declaration.valueParameters.size)
|
|
||||||
|
|
||||||
for (i in declaration.valueParameters.size - 1 downTo 0) {
|
|
||||||
|
|
||||||
if (!declaration.valueParameters[i].hasDefaultValue) continue
|
|
||||||
|
|
||||||
skipMask.set(i)
|
|
||||||
|
|
||||||
result.add(
|
|
||||||
FirLightSimpleMethodForSymbol(
|
|
||||||
functionSymbol = declaration,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
containingClass = this@FirLightClassBase,
|
|
||||||
isTopLevel = isTopLevel,
|
|
||||||
methodIndex = methodIndex++,
|
|
||||||
argumentsSkipMask = skipMask
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
is KtConstructorSymbol -> {
|
|
||||||
result.add(
|
|
||||||
FirLightConstructorForSymbol(
|
|
||||||
constructorSymbol = declaration,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
containingClass = this@FirLightClassBase,
|
|
||||||
methodIndex++
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
is KtPropertySymbol -> {
|
|
||||||
|
|
||||||
if (declaration.hasJvmFieldAnnotation()) continue
|
|
||||||
|
|
||||||
val getter = declaration.getter?.takeIf {
|
|
||||||
!declaration.hasJvmSyntheticAnnotation(AnnotationUseSiteTarget.PROPERTY_GETTER) &&
|
|
||||||
!it.isInline &&
|
|
||||||
!declaration.isHiddenByDeprecation(AnnotationUseSiteTarget.PROPERTY_GETTER)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (getter != null) {
|
|
||||||
result.add(
|
|
||||||
FirLightAccessorMethodForSymbol(
|
|
||||||
propertyAccessorSymbol = getter,
|
|
||||||
containingPropertySymbol = declaration,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
containingClass = this@FirLightClassBase,
|
|
||||||
isTopLevel = isTopLevel
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
val setter = declaration.setter?.takeIf {
|
|
||||||
!declaration.hasJvmSyntheticAnnotation(AnnotationUseSiteTarget.PROPERTY_SETTER) &&
|
|
||||||
!it.isInline &&
|
|
||||||
!declaration.isHiddenByDeprecation(AnnotationUseSiteTarget.PROPERTY_GETTER)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (setter != null) {
|
|
||||||
result.add(
|
|
||||||
FirLightAccessorMethodForSymbol(
|
|
||||||
propertyAccessorSymbol = setter,
|
|
||||||
containingPropertySymbol = declaration,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
containingClass = this@FirLightClassBase,
|
|
||||||
isTopLevel = isTopLevel
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected fun createFields(declarations: Sequence<KtCallableSymbol>, isTopLevel: Boolean, result: MutableList<KtLightField>) {
|
|
||||||
//TODO isHiddenByDeprecation
|
|
||||||
for (declaration in declarations) {
|
|
||||||
if (declaration !is KtPropertySymbol) continue
|
|
||||||
|
|
||||||
if (!declaration.hasBackingField) continue
|
|
||||||
if (declaration.hasJvmSyntheticAnnotation(AnnotationUseSiteTarget.FIELD)) continue
|
|
||||||
result.add(
|
|
||||||
FirLightFieldForPropertySymbol(
|
|
||||||
propertySymbol = declaration,
|
|
||||||
containingClass = this@FirLightClassBase,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
isTopLevel = isTopLevel
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
-350
@@ -1,350 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
|
||||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.idea.asJava
|
|
||||||
|
|
||||||
import com.intellij.openapi.util.Comparing
|
|
||||||
import com.intellij.psi.*
|
|
||||||
import com.intellij.psi.impl.InheritanceImplUtil
|
|
||||||
import com.intellij.psi.impl.PsiClassImplUtil
|
|
||||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil
|
|
||||||
import com.intellij.psi.search.SearchScope
|
|
||||||
import com.intellij.psi.stubs.IStubElementType
|
|
||||||
import com.intellij.psi.stubs.StubElement
|
|
||||||
import com.intellij.psi.util.CachedValueProvider
|
|
||||||
import com.intellij.psi.util.CachedValuesManager
|
|
||||||
import com.intellij.util.IncorrectOperationException
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
|
||||||
import org.jetbrains.kotlin.asJava.classes.*
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType
|
|
||||||
import org.jetbrains.kotlin.idea.util.ifFalse
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
|
||||||
import org.jetbrains.kotlin.psi.*
|
|
||||||
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
|
||||||
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
|
||||||
import javax.swing.Icon
|
|
||||||
import kotlin.collections.ArrayList
|
|
||||||
|
|
||||||
class FirLightClassForSymbol(
|
|
||||||
private val classOrObjectSymbol: KtClassOrObjectSymbol,
|
|
||||||
manager: PsiManager
|
|
||||||
) :
|
|
||||||
FirLightClassBase(manager),
|
|
||||||
StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
|
|
||||||
|
|
||||||
private val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL
|
|
||||||
|
|
||||||
private val _modifierList: PsiModifierList? by lazyPub {
|
|
||||||
|
|
||||||
val modifiers = mutableSetOf(classOrObjectSymbol.computeVisibility(isTopLevel))
|
|
||||||
classOrObjectSymbol.computeSimpleModality()?.run {
|
|
||||||
modifiers.add(this)
|
|
||||||
}
|
|
||||||
if (!isTopLevel && !classOrObjectSymbol.isInner) {
|
|
||||||
modifiers.add(PsiModifier.STATIC)
|
|
||||||
}
|
|
||||||
|
|
||||||
val annotations = classOrObjectSymbol.computeAnnotations(
|
|
||||||
parent = this@FirLightClassForSymbol,
|
|
||||||
nullability = NullabilityType.Unknown,
|
|
||||||
annotationUseSiteTarget = null,
|
|
||||||
)
|
|
||||||
|
|
||||||
FirLightClassModifierList(this@FirLightClassForSymbol, modifiers, annotations)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getModifierList(): PsiModifierList? = _modifierList
|
|
||||||
override fun getOwnFields(): List<KtLightField> = _ownFields
|
|
||||||
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
|
||||||
override fun isDeprecated(): Boolean = false //TODO()
|
|
||||||
override fun getNameIdentifier(): KtLightIdentifier? = null //TODO()
|
|
||||||
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
|
||||||
override fun getImplementsList(): PsiReferenceList? = _implementsList
|
|
||||||
override fun getTypeParameterList(): PsiTypeParameterList? = null //TODO()
|
|
||||||
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray() //TODO()
|
|
||||||
|
|
||||||
override fun getOwnInnerClasses(): List<PsiClass> {
|
|
||||||
val result = ArrayList<PsiClass>()
|
|
||||||
|
|
||||||
// workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927
|
|
||||||
// inner classes with null names can't be searched for and can't be used from java anyway
|
|
||||||
// we can't prohibit creating light classes with null names either since they can contain members
|
|
||||||
|
|
||||||
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
|
||||||
classOrObjectSymbol.getDeclaredMemberScope().getAllSymbols().filterIsInstance<KtClassOrObjectSymbol>().mapTo(result) {
|
|
||||||
FirLightClassForSymbol(it, manager)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//TODO
|
|
||||||
//if (classOrObject.hasInterfaceDefaultImpls) {
|
|
||||||
// result.add(KtLightClassForInterfaceDefaultImpls(classOrObject))
|
|
||||||
//}
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getTextOffset(): Int = kotlinOrigin?.textOffset ?: 0
|
|
||||||
override fun getStartOffsetInParent(): Int = kotlinOrigin?.startOffsetInParent ?: 0
|
|
||||||
override fun isWritable() = kotlinOrigin?.isWritable ?: false
|
|
||||||
override val kotlinOrigin: KtClassOrObject? = classOrObjectSymbol.psi as? KtClassOrObject
|
|
||||||
|
|
||||||
private val _extendsList by lazyPub { createInheritanceList(forExtendsList = true) }
|
|
||||||
private val _implementsList by lazyPub { createInheritanceList(forExtendsList = false) }
|
|
||||||
|
|
||||||
private fun KtClassType.isTypeForInheritanceList(forExtendsList: Boolean): Boolean {
|
|
||||||
|
|
||||||
// Do not add redundant "extends java.lang.Object" anywhere
|
|
||||||
if (classId == StandardClassIds.Any) return false
|
|
||||||
|
|
||||||
// We don't have Enum among enums supertype in sources neither we do for decompiled class-files and light-classes
|
|
||||||
if (isEnum && classId == StandardClassIds.Enum) return false
|
|
||||||
|
|
||||||
// Interfaces have only extends lists
|
|
||||||
if (isInterface) return forExtendsList
|
|
||||||
|
|
||||||
val isInterface = (this.classSymbol as? KtClassOrObjectSymbol)?.classKind == KtClassKind.INTERFACE
|
|
||||||
|
|
||||||
return forExtendsList == !isInterface
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun createInheritanceList(forExtendsList: Boolean): PsiReferenceList? {
|
|
||||||
|
|
||||||
val role = if (forExtendsList) PsiReferenceList.Role.EXTENDS_LIST else PsiReferenceList.Role.IMPLEMENTS_LIST
|
|
||||||
|
|
||||||
if (isAnnotationType) return KotlinLightReferenceListBuilder(manager, language, role)
|
|
||||||
|
|
||||||
val listBuilder = KotlinSuperTypeListBuilder(
|
|
||||||
kotlinOrigin = kotlinOrigin?.getSuperTypeList(),
|
|
||||||
manager = manager,
|
|
||||||
language = language,
|
|
||||||
role = role
|
|
||||||
)
|
|
||||||
|
|
||||||
//TODO Add support for kotlin.collections.
|
|
||||||
classOrObjectSymbol.superTypes.map { type ->
|
|
||||||
if (type is KtClassType && type.isTypeForInheritanceList(forExtendsList)) {
|
|
||||||
type.mapSupertype(this, kotlinCollectionAsIs = true)?.run {
|
|
||||||
listBuilder.addReference(this)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return listBuilder
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
|
||||||
|
|
||||||
val result = mutableListOf<KtLightMethod>()
|
|
||||||
|
|
||||||
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
|
||||||
//TODO filterNot { it.isHiddenByDeprecation(support) }
|
|
||||||
val callableSymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
|
||||||
val visibleDeclarations = callableSymbols.filterNot {
|
|
||||||
isInterface && it is KtFunctionSymbol && it.visibility == KtSymbolVisibility.PRIVATE
|
|
||||||
}
|
|
||||||
|
|
||||||
createMethods(visibleDeclarations, isTopLevel = false, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
if (result.none { it.isConstructor }) {
|
|
||||||
classOrObjectSymbol.primaryConstructor?.let {
|
|
||||||
result.add(
|
|
||||||
FirLightConstructorForSymbol(
|
|
||||||
constructorSymbol = it,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
containingClass = this,
|
|
||||||
methodIndex = METHOD_INDEX_FOR_DEFAULT_CTOR
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _ownFields: List<KtLightField> by lazyPub {
|
|
||||||
|
|
||||||
val result = mutableListOf<KtLightField>()
|
|
||||||
|
|
||||||
classOrObjectSymbol.companionObject?.run {
|
|
||||||
result.add(FirLightFieldForObjectSymbol(this, this@FirLightClassForSymbol, null))
|
|
||||||
|
|
||||||
if (!isInterface) {
|
|
||||||
analyzeWithSymbolAsContext(this) {
|
|
||||||
getDeclaredMemberScope().getCallableSymbols()
|
|
||||||
.filterIsInstance<KtPropertySymbol>()
|
|
||||||
.filter { it.hasJvmFieldAnnotation() || it.isConst }
|
|
||||||
.mapTo(result) {
|
|
||||||
FirLightFieldForPropertySymbol(
|
|
||||||
propertySymbol = it,
|
|
||||||
containingClass = this@FirLightClassForSymbol,
|
|
||||||
lightMemberOrigin = null,
|
|
||||||
isTopLevel = false,
|
|
||||||
forceStatic = true
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val isNamedObject = classOrObjectSymbol.classKind == KtClassKind.OBJECT
|
|
||||||
if (isNamedObject && classOrObjectSymbol.symbolKind != KtSymbolKind.LOCAL) {
|
|
||||||
result.add(FirLightFieldForObjectSymbol(classOrObjectSymbol, this@FirLightClassForSymbol, null))
|
|
||||||
}
|
|
||||||
|
|
||||||
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
|
||||||
val callableSymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
|
||||||
.filterIsInstance<KtPropertySymbol>()
|
|
||||||
.applyIf(classOrObjectSymbol.classKind == KtClassKind.COMPANION_OBJECT) {
|
|
||||||
filter { it.hasJvmFieldAnnotation() || it.isConst }
|
|
||||||
}
|
|
||||||
createFields(callableSymbols, isTopLevel = false, result)
|
|
||||||
}
|
|
||||||
|
|
||||||
result
|
|
||||||
}
|
|
||||||
|
|
||||||
private val _containingFile: PsiFile? by lazyPub {
|
|
||||||
|
|
||||||
val kotlinOrigin = kotlinOrigin ?: return@lazyPub null
|
|
||||||
|
|
||||||
val containingClass = isTopLevel.ifFalse { create(getOutermostClassOrObject(kotlinOrigin)) } ?: this
|
|
||||||
|
|
||||||
FirFakeFileImpl(kotlinOrigin, containingClass)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getContainingFile(): PsiFile? = _containingFile
|
|
||||||
|
|
||||||
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: this
|
|
||||||
|
|
||||||
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
|
||||||
basicIsEquivalentTo(this, another) ||
|
|
||||||
another is PsiClass && qualifiedName != null && Comparing.equal(another.qualifiedName, qualifiedName)
|
|
||||||
|
|
||||||
override fun getElementIcon(flags: Int): Icon? =
|
|
||||||
throw UnsupportedOperationException("This should be done by JetIconProvider")
|
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
|
||||||
this === other ||
|
|
||||||
(other is FirLightClassForSymbol && kotlinOrigin == other.kotlinOrigin && classOrObjectSymbol == other.classOrObjectSymbol)
|
|
||||||
|
|
||||||
override fun hashCode(): Int = kotlinOrigin.hashCode()
|
|
||||||
|
|
||||||
override fun getName(): String = classOrObjectSymbol.name.asString()
|
|
||||||
|
|
||||||
override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
|
|
||||||
|
|
||||||
override fun isInterface(): Boolean =
|
|
||||||
classOrObjectSymbol.classKind == KtClassKind.INTERFACE || classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS
|
|
||||||
|
|
||||||
override fun isAnnotationType(): Boolean =
|
|
||||||
classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS
|
|
||||||
|
|
||||||
override fun isEnum(): Boolean =
|
|
||||||
classOrObjectSymbol.classKind == KtClassKind.ENUM_CLASS
|
|
||||||
|
|
||||||
override fun hasTypeParameters(): Boolean =
|
|
||||||
classOrObjectSymbol is KtClass && classOrObjectSymbol.typeParameters.isNotEmpty()
|
|
||||||
|
|
||||||
override fun isValid(): Boolean = kotlinOrigin?.isValid ?: true
|
|
||||||
|
|
||||||
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean =
|
|
||||||
InheritanceImplUtil.isInheritor(this, baseClass, checkDeep)
|
|
||||||
|
|
||||||
@Throws(IncorrectOperationException::class)
|
|
||||||
override fun setName(@NonNls name: String): PsiElement =
|
|
||||||
throw IncorrectOperationException()
|
|
||||||
|
|
||||||
override fun toString() =
|
|
||||||
"${this::class.java.simpleName}:${kotlinOrigin?.getDebugText()}"
|
|
||||||
|
|
||||||
override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: TODO()
|
|
||||||
override fun getElementType(): IStubElementType<out StubElement<*>, *>? = kotlinOrigin?.elementType
|
|
||||||
override fun getStub(): KotlinClassOrObjectStub<out KtClassOrObject>? = kotlinOrigin?.stub
|
|
||||||
|
|
||||||
override val originKind: LightClassOriginKind
|
|
||||||
get() = LightClassOriginKind.SOURCE
|
|
||||||
|
|
||||||
override fun getQualifiedName() = kotlinOrigin?.fqName?.asString()
|
|
||||||
|
|
||||||
override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this)
|
|
||||||
override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this)
|
|
||||||
override fun getSupers(): Array<PsiClass> = PsiClassImplUtil.getSupers(this)
|
|
||||||
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
|
|
||||||
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
|
|
||||||
|
|
||||||
override fun getRBrace(): PsiElement? = null
|
|
||||||
override fun getLBrace(): PsiElement? = null
|
|
||||||
|
|
||||||
override fun getInitializers(): Array<PsiClassInitializer> = emptyArray()
|
|
||||||
|
|
||||||
override fun getContainingClass(): PsiClass? {
|
|
||||||
|
|
||||||
val containingBody = kotlinOrigin?.parent as? KtClassBody
|
|
||||||
val containingClass = containingBody?.parent as? KtClassOrObject
|
|
||||||
containingClass?.let { return create(it) }
|
|
||||||
|
|
||||||
val containingBlock = kotlinOrigin?.parent as? KtBlockExpression
|
|
||||||
// val containingScript = containingBlock?.parent as? KtScript
|
|
||||||
// containingScript?.let { return KtLightClassForScript.create(it) }
|
|
||||||
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getParent(): PsiElement? = containingClass ?: containingFile
|
|
||||||
|
|
||||||
override fun getScope(): PsiElement? = parent
|
|
||||||
|
|
||||||
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
|
|
||||||
baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false
|
|
||||||
|
|
||||||
override fun copy(): FirLightClassForSymbol =
|
|
||||||
FirLightClassForSymbol(classOrObjectSymbol, manager)
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
fun create(classOrObject: KtClassOrObject): FirLightClassForSymbol? =
|
|
||||||
CachedValuesManager.getCachedValue(classOrObject) {
|
|
||||||
CachedValueProvider.Result
|
|
||||||
.create(
|
|
||||||
createNoCache(classOrObject),
|
|
||||||
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun createNoCache(classOrObject: KtClassOrObject): FirLightClassForSymbol? {
|
|
||||||
val containingFile = classOrObject.containingFile
|
|
||||||
if (containingFile is KtCodeFragment) {
|
|
||||||
// Avoid building light classes for code fragments
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
if (classOrObject.shouldNotBeVisibleAsLightClass()) {
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
|
|
||||||
return when {
|
|
||||||
classOrObject.isObjectLiteral() -> return null //TODO
|
|
||||||
classOrObject.safeIsLocal() -> return null //TODO
|
|
||||||
classOrObject.hasModifier(KtTokens.INLINE_KEYWORD) -> return null //TODO
|
|
||||||
else -> FirLightClassForSymbol(
|
|
||||||
analyze(classOrObject) { classOrObject.getClassOrObjectSymbol() },
|
|
||||||
manager = classOrObject.manager
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+67
@@ -0,0 +1,67 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava.classes
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.psi.PsiReferenceList
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassForClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassKind
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
|
||||||
|
|
||||||
|
internal class FirLightAnnotationClassSymbol(
|
||||||
|
private val classOrObjectSymbol: KtClassOrObjectSymbol,
|
||||||
|
manager: PsiManager
|
||||||
|
) : FirLightInterfaceOrAnnotationClassSymbol(classOrObjectSymbol, manager) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
require(classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isAnnotationType(): Boolean = true
|
||||||
|
|
||||||
|
private val _ownFields: List<KtLightField> by lazyPub {
|
||||||
|
//TODO
|
||||||
|
mutableListOf<KtLightField>().also {
|
||||||
|
it.addCompanionObjectFieldIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOwnFields(): List<KtLightField> = _ownFields
|
||||||
|
|
||||||
|
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
||||||
|
//TODO
|
||||||
|
val result = mutableListOf<KtLightMethod>()
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||||
|
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
.filterNot { it is KtFunctionSymbol && it.visibility == KtSymbolVisibility.PRIVATE }
|
||||||
|
.filterNot { it is KtConstructorSymbol }
|
||||||
|
|
||||||
|
createMethods(visibleDeclarations, isTopLevel = false, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
||||||
|
|
||||||
|
override fun getExtendsList(): PsiReferenceList? = null
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
other is FirLightAnnotationClassSymbol && classOrObjectSymbol == other.classOrObjectSymbol
|
||||||
|
|
||||||
|
override fun hashCode(): Int = classOrObjectSymbol.hashCode()
|
||||||
|
|
||||||
|
override fun copy(): FirLightClassForClassOrObjectSymbol = FirLightAnnotationClassSymbol(classOrObjectSymbol, manager)
|
||||||
|
}
|
||||||
+156
@@ -0,0 +1,156 @@
|
|||||||
|
/*
|
||||||
|
* 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.idea.asJava
|
||||||
|
|
||||||
|
import com.intellij.navigation.ItemPresentation
|
||||||
|
import com.intellij.navigation.ItemPresentationProviders
|
||||||
|
import com.intellij.openapi.util.Pair
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.impl.PsiClassImplUtil
|
||||||
|
import com.intellij.psi.impl.PsiImplUtil
|
||||||
|
import com.intellij.psi.impl.PsiSuperMethodImplUtil
|
||||||
|
import com.intellij.psi.impl.light.LightElement
|
||||||
|
import com.intellij.psi.impl.source.PsiExtensibleClass
|
||||||
|
import com.intellij.psi.javadoc.PsiDocComment
|
||||||
|
import com.intellij.psi.scope.PsiScopeProcessor
|
||||||
|
import com.intellij.psi.util.PsiUtil
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KotlinClassInnerStuffCache.Companion.processDeclarationsInEnum
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.cannotModify
|
||||||
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
|
import javax.swing.Icon
|
||||||
|
|
||||||
|
abstract class FirLightClassBase protected constructor(manager: PsiManager) : LightElement(manager, KotlinLanguage.INSTANCE), PsiClass,
|
||||||
|
KtLightClass, PsiExtensibleClass {
|
||||||
|
|
||||||
|
override val clsDelegate: PsiClass
|
||||||
|
get() = invalidAccess()
|
||||||
|
|
||||||
|
protected open val myInnersCache = KotlinClassInnerStuffCache(
|
||||||
|
myClass = this,
|
||||||
|
externalDependencies = listOf(KotlinModificationTrackerService.getInstance(manager.project).outOfBlockModificationTracker)
|
||||||
|
)
|
||||||
|
|
||||||
|
override fun getFields(): Array<PsiField> = myInnersCache.fields
|
||||||
|
|
||||||
|
override fun getMethods(): Array<PsiMethod> = myInnersCache.methods
|
||||||
|
|
||||||
|
override fun getConstructors(): Array<PsiMethod> = myInnersCache.constructors
|
||||||
|
|
||||||
|
override fun getInnerClasses(): Array<out PsiClass> = myInnersCache.innerClasses
|
||||||
|
|
||||||
|
override fun getAllFields(): Array<PsiField> = PsiClassImplUtil.getAllFields(this)
|
||||||
|
|
||||||
|
override fun getAllMethods(): Array<PsiMethod> = PsiClassImplUtil.getAllMethods(this)
|
||||||
|
|
||||||
|
override fun getAllInnerClasses(): Array<PsiClass> = PsiClassImplUtil.getAllInnerClasses(this)
|
||||||
|
|
||||||
|
override fun findFieldByName(name: String, checkBases: Boolean) =
|
||||||
|
myInnersCache.findFieldByName(name, checkBases)
|
||||||
|
|
||||||
|
override fun findMethodsByName(name: String, checkBases: Boolean): Array<PsiMethod> =
|
||||||
|
myInnersCache.findMethodsByName(name, checkBases)
|
||||||
|
|
||||||
|
override fun findInnerClassByName(name: String, checkBases: Boolean): PsiClass? =
|
||||||
|
myInnersCache.findInnerClassByName(name, checkBases)
|
||||||
|
|
||||||
|
override fun processDeclarations(
|
||||||
|
processor: PsiScopeProcessor, state: ResolveState, lastParent: PsiElement?, place: PsiElement
|
||||||
|
): Boolean {
|
||||||
|
|
||||||
|
if (isEnum && !processDeclarationsInEnum(processor, state, myInnersCache)) return false
|
||||||
|
|
||||||
|
return PsiClassImplUtil.processDeclarationsInClass(
|
||||||
|
this,
|
||||||
|
processor,
|
||||||
|
state,
|
||||||
|
null,
|
||||||
|
lastParent,
|
||||||
|
place,
|
||||||
|
PsiUtil.getLanguageLevel(place),
|
||||||
|
false
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getText(): String = kotlinOrigin?.text ?: ""
|
||||||
|
|
||||||
|
override fun getLanguage(): KotlinLanguage = KotlinLanguage.INSTANCE
|
||||||
|
|
||||||
|
override fun getPresentation(): ItemPresentation? =
|
||||||
|
ItemPresentationProviders.getItemPresentation(this)
|
||||||
|
|
||||||
|
abstract override fun equals(other: Any?): Boolean
|
||||||
|
|
||||||
|
abstract override fun hashCode(): Int
|
||||||
|
|
||||||
|
override fun getContext(): PsiElement = parent
|
||||||
|
|
||||||
|
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
||||||
|
PsiClassImplUtil.isClassEquivalentTo(this, another)
|
||||||
|
|
||||||
|
override fun getDocComment(): PsiDocComment? = null
|
||||||
|
|
||||||
|
override fun hasTypeParameters(): Boolean = PsiImplUtil.hasTypeParameters(this)
|
||||||
|
|
||||||
|
override fun getExtendsListTypes(): Array<PsiClassType?> =
|
||||||
|
PsiClassImplUtil.getExtendsListTypes(this)
|
||||||
|
|
||||||
|
override fun getImplementsListTypes(): Array<PsiClassType?> =
|
||||||
|
PsiClassImplUtil.getImplementsListTypes(this)
|
||||||
|
|
||||||
|
override fun findMethodBySignature(patternMethod: PsiMethod?, checkBases: Boolean): PsiMethod? =
|
||||||
|
patternMethod?.let { PsiClassImplUtil.findMethodBySignature(this, it, checkBases) }
|
||||||
|
|
||||||
|
override fun findMethodsBySignature(patternMethod: PsiMethod?, checkBases: Boolean): Array<PsiMethod?> =
|
||||||
|
patternMethod?.let { PsiClassImplUtil.findMethodsBySignature(this, it, checkBases) } ?: emptyArray()
|
||||||
|
|
||||||
|
override fun findMethodsAndTheirSubstitutorsByName(
|
||||||
|
@NonNls name: String?,
|
||||||
|
checkBases: Boolean
|
||||||
|
): List<Pair<PsiMethod?, PsiSubstitutor?>?> =
|
||||||
|
PsiClassImplUtil.findMethodsAndTheirSubstitutorsByName(this, name, checkBases)
|
||||||
|
|
||||||
|
override fun getAllMethodsAndTheirSubstitutors(): List<Pair<PsiMethod?, PsiSubstitutor?>?> {
|
||||||
|
return PsiClassImplUtil.getAllWithSubstitutorsByMap(this, PsiClassImplUtil.MemberType.METHOD)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getRBrace(): PsiElement? = null
|
||||||
|
|
||||||
|
override fun getLBrace(): PsiElement? = null
|
||||||
|
|
||||||
|
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
|
||||||
|
|
||||||
|
override fun getElementIcon(flags: Int): Icon? =
|
||||||
|
throw UnsupportedOperationException("This should be done by KotlinFirIconProvider")
|
||||||
|
|
||||||
|
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
|
||||||
|
|
||||||
|
override fun setName(name: String): PsiElement? = cannotModify()
|
||||||
|
|
||||||
|
abstract override fun copy(): PsiElement
|
||||||
|
|
||||||
|
override fun accept(visitor: PsiElementVisitor) {
|
||||||
|
if (visitor is JavaElementVisitor) {
|
||||||
|
visitor.visitClass(this)
|
||||||
|
} else {
|
||||||
|
visitor.visitElement(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
+180
@@ -0,0 +1,180 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.Comparing
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.impl.InheritanceImplUtil
|
||||||
|
import com.intellij.psi.impl.PsiClassImplUtil
|
||||||
|
import com.intellij.psi.search.SearchScope
|
||||||
|
import com.intellij.psi.stubs.IStubElementType
|
||||||
|
import com.intellij.psi.stubs.StubElement
|
||||||
|
import org.jetbrains.annotations.NonNls
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KotlinSuperTypeListBuilder
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.getOutermostClassOrObject
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightIdentifier
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.getOrCreateFirLightClass
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
|
||||||
|
import org.jetbrains.kotlin.idea.util.ifFalse
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||||
|
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassBody
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
import org.jetbrains.kotlin.psi.debugText.getDebugText
|
||||||
|
import org.jetbrains.kotlin.psi.stubs.KotlinClassOrObjectStub
|
||||||
|
|
||||||
|
internal abstract class FirLightClassForClassOrObjectSymbol(
|
||||||
|
private val classOrObjectSymbol: KtClassOrObjectSymbol,
|
||||||
|
manager: PsiManager
|
||||||
|
) : FirLightClassBase(manager),
|
||||||
|
StubBasedPsiElement<KotlinClassOrObjectStub<out KtClassOrObject>> {
|
||||||
|
|
||||||
|
private val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL
|
||||||
|
|
||||||
|
abstract override fun getModifierList(): PsiModifierList?
|
||||||
|
abstract override fun getOwnFields(): List<KtLightField>
|
||||||
|
abstract override fun getOwnMethods(): List<PsiMethod>
|
||||||
|
override fun isDeprecated(): Boolean = false //TODO()
|
||||||
|
override fun getNameIdentifier(): KtLightIdentifier? = null //TODO()
|
||||||
|
abstract override fun getExtendsList(): PsiReferenceList?
|
||||||
|
abstract override fun getImplementsList(): PsiReferenceList?
|
||||||
|
override fun getTypeParameterList(): PsiTypeParameterList? = null //TODO()
|
||||||
|
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray() //TODO()
|
||||||
|
|
||||||
|
abstract override fun getOwnInnerClasses(): List<PsiClass>
|
||||||
|
|
||||||
|
override fun getTextOffset(): Int = kotlinOrigin?.textOffset ?: 0
|
||||||
|
override fun getStartOffsetInParent(): Int = kotlinOrigin?.startOffsetInParent ?: 0
|
||||||
|
override fun isWritable() = kotlinOrigin?.isWritable ?: false
|
||||||
|
override val kotlinOrigin: KtClassOrObject? = classOrObjectSymbol.psi as? KtClassOrObject
|
||||||
|
|
||||||
|
protected fun createInheritanceList(forExtendsList: Boolean): PsiReferenceList {
|
||||||
|
|
||||||
|
val role = if (forExtendsList) PsiReferenceList.Role.EXTENDS_LIST else PsiReferenceList.Role.IMPLEMENTS_LIST
|
||||||
|
|
||||||
|
val listBuilder = KotlinSuperTypeListBuilder(
|
||||||
|
kotlinOrigin = kotlinOrigin?.getSuperTypeList(),
|
||||||
|
manager = manager,
|
||||||
|
language = language,
|
||||||
|
role = role
|
||||||
|
)
|
||||||
|
|
||||||
|
fun KtType.needToAddTypeIntoList(): Boolean {
|
||||||
|
if (this !is KtClassType) return false
|
||||||
|
|
||||||
|
// Do not add redundant "extends java.lang.Object" anywhere
|
||||||
|
if (this.classId == StandardClassIds.Any) return false
|
||||||
|
|
||||||
|
// We don't have Enum among enums supertype in sources neither we do for decompiled class-files and light-classes
|
||||||
|
if (isEnum && this.classId == StandardClassIds.Enum) return false
|
||||||
|
|
||||||
|
val isInterfaceType =
|
||||||
|
(this.classSymbol as? KtClassOrObjectSymbol)?.classKind == KtClassKind.INTERFACE
|
||||||
|
|
||||||
|
return forExtendsList == !isInterfaceType
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO Add support for kotlin.collections.
|
||||||
|
classOrObjectSymbol.superTypes
|
||||||
|
.filterIsInstance<KtClassType>()
|
||||||
|
.filter { it.needToAddTypeIntoList() }
|
||||||
|
.mapNotNull { it.mapSupertype(this, kotlinCollectionAsIs = true) }
|
||||||
|
.forEach { listBuilder.addReference(it) }
|
||||||
|
|
||||||
|
return listBuilder
|
||||||
|
}
|
||||||
|
|
||||||
|
protected fun MutableList<KtLightField>.addCompanionObjectFieldIfNeeded() {
|
||||||
|
classOrObjectSymbol.companionObject?.run {
|
||||||
|
add(FirLightFieldForObjectSymbol(this, this@FirLightClassForClassOrObjectSymbol, null))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _containingFile: PsiFile? by lazyPub {
|
||||||
|
|
||||||
|
val kotlinOrigin = kotlinOrigin ?: return@lazyPub null
|
||||||
|
|
||||||
|
val containingClass = isTopLevel.ifFalse { getOrCreateFirLightClass(getOutermostClassOrObject(kotlinOrigin)) } ?: this
|
||||||
|
|
||||||
|
FirFakeFileImpl(kotlinOrigin, containingClass)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getContainingFile(): PsiFile? = _containingFile
|
||||||
|
|
||||||
|
override fun getNavigationElement(): PsiElement = kotlinOrigin ?: this
|
||||||
|
|
||||||
|
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
||||||
|
basicIsEquivalentTo(this, another) ||
|
||||||
|
another is PsiClass && qualifiedName != null && Comparing.equal(another.qualifiedName, qualifiedName)
|
||||||
|
|
||||||
|
abstract override fun equals(other: Any?): Boolean
|
||||||
|
|
||||||
|
abstract override fun hashCode(): Int
|
||||||
|
|
||||||
|
override fun getName(): String = classOrObjectSymbol.name.asString()
|
||||||
|
|
||||||
|
override fun hasModifierProperty(@NonNls name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
|
||||||
|
|
||||||
|
abstract override fun isInterface(): Boolean
|
||||||
|
|
||||||
|
abstract override fun isAnnotationType(): Boolean
|
||||||
|
|
||||||
|
abstract override fun isEnum(): Boolean
|
||||||
|
|
||||||
|
override fun hasTypeParameters(): Boolean =
|
||||||
|
classOrObjectSymbol is KtClass && classOrObjectSymbol.typeParameters.isNotEmpty()
|
||||||
|
|
||||||
|
override fun isValid(): Boolean = kotlinOrigin?.isValid ?: true
|
||||||
|
|
||||||
|
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean =
|
||||||
|
InheritanceImplUtil.isInheritor(this, baseClass, checkDeep)
|
||||||
|
|
||||||
|
override fun toString() =
|
||||||
|
"${this::class.java.simpleName}:${kotlinOrigin?.getDebugText()}"
|
||||||
|
|
||||||
|
override fun getUseScope(): SearchScope = kotlinOrigin?.useScope ?: TODO()
|
||||||
|
override fun getElementType(): IStubElementType<out StubElement<*>, *>? = kotlinOrigin?.elementType
|
||||||
|
override fun getStub(): KotlinClassOrObjectStub<out KtClassOrObject>? = kotlinOrigin?.stub
|
||||||
|
|
||||||
|
override val originKind: LightClassOriginKind
|
||||||
|
get() = LightClassOriginKind.SOURCE
|
||||||
|
|
||||||
|
override fun getQualifiedName() = kotlinOrigin?.fqName?.asString()
|
||||||
|
|
||||||
|
override fun getInterfaces(): Array<PsiClass> = PsiClassImplUtil.getInterfaces(this)
|
||||||
|
override fun getSuperClass(): PsiClass? = PsiClassImplUtil.getSuperClass(this)
|
||||||
|
override fun getSupers(): Array<PsiClass> = PsiClassImplUtil.getSupers(this)
|
||||||
|
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
|
||||||
|
|
||||||
|
override fun getContainingClass(): PsiClass? {
|
||||||
|
|
||||||
|
val containingBody = kotlinOrigin?.parent as? KtClassBody
|
||||||
|
val containingClass = containingBody?.parent as? KtClassOrObject
|
||||||
|
containingClass?.let { return getOrCreateFirLightClass(it) }
|
||||||
|
|
||||||
|
val containingBlock = kotlinOrigin?.parent as? KtBlockExpression
|
||||||
|
// val containingScript = containingBlock?.parent as? KtScript
|
||||||
|
// containingScript?.let { return KtLightClassForScript.create(it) }
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getParent(): PsiElement? = containingClass ?: containingFile
|
||||||
|
|
||||||
|
override fun getScope(): PsiElement? = parent
|
||||||
|
|
||||||
|
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean =
|
||||||
|
baseClass?.let { InheritanceImplUtil.isInheritorDeep(this, it, classToByPass) } ?: false
|
||||||
|
|
||||||
|
abstract override fun copy(): FirLightClassForClassOrObjectSymbol
|
||||||
|
}
|
||||||
+139
@@ -0,0 +1,139 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.asJava.classes
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import com.intellij.psi.impl.PsiClassImplUtil
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.*
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassModifierList
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightPsiJavaCodeReferenceElementWithNoReference
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.createMethods
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.fields.FirLightFieldForEnumEntry
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType
|
||||||
|
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||||
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
|
|
||||||
|
internal class FirLightClassForEnumEntry(
|
||||||
|
private val enumEntrySymbol: KtEnumEntrySymbol,
|
||||||
|
private val enumConstant: FirLightFieldForEnumEntry,
|
||||||
|
private val enumClass: FirLightClassForSymbol,
|
||||||
|
manager: PsiManager
|
||||||
|
) : FirLightClassBase(manager), PsiEnumConstantInitializer {
|
||||||
|
|
||||||
|
override fun getName(): String? = enumEntrySymbol.name.asString()
|
||||||
|
|
||||||
|
override fun getBaseClassType(): PsiClassType = enumConstant.type as PsiClassType //???TODO
|
||||||
|
|
||||||
|
override fun getBaseClassReference(): PsiJavaCodeReferenceElement =
|
||||||
|
FirLightPsiJavaCodeReferenceElementWithNoReference(enumConstant) //???TODO
|
||||||
|
|
||||||
|
override fun getArgumentList(): PsiExpressionList? = null
|
||||||
|
|
||||||
|
override fun getEnumConstant(): PsiEnumConstant = enumConstant
|
||||||
|
|
||||||
|
override fun isInQualifiedNew(): Boolean = false
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
other is FirLightClassForEnumEntry &&
|
||||||
|
this.enumEntrySymbol == other.enumEntrySymbol
|
||||||
|
|
||||||
|
override fun hashCode(): Int =
|
||||||
|
enumEntrySymbol.hashCode()
|
||||||
|
|
||||||
|
override fun copy(): PsiElement =
|
||||||
|
FirLightClassForEnumEntry(enumEntrySymbol, enumConstant, enumClass, manager)
|
||||||
|
|
||||||
|
override fun toString(): String = "FirLightClassForEnumEntry for $name"
|
||||||
|
|
||||||
|
override fun getNameIdentifier(): PsiIdentifier? = null //TODO
|
||||||
|
|
||||||
|
private val _modifierList: PsiModifierList by lazyPub {
|
||||||
|
FirLightClassModifierList(
|
||||||
|
containingDeclaration = this,
|
||||||
|
modifiers = setOf(PsiModifier.PUBLIC, PsiModifier.STATIC, PsiModifier.FINAL),
|
||||||
|
annotations = emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||||
|
|
||||||
|
override fun hasModifierProperty(name: String): Boolean =
|
||||||
|
name == PsiModifier.PUBLIC || name == PsiModifier.STATIC || name == PsiModifier.FINAL
|
||||||
|
|
||||||
|
override fun getContainingClass(): PsiClass? = enumClass
|
||||||
|
|
||||||
|
override fun isDeprecated(): Boolean = false
|
||||||
|
|
||||||
|
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray()
|
||||||
|
|
||||||
|
override fun getTypeParameterList(): PsiTypeParameterList? = null
|
||||||
|
|
||||||
|
override fun getQualifiedName(): String? = "${enumConstant.containingClass.qualifiedName}.${enumConstant.name}"
|
||||||
|
|
||||||
|
override fun isInterface(): Boolean = false
|
||||||
|
|
||||||
|
override fun isAnnotationType(): Boolean = false
|
||||||
|
|
||||||
|
override fun isEnum(): Boolean = false
|
||||||
|
|
||||||
|
private val _extendsList: PsiReferenceList? by lazyPub {
|
||||||
|
|
||||||
|
val mappedType = (enumEntrySymbol.type as? KtClassType)?.let {
|
||||||
|
it.mapSupertype(this@FirLightClassForEnumEntry)
|
||||||
|
} ?: return@lazyPub null
|
||||||
|
|
||||||
|
KotlinSuperTypeListBuilder(
|
||||||
|
kotlinOrigin = enumClass.kotlinOrigin?.getSuperTypeList(),
|
||||||
|
manager = manager,
|
||||||
|
language = language,
|
||||||
|
role = PsiReferenceList.Role.EXTENDS_LIST
|
||||||
|
).also {
|
||||||
|
it.addReference(mappedType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
||||||
|
|
||||||
|
override fun getImplementsList(): PsiReferenceList? = null
|
||||||
|
|
||||||
|
override fun getSuperClass(): PsiClass? = enumClass
|
||||||
|
|
||||||
|
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
||||||
|
|
||||||
|
override fun getSupers(): Array<PsiClass> = arrayOf(enumClass)
|
||||||
|
|
||||||
|
override fun getSuperTypes(): Array<PsiClassType> = PsiClassImplUtil.getSuperTypes(this)
|
||||||
|
|
||||||
|
override fun getParent(): PsiElement? = containingClass ?: containingFile
|
||||||
|
|
||||||
|
override fun getScope(): PsiElement? = parent
|
||||||
|
|
||||||
|
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = false //TODO
|
||||||
|
|
||||||
|
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = false //TODO
|
||||||
|
|
||||||
|
override val kotlinOrigin: KtClassOrObject? = enumConstant.kotlinOrigin
|
||||||
|
|
||||||
|
override val originKind: LightClassOriginKind = LightClassOriginKind.SOURCE
|
||||||
|
|
||||||
|
override fun getOwnFields(): MutableList<PsiField> = mutableListOf()
|
||||||
|
|
||||||
|
override fun getOwnMethods(): MutableList<KtLightMethod> {
|
||||||
|
val result = mutableListOf<KtLightMethod>()
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(enumEntrySymbol) {
|
||||||
|
val callableSymbols = enumEntrySymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
createMethods(callableSymbols, isTopLevel = false, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOwnInnerClasses(): MutableList<PsiClass> = mutableListOf()
|
||||||
|
}
|
||||||
+2
-17
@@ -8,26 +8,23 @@ package org.jetbrains.kotlin.idea.asJava
|
|||||||
import com.intellij.openapi.util.Comparing
|
import com.intellij.openapi.util.Comparing
|
||||||
import com.intellij.openapi.util.TextRange
|
import com.intellij.openapi.util.TextRange
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.impl.PsiSuperMethodImplUtil
|
|
||||||
import com.intellij.psi.impl.light.LightEmptyImplementsList
|
import com.intellij.psi.impl.light.LightEmptyImplementsList
|
||||||
import com.intellij.psi.impl.light.LightModifierList
|
import com.intellij.psi.impl.light.LightModifierList
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import org.jetbrains.kotlin.asJava.classes.*
|
import org.jetbrains.kotlin.asJava.classes.*
|
||||||
import org.jetbrains.kotlin.asJava.elements.*
|
import org.jetbrains.kotlin.asJava.elements.*
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
|
||||||
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
import org.jetbrains.kotlin.fileClasses.JvmFileClassUtil
|
||||||
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
import org.jetbrains.kotlin.fileClasses.javaFileFacadeFqName
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.types.ConeNullability
|
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.createFields
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.createMethods
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtCallableSymbol
|
||||||
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
import org.jetbrains.kotlin.load.java.structure.LightClassOriginKind
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
|
import org.jetbrains.kotlin.psi.psiUtil.isPrivate
|
||||||
import org.jetbrains.kotlin.util.collectionUtils.filterIsInstanceAnd
|
|
||||||
import javax.swing.Icon
|
|
||||||
|
|
||||||
class FirLightClassForFacade(
|
class FirLightClassForFacade(
|
||||||
manager: PsiManager,
|
manager: PsiManager,
|
||||||
@@ -200,20 +197,12 @@ class FirLightClassForFacade(
|
|||||||
|
|
||||||
override fun getAllInnerClasses(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
override fun getAllInnerClasses(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
|
||||||
|
|
||||||
override fun getInitializers(): Array<out PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
|
|
||||||
|
|
||||||
override fun findInnerClassByName(@NonNls name: String, checkBases: Boolean): PsiClass? = null
|
override fun findInnerClassByName(@NonNls name: String, checkBases: Boolean): PsiClass? = null
|
||||||
|
|
||||||
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = false
|
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = false
|
||||||
|
|
||||||
override fun getLBrace(): PsiElement? = null
|
|
||||||
|
|
||||||
override fun getRBrace(): PsiElement? = null
|
|
||||||
|
|
||||||
override fun getName(): String = facadeClassFqName.shortName().asString()
|
override fun getName(): String = facadeClassFqName.shortName().asString()
|
||||||
|
|
||||||
override fun setName(name: String): PsiElement? = cannotModify()
|
|
||||||
|
|
||||||
override fun getQualifiedName() = facadeClassFqName.asString()
|
override fun getQualifiedName() = facadeClassFqName.asString()
|
||||||
|
|
||||||
override fun getNameIdentifier(): PsiIdentifier? = null
|
override fun getNameIdentifier(): PsiIdentifier? = null
|
||||||
@@ -225,8 +214,6 @@ class FirLightClassForFacade(
|
|||||||
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
override fun isEquivalentTo(another: PsiElement?): Boolean =
|
||||||
equals(another) || another is FirLightClassForFacade && Comparing.equal(another.qualifiedName, qualifiedName)
|
equals(another) || another is FirLightClassForFacade && Comparing.equal(another.qualifiedName, qualifiedName)
|
||||||
|
|
||||||
override fun getElementIcon(flags: Int): Icon? = throw UnsupportedOperationException("This should be done by JetIconProvider")
|
|
||||||
|
|
||||||
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean {
|
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean {
|
||||||
return baseClass.qualifiedName == CommonClassNames.JAVA_LANG_OBJECT
|
return baseClass.qualifiedName == CommonClassNames.JAVA_LANG_OBJECT
|
||||||
}
|
}
|
||||||
@@ -267,6 +254,4 @@ class FirLightClassForFacade(
|
|||||||
override fun getStartOffsetInParent() = firstFileInFacade.startOffsetInParent
|
override fun getStartOffsetInParent() = firstFileInFacade.startOffsetInParent
|
||||||
|
|
||||||
override fun isWritable() = files.all { it.isWritable }
|
override fun isWritable() = files.all { it.isWritable }
|
||||||
|
|
||||||
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = PsiSuperMethodImplUtil.getVisibleSignatures(this)
|
|
||||||
}
|
}
|
||||||
+195
@@ -0,0 +1,195 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_DEFAULT_CTOR
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.createFields
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.classes.createMethods
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.fields.FirLightFieldForEnumEntry
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibility
|
||||||
|
|
||||||
|
internal class FirLightClassForSymbol(
|
||||||
|
private val classOrObjectSymbol: KtClassOrObjectSymbol,
|
||||||
|
manager: PsiManager
|
||||||
|
) : FirLightClassForClassOrObjectSymbol(classOrObjectSymbol, manager) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
require(classOrObjectSymbol.classKind != KtClassKind.INTERFACE && classOrObjectSymbol.classKind != KtClassKind.ANNOTATION_CLASS)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun tryGetEffectiveVisibility(symbol: KtCallableSymbol): KtSymbolVisibility? {
|
||||||
|
|
||||||
|
if (symbol !is KtPropertySymbol && symbol !is KtFunctionSymbol) return null
|
||||||
|
|
||||||
|
var visibility = (symbol as? KtSymbolWithVisibility)?.visibility
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(symbol) {
|
||||||
|
for (overriddenSymbol in symbol.getOverriddenSymbols(classOrObjectSymbol)) {
|
||||||
|
val newVisibility = (overriddenSymbol as? KtSymbolWithVisibility)?.visibility
|
||||||
|
if (newVisibility != null) {
|
||||||
|
visibility = newVisibility
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return visibility
|
||||||
|
}
|
||||||
|
|
||||||
|
private val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL
|
||||||
|
|
||||||
|
private val _modifierList: PsiModifierList? by lazyPub {
|
||||||
|
|
||||||
|
val modifiers = mutableSetOf(classOrObjectSymbol.computeVisibility(isTopLevel))
|
||||||
|
classOrObjectSymbol.computeSimpleModality()?.run {
|
||||||
|
modifiers.add(this)
|
||||||
|
}
|
||||||
|
if (!isTopLevel && !classOrObjectSymbol.isInner) {
|
||||||
|
modifiers.add(PsiModifier.STATIC)
|
||||||
|
}
|
||||||
|
|
||||||
|
val annotations = classOrObjectSymbol.computeAnnotations(
|
||||||
|
parent = this@FirLightClassForSymbol,
|
||||||
|
nullability = NullabilityType.Unknown,
|
||||||
|
annotationUseSiteTarget = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
FirLightClassModifierList(this@FirLightClassForSymbol, modifiers, annotations)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||||
|
override fun getOwnFields(): List<KtLightField> = _ownFields
|
||||||
|
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
||||||
|
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
||||||
|
override fun getImplementsList(): PsiReferenceList? = _implementsList
|
||||||
|
|
||||||
|
override fun getOwnInnerClasses(): List<PsiClass> {
|
||||||
|
val result = ArrayList<PsiClass>()
|
||||||
|
|
||||||
|
// workaround for ClassInnerStuffCache not supporting classes with null names, see KT-13927
|
||||||
|
// inner classes with null names can't be searched for and can't be used from java anyway
|
||||||
|
// we can't prohibit creating light classes with null names either since they can contain members
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||||
|
classOrObjectSymbol.getDeclaredMemberScope().getAllSymbols().filterIsInstance<KtClassOrObjectSymbol>().mapTo(result) {
|
||||||
|
FirLightClassForSymbol(it, manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO
|
||||||
|
//if (classOrObject.hasInterfaceDefaultImpls) {
|
||||||
|
// result.add(KtLightClassForInterfaceDefaultImpls(classOrObject))
|
||||||
|
//}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getTextOffset(): Int = kotlinOrigin?.textOffset ?: 0
|
||||||
|
override fun getStartOffsetInParent(): Int = kotlinOrigin?.startOffsetInParent ?: 0
|
||||||
|
override fun isWritable() = kotlinOrigin?.isWritable ?: false
|
||||||
|
|
||||||
|
private val _extendsList by lazyPub { createInheritanceList(forExtendsList = true) }
|
||||||
|
private val _implementsList by lazyPub { createInheritanceList(forExtendsList = false) }
|
||||||
|
|
||||||
|
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
||||||
|
|
||||||
|
val result = mutableListOf<KtLightMethod>()
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||||
|
val callableSymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
val visibleDeclarations = callableSymbols.applyIf(isEnum) {
|
||||||
|
filterNot { function ->
|
||||||
|
function is KtFunctionSymbol && function.name.asString().let { it == "values" || it == "valueOf" }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
createMethods(visibleDeclarations, isTopLevel = false, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.none { it.isConstructor }) {
|
||||||
|
classOrObjectSymbol.primaryConstructor?.let {
|
||||||
|
result.add(
|
||||||
|
FirLightConstructorForSymbol(
|
||||||
|
constructorSymbol = it,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
containingClass = this,
|
||||||
|
methodIndex = METHOD_INDEX_FOR_DEFAULT_CTOR
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _ownFields: List<KtLightField> by lazyPub {
|
||||||
|
|
||||||
|
val result = mutableListOf<KtLightField>()
|
||||||
|
|
||||||
|
result.addCompanionObjectFieldIfNeeded()
|
||||||
|
|
||||||
|
classOrObjectSymbol.companionObject?.run {
|
||||||
|
analyzeWithSymbolAsContext(this) {
|
||||||
|
getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
.filterIsInstance<KtPropertySymbol>()
|
||||||
|
.filter { it.hasJvmFieldAnnotation() || it.isConst }
|
||||||
|
.mapTo(result) {
|
||||||
|
FirLightFieldForPropertySymbol(
|
||||||
|
propertySymbol = it,
|
||||||
|
containingClass = this@FirLightClassForSymbol,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
isTopLevel = false,
|
||||||
|
forceStatic = true
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val isNamedObject = classOrObjectSymbol.classKind == KtClassKind.OBJECT
|
||||||
|
if (isNamedObject && classOrObjectSymbol.symbolKind != KtSymbolKind.LOCAL) {
|
||||||
|
result.add(FirLightFieldForObjectSymbol(classOrObjectSymbol, this@FirLightClassForSymbol, null))
|
||||||
|
}
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||||
|
val propertySymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
.filterIsInstance<KtPropertySymbol>()
|
||||||
|
.applyIf(classOrObjectSymbol.classKind == KtClassKind.COMPANION_OBJECT) {
|
||||||
|
filter { it.hasJvmFieldAnnotation() || it.isConst }
|
||||||
|
}
|
||||||
|
createFields(propertySymbols, isTopLevel = false, result)
|
||||||
|
|
||||||
|
if (isEnum) {
|
||||||
|
classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
.filterIsInstance<KtEnumEntrySymbol>()
|
||||||
|
.mapTo(result) { FirLightFieldForEnumEntry(it, this@FirLightClassForSymbol, null) }
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode(): Int = classOrObjectSymbol.hashCode()
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
this === other || (other is FirLightClassForSymbol && classOrObjectSymbol == other.classOrObjectSymbol)
|
||||||
|
|
||||||
|
override fun isInterface(): Boolean = false
|
||||||
|
|
||||||
|
override fun isAnnotationType(): Boolean = false
|
||||||
|
|
||||||
|
override fun isEnum(): Boolean =
|
||||||
|
classOrObjectSymbol.classKind == KtClassKind.ENUM_CLASS
|
||||||
|
|
||||||
|
override fun copy(): FirLightClassForSymbol =
|
||||||
|
FirLightClassForSymbol(classOrObjectSymbol, manager)
|
||||||
|
}
|
||||||
+69
@@ -0,0 +1,69 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava.classes
|
||||||
|
|
||||||
|
import com.intellij.psi.PsiManager
|
||||||
|
import com.intellij.psi.PsiMethod
|
||||||
|
import com.intellij.psi.PsiReferenceList
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassForClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassKind
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
|
||||||
|
|
||||||
|
internal class FirLightInterfaceClassSymbol(
|
||||||
|
private val classOrObjectSymbol: KtClassOrObjectSymbol,
|
||||||
|
manager: PsiManager
|
||||||
|
) : FirLightInterfaceOrAnnotationClassSymbol(classOrObjectSymbol, manager) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
require(classOrObjectSymbol.classKind == KtClassKind.INTERFACE)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _ownFields: List<KtLightField> by lazyPub {
|
||||||
|
mutableListOf<KtLightField>().also {
|
||||||
|
it.addCompanionObjectFieldIfNeeded()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOwnFields(): List<KtLightField> = _ownFields
|
||||||
|
|
||||||
|
private val _ownMethods: List<KtLightMethod> by lazyPub {
|
||||||
|
|
||||||
|
val result = mutableListOf<KtLightMethod>()
|
||||||
|
|
||||||
|
analyzeWithSymbolAsContext(classOrObjectSymbol) {
|
||||||
|
val visibleDeclarations = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
|
||||||
|
.filterNot { it is KtFunctionSymbol && it.visibility == KtSymbolVisibility.PRIVATE }
|
||||||
|
|
||||||
|
createMethods(visibleDeclarations, isTopLevel = false, result)
|
||||||
|
}
|
||||||
|
|
||||||
|
result
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getOwnMethods(): List<PsiMethod> = _ownMethods
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
other === this || (other is FirLightInterfaceClassSymbol && classOrObjectSymbol == other.classOrObjectSymbol)
|
||||||
|
|
||||||
|
override fun hashCode(): Int = classOrObjectSymbol.hashCode()
|
||||||
|
|
||||||
|
override fun isAnnotationType(): Boolean = false
|
||||||
|
|
||||||
|
override fun copy(): FirLightClassForClassOrObjectSymbol =
|
||||||
|
FirLightInterfaceClassSymbol(classOrObjectSymbol, manager)
|
||||||
|
|
||||||
|
private val _extendsList: PsiReferenceList by lazyPub {
|
||||||
|
createInheritanceList(forExtendsList = false)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getExtendsList(): PsiReferenceList? = _extendsList
|
||||||
|
}
|
||||||
+48
@@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava.classes
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.*
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassKind
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolKind
|
||||||
|
|
||||||
|
internal abstract class FirLightInterfaceOrAnnotationClassSymbol(
|
||||||
|
private val classOrObjectSymbol: KtClassOrObjectSymbol,
|
||||||
|
manager: PsiManager
|
||||||
|
) : FirLightClassForClassOrObjectSymbol(classOrObjectSymbol, manager) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
require(classOrObjectSymbol.classKind == KtClassKind.INTERFACE || classOrObjectSymbol.classKind == KtClassKind.ANNOTATION_CLASS)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val _modifierList: PsiModifierList? by lazyPub {
|
||||||
|
|
||||||
|
val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL
|
||||||
|
|
||||||
|
val modifiers = mutableSetOf(classOrObjectSymbol.computeVisibility(isTopLevel), PsiModifier.ABSTRACT)
|
||||||
|
|
||||||
|
val annotations = classOrObjectSymbol.computeAnnotations(
|
||||||
|
parent = this@FirLightInterfaceOrAnnotationClassSymbol,
|
||||||
|
nullability = NullabilityType.Unknown,
|
||||||
|
annotationUseSiteTarget = null,
|
||||||
|
)
|
||||||
|
|
||||||
|
FirLightClassModifierList(this@FirLightInterfaceOrAnnotationClassSymbol, modifiers, annotations)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||||
|
|
||||||
|
override fun getImplementsList(): PsiReferenceList? = null
|
||||||
|
|
||||||
|
override fun getOwnInnerClasses(): List<PsiClass> = emptyList()
|
||||||
|
|
||||||
|
override fun isInterface(): Boolean = true
|
||||||
|
|
||||||
|
override fun isEnum(): Boolean = false
|
||||||
|
}
|
||||||
+214
@@ -0,0 +1,214 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava.classes
|
||||||
|
|
||||||
|
import com.intellij.psi.util.CachedValueProvider
|
||||||
|
import com.intellij.psi.util.CachedValuesManager
|
||||||
|
import org.jetbrains.kotlin.analyzer.KotlinModificationTrackerService
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_BASE
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.safeIsLocal
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.shouldNotBeVisibleAsLightClass
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightField
|
||||||
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.*
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassForSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.fields.FirLightFieldForEnumEntry
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.analyze
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtCommonSymbolModality
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibility
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
|
import org.jetbrains.kotlin.psi.*
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||||
|
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
|
fun getOrCreateFirLightClass(classOrObject: KtClassOrObject): KtLightClass? =
|
||||||
|
CachedValuesManager.getCachedValue(classOrObject) {
|
||||||
|
CachedValueProvider.Result
|
||||||
|
.create(
|
||||||
|
createFirLightClassNoCache(classOrObject),
|
||||||
|
KotlinModificationTrackerService.getInstance(classOrObject.project).outOfBlockModificationTracker
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun createFirLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? {
|
||||||
|
|
||||||
|
val containingFile = classOrObject.containingFile
|
||||||
|
if (containingFile is KtCodeFragment) {
|
||||||
|
// Avoid building light classes for code fragments
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containingFile is KtFile && containingFile.isCompiled) return null
|
||||||
|
|
||||||
|
if (classOrObject.shouldNotBeVisibleAsLightClass()) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
return when {
|
||||||
|
classOrObject is KtEnumEntry -> lightClassForEnumEntry(classOrObject)
|
||||||
|
classOrObject.isObjectLiteral() -> return null //TODO
|
||||||
|
classOrObject.safeIsLocal() -> return null //TODO
|
||||||
|
classOrObject.hasModifier(KtTokens.INLINE_KEYWORD) -> return null //TODO
|
||||||
|
else -> {
|
||||||
|
analyze(classOrObject) {
|
||||||
|
val symbol = classOrObject.getClassOrObjectSymbol()
|
||||||
|
when (symbol.classKind) {
|
||||||
|
KtClassKind.INTERFACE -> FirLightInterfaceClassSymbol(symbol, classOrObject.manager)
|
||||||
|
KtClassKind.ANNOTATION_CLASS -> FirLightAnnotationClassSymbol(symbol, classOrObject.manager)
|
||||||
|
else -> FirLightClassForSymbol(symbol, classOrObject.manager)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private fun lightClassForEnumEntry(ktEnumEntry: KtEnumEntry): KtLightClass? {
|
||||||
|
if (ktEnumEntry.body == null) return null
|
||||||
|
|
||||||
|
val firClass = ktEnumEntry
|
||||||
|
.containingClass()
|
||||||
|
?.let { getOrCreateFirLightClass(it) } as? FirLightClassForSymbol
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
val targetField = firClass.ownFields
|
||||||
|
.firstOrNull { it is FirLightFieldForEnumEntry && it.kotlinOrigin == ktEnumEntry }
|
||||||
|
?: return null
|
||||||
|
|
||||||
|
return (targetField as? FirLightFieldForEnumEntry)?.initializingClass as? KtLightClass
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun FirLightClassBase.createMethods(
|
||||||
|
declarations: Sequence<KtCallableSymbol>,
|
||||||
|
isTopLevel: Boolean,
|
||||||
|
result: MutableList<KtLightMethod>
|
||||||
|
) {
|
||||||
|
var methodIndex = METHOD_INDEX_BASE
|
||||||
|
for (declaration in declarations) {
|
||||||
|
|
||||||
|
if (declaration is KtFunctionSymbol && declaration.isInline) continue
|
||||||
|
|
||||||
|
if (declaration is KtAnnotatedSymbol && declaration.hasJvmSyntheticAnnotation(annotationUseSiteTarget = null)) continue
|
||||||
|
|
||||||
|
if (declaration is KtAnnotatedSymbol && declaration.isHiddenByDeprecation(annotationUseSiteTarget = null)) continue
|
||||||
|
|
||||||
|
when (declaration) {
|
||||||
|
is KtFunctionSymbol -> {
|
||||||
|
result.add(
|
||||||
|
FirLightSimpleMethodForSymbol(
|
||||||
|
functionSymbol = declaration,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
containingClass = this@createMethods,
|
||||||
|
isTopLevel = isTopLevel,
|
||||||
|
methodIndex = methodIndex++
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (declaration.hasJvmOverloadsAnnotation()) {
|
||||||
|
val skipMask = BitSet(declaration.valueParameters.size)
|
||||||
|
|
||||||
|
for (i in declaration.valueParameters.size - 1 downTo 0) {
|
||||||
|
|
||||||
|
if (!declaration.valueParameters[i].hasDefaultValue) continue
|
||||||
|
|
||||||
|
skipMask.set(i)
|
||||||
|
|
||||||
|
result.add(
|
||||||
|
FirLightSimpleMethodForSymbol(
|
||||||
|
functionSymbol = declaration,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
containingClass = this@createMethods,
|
||||||
|
isTopLevel = isTopLevel,
|
||||||
|
methodIndex = methodIndex++,
|
||||||
|
argumentsSkipMask = skipMask
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is KtConstructorSymbol -> {
|
||||||
|
result.add(
|
||||||
|
FirLightConstructorForSymbol(
|
||||||
|
constructorSymbol = declaration,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
containingClass = this@createMethods,
|
||||||
|
methodIndex++
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
is KtPropertySymbol -> {
|
||||||
|
|
||||||
|
if (declaration.hasJvmFieldAnnotation()) continue
|
||||||
|
|
||||||
|
val getter = declaration.getter?.takeIf {
|
||||||
|
!declaration.hasJvmSyntheticAnnotation(AnnotationUseSiteTarget.PROPERTY_GETTER) &&
|
||||||
|
!it.isInline &&
|
||||||
|
!declaration.isHiddenByDeprecation(AnnotationUseSiteTarget.PROPERTY_GETTER)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getter != null) {
|
||||||
|
result.add(
|
||||||
|
FirLightAccessorMethodForSymbol(
|
||||||
|
propertyAccessorSymbol = getter,
|
||||||
|
containingPropertySymbol = declaration,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
containingClass = this@createMethods,
|
||||||
|
isTopLevel = isTopLevel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
val setter = declaration.setter?.takeIf {
|
||||||
|
!isAnnotationType &&
|
||||||
|
!declaration.hasJvmSyntheticAnnotation(AnnotationUseSiteTarget.PROPERTY_SETTER) &&
|
||||||
|
!it.isInline &&
|
||||||
|
!declaration.isHiddenByDeprecation(AnnotationUseSiteTarget.PROPERTY_GETTER)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (setter != null) {
|
||||||
|
result.add(
|
||||||
|
FirLightAccessorMethodForSymbol(
|
||||||
|
propertyAccessorSymbol = setter,
|
||||||
|
containingPropertySymbol = declaration,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
containingClass = this@createMethods,
|
||||||
|
isTopLevel = isTopLevel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun FirLightClassBase.createFields(
|
||||||
|
declarations: Sequence<KtCallableSymbol>,
|
||||||
|
isTopLevel: Boolean,
|
||||||
|
result: MutableList<KtLightField>
|
||||||
|
) {
|
||||||
|
//TODO isHiddenByDeprecation
|
||||||
|
for (declaration in declarations) {
|
||||||
|
if (declaration !is KtPropertySymbol) continue
|
||||||
|
|
||||||
|
if (!declaration.hasBackingField) continue
|
||||||
|
if (declaration.hasJvmSyntheticAnnotation(AnnotationUseSiteTarget.FIELD)) continue
|
||||||
|
if (declaration.modality == KtCommonSymbolModality.ABSTRACT) continue
|
||||||
|
|
||||||
|
result.add(
|
||||||
|
FirLightFieldForPropertySymbol(
|
||||||
|
propertySymbol = declaration,
|
||||||
|
containingClass = this@createFields,
|
||||||
|
lightMemberOrigin = null,
|
||||||
|
isTopLevel = isTopLevel
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
-3
@@ -5,10 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.asJava
|
package org.jetbrains.kotlin.idea.asJava
|
||||||
|
|
||||||
import com.intellij.openapi.util.TextRange
|
|
||||||
import com.intellij.psi.*
|
import com.intellij.psi.*
|
||||||
import com.intellij.psi.scope.PsiScopeProcessor
|
|
||||||
import com.intellij.util.IncorrectOperationException
|
|
||||||
|
|
||||||
internal class FirLightPsiJavaCodeReferenceElementWithReference(private val ktElement: PsiElement, reference: PsiReference):
|
internal class FirLightPsiJavaCodeReferenceElementWithReference(private val ktElement: PsiElement, reference: PsiReference):
|
||||||
FirLightPsiJavaCodeReferenceElementBase(ktElement),
|
FirLightPsiJavaCodeReferenceElementBase(ktElement),
|
||||||
|
|||||||
+79
@@ -0,0 +1,79 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.asJava.fields
|
||||||
|
|
||||||
|
import com.intellij.psi.*
|
||||||
|
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
||||||
|
import org.jetbrains.kotlin.asJava.classes.*
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassForSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightClassModifierList
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.FirLightField
|
||||||
|
import org.jetbrains.kotlin.idea.asJava.asPsiType
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
|
||||||
|
import org.jetbrains.kotlin.idea.util.ifTrue
|
||||||
|
import org.jetbrains.kotlin.psi.KtEnumEntry
|
||||||
|
|
||||||
|
internal class FirLightFieldForEnumEntry(
|
||||||
|
private val enumEntrySymbol: KtEnumEntrySymbol,
|
||||||
|
containingClass: FirLightClassForSymbol,
|
||||||
|
override val lightMemberOrigin: LightMemberOrigin?
|
||||||
|
) : FirLightField(containingClass, lightMemberOrigin), PsiEnumConstant {
|
||||||
|
|
||||||
|
private val _modifierList by lazyPub {
|
||||||
|
FirLightClassModifierList(
|
||||||
|
containingDeclaration = this@FirLightFieldForEnumEntry,
|
||||||
|
modifiers = setOf(PsiModifier.STATIC, PsiModifier.FINAL, PsiModifier.PUBLIC),
|
||||||
|
annotations = emptyList()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getModifierList(): PsiModifierList? = _modifierList
|
||||||
|
|
||||||
|
override val kotlinOrigin: KtEnumEntry? = enumEntrySymbol.psi as? KtEnumEntry
|
||||||
|
|
||||||
|
//TODO Make with KtSymbols
|
||||||
|
private val hasBody: Boolean get() = kotlinOrigin?.let { it.body != null } ?: true
|
||||||
|
|
||||||
|
private val _initializingClass: PsiEnumConstantInitializer? by lazyPub {
|
||||||
|
hasBody.ifTrue {
|
||||||
|
FirLightClassForEnumEntry(
|
||||||
|
enumEntrySymbol = enumEntrySymbol,
|
||||||
|
enumConstant = this@FirLightFieldForEnumEntry,
|
||||||
|
enumClass = containingClass,
|
||||||
|
manager = manager
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getInitializingClass(): PsiEnumConstantInitializer? = _initializingClass
|
||||||
|
override fun getOrCreateInitializingClass(): PsiEnumConstantInitializer =
|
||||||
|
_initializingClass ?: cannotModify()
|
||||||
|
|
||||||
|
override fun getArgumentList(): PsiExpressionList? = null
|
||||||
|
override fun resolveMethod(): PsiMethod? = null
|
||||||
|
override fun resolveConstructor(): PsiMethod? = null
|
||||||
|
|
||||||
|
override fun resolveMethodGenerics(): JavaResolveResult = JavaResolveResult.EMPTY
|
||||||
|
|
||||||
|
override fun hasInitializer() = true
|
||||||
|
override fun computeConstantValue(visitedVars: MutableSet<PsiVariable>?) = this
|
||||||
|
|
||||||
|
override fun getName(): String = enumEntrySymbol.name.asString()
|
||||||
|
|
||||||
|
private val _type: PsiType by lazyPub {
|
||||||
|
enumEntrySymbol.type.asPsiType(enumEntrySymbol, this@FirLightFieldForEnumEntry, FirResolvePhase.TYPES)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getType(): PsiType = _type
|
||||||
|
override fun getInitializer(): PsiExpression? = null
|
||||||
|
|
||||||
|
override fun hashCode(): Int = enumEntrySymbol.hashCode()
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean =
|
||||||
|
other is FirLightFieldForEnumEntry &&
|
||||||
|
enumEntrySymbol == other.enumEntrySymbol
|
||||||
|
}
|
||||||
+8
-5
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
|||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertyGetterSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
|
|
||||||
@@ -42,15 +41,19 @@ internal class FirLightFieldForPropertySymbol(
|
|||||||
|
|
||||||
private val _modifierList: PsiModifierList by lazyPub {
|
private val _modifierList: PsiModifierList by lazyPub {
|
||||||
|
|
||||||
val modifiersFromSymbol = propertySymbol.computeModalityForMethod(isTopLevel = isTopLevel, isOverride = false)
|
val isJvmField = propertySymbol.hasJvmFieldAnnotation()
|
||||||
|
val suppressFinal = !isJvmField && !propertySymbol.isVal
|
||||||
|
|
||||||
|
val modifiersFromSymbol = propertySymbol.computeModalityForMethod(
|
||||||
|
isTopLevel = isTopLevel,
|
||||||
|
suppressFinal = suppressFinal
|
||||||
|
)
|
||||||
|
|
||||||
val basicModifiers = modifiersFromSymbol.add(
|
val basicModifiers = modifiersFromSymbol.add(
|
||||||
what = PsiModifier.STATIC,
|
what = PsiModifier.STATIC,
|
||||||
`if` = forceStatic
|
`if` = forceStatic
|
||||||
)
|
)
|
||||||
|
|
||||||
val isJvmField = propertySymbol.hasJvmFieldAnnotation()
|
|
||||||
|
|
||||||
val visibility =
|
val visibility =
|
||||||
if (isJvmField) propertySymbol.computeVisibility(isTopLevel = false) else PsiModifier.PRIVATE
|
if (isJvmField) propertySymbol.computeVisibility(isTopLevel = false) else PsiModifier.PRIVATE
|
||||||
|
|
||||||
@@ -58,7 +61,7 @@ internal class FirLightFieldForPropertySymbol(
|
|||||||
|
|
||||||
val modifiers = modifiersWithVisibility.add(
|
val modifiers = modifiersWithVisibility.add(
|
||||||
what = PsiModifier.FINAL,
|
what = PsiModifier.FINAL,
|
||||||
`if` = !isJvmField || propertySymbol.isVal
|
`if` = !suppressFinal
|
||||||
)
|
)
|
||||||
|
|
||||||
val annotations = propertySymbol.computeAnnotations(
|
val annotations = propertySymbol.computeAnnotations(
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.fir.backend.jvm.jvmTypeMapper
|
|||||||
import org.jetbrains.kotlin.fir.declarations.*
|
import org.jetbrains.kotlin.fir.declarations.*
|
||||||
import org.jetbrains.kotlin.fir.isPrimitiveNumberOrUnsignedNumberType
|
import org.jetbrains.kotlin.fir.isPrimitiveNumberOrUnsignedNumberType
|
||||||
import org.jetbrains.kotlin.fir.isPrimitiveType
|
import org.jetbrains.kotlin.fir.isPrimitiveType
|
||||||
|
import org.jetbrains.kotlin.fir.resolve.toSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
|
||||||
import org.jetbrains.kotlin.fir.typeCheckerContext
|
import org.jetbrains.kotlin.fir.typeCheckerContext
|
||||||
import org.jetbrains.kotlin.fir.types.*
|
import org.jetbrains.kotlin.fir.types.*
|
||||||
@@ -31,10 +32,7 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymb
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirClassType
|
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirClassType
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
|
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassLikeSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.types.*
|
import org.jetbrains.kotlin.idea.frontend.api.types.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
import org.jetbrains.kotlin.load.kotlin.TypeMappingMode
|
||||||
@@ -89,6 +87,7 @@ private fun ConeKotlinType.asPsiType(
|
|||||||
if (this.typeArguments.any { it is ConeClassErrorType }) return psiContext.nonExistentType()
|
if (this.typeArguments.any { it is ConeClassErrorType }) return psiContext.nonExistentType()
|
||||||
if (this is ConeClassLikeType) {
|
if (this is ConeClassLikeType) {
|
||||||
val classId = classId
|
val classId = classId
|
||||||
|
//TODO make anonymous type deriving
|
||||||
if (classId != null && classId.shortClassName.asString() == SpecialNames.ANONYMOUS) return PsiType.NULL
|
if (classId != null && classId.shortClassName.asString() == SpecialNames.ANONYMOUS) return PsiType.NULL
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -98,8 +97,10 @@ private fun ConeKotlinType.asPsiType(
|
|||||||
|
|
||||||
val canonicalSignature = signatureWriter.toString()
|
val canonicalSignature = signatureWriter.toString()
|
||||||
|
|
||||||
if (canonicalSignature == "[L<error>;") return psiContext.nonExistentType()
|
if (canonicalSignature.contains("L<error>")) return psiContext.nonExistentType()
|
||||||
val signature = StringCharacterIterator(canonicalSignature)
|
//TODO Fix it in typemapper
|
||||||
|
val patchedCanonicalSignature = canonicalSignature.replace(SpecialNames.ANONYMOUS, "java.lang.Object")
|
||||||
|
val signature = StringCharacterIterator(patchedCanonicalSignature)
|
||||||
val javaType = SignatureParsing.parseTypeString(signature, StubBuildingVisitor.GUESSING_MAPPER)
|
val javaType = SignatureParsing.parseTypeString(signature, StubBuildingVisitor.GUESSING_MAPPER)
|
||||||
val typeInfo = TypeInfo.fromString(javaType, false)
|
val typeInfo = TypeInfo.fromString(javaType, false)
|
||||||
val typeText = TypeInfo.createTypeText(typeInfo) ?: return psiContext.nonExistentType()
|
val typeText = TypeInfo.createTypeText(typeInfo) ?: return psiContext.nonExistentType()
|
||||||
@@ -178,13 +179,16 @@ internal fun FirMemberDeclaration.computeModalityForMethod(isTopLevel: Boolean):
|
|||||||
return withTopLevelStatic
|
return withTopLevelStatic
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtSymbolWithModality<KtCommonSymbolModality>.computeModalityForMethod(isTopLevel: Boolean, isOverride: Boolean): Set<String> {
|
internal fun KtSymbolWithModality<KtCommonSymbolModality>.computeModalityForMethod(
|
||||||
|
isTopLevel: Boolean,
|
||||||
|
suppressFinal: Boolean
|
||||||
|
): Set<String> {
|
||||||
require(this !is KtClassLikeSymbol)
|
require(this !is KtClassLikeSymbol)
|
||||||
|
|
||||||
val modality = mutableSetOf<String>()
|
val modality = mutableSetOf<String>()
|
||||||
|
|
||||||
computeSimpleModality()?.run {
|
computeSimpleModality()?.run {
|
||||||
if (this != PsiModifier.FINAL || !isOverride) {
|
if (this != PsiModifier.FINAL || !suppressFinal) {
|
||||||
modality.add(this)
|
modality.add(this)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -209,14 +213,15 @@ internal fun FirMemberDeclaration.computeVisibility(isTopLevel: Boolean): String
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun KtSymbolWithVisibility.computeVisibility(isTopLevel: Boolean): String {
|
internal fun KtSymbolWithVisibility.computeVisibility(isTopLevel: Boolean): String =
|
||||||
return when (this.visibility) {
|
visibility.toPsiVisibility(isTopLevel)
|
||||||
// Top-level private class has PACKAGE_LOCAL visibility in Java
|
|
||||||
// Nested private class has PRIVATE visibility
|
internal fun KtSymbolVisibility.toPsiVisibility(isTopLevel: Boolean): String = when (this) {
|
||||||
KtSymbolVisibility.PRIVATE -> if (isTopLevel) PsiModifier.PACKAGE_LOCAL else PsiModifier.PRIVATE
|
// Top-level private class has PACKAGE_LOCAL visibility in Java
|
||||||
KtSymbolVisibility.PROTECTED -> PsiModifier.PROTECTED
|
// Nested private class has PRIVATE visibility
|
||||||
else -> PsiModifier.PUBLIC
|
KtSymbolVisibility.PRIVATE -> if (isTopLevel) PsiModifier.PACKAGE_LOCAL else PsiModifier.PRIVATE
|
||||||
}
|
KtSymbolVisibility.PROTECTED -> PsiModifier.PROTECTED
|
||||||
|
else -> PsiModifier.PUBLIC
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun basicIsEquivalentTo(`this`: PsiElement?, that: PsiElement?): Boolean {
|
internal fun basicIsEquivalentTo(`this`: PsiElement?, that: PsiElement?): Boolean {
|
||||||
|
|||||||
+36
-17
@@ -11,12 +11,17 @@ import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
|
|||||||
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_GETTER
|
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_GETTER
|
||||||
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_SETTER
|
import org.jetbrains.kotlin.asJava.classes.METHOD_INDEX_FOR_SETTER
|
||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
|
import org.jetbrains.kotlin.builtins.StandardNames
|
||||||
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertyAccessorSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.analyzeWithSymbolAsContext
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertyGetterSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirPropertyGetterSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySetterSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.*
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.*
|
||||||
|
import org.jetbrains.kotlin.idea.util.ifTrue
|
||||||
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi.getterName
|
import org.jetbrains.kotlin.load.java.JvmAbi.getterName
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi.setterName
|
import org.jetbrains.kotlin.load.java.JvmAbi.setterName
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
@@ -26,7 +31,7 @@ internal class FirLightAccessorMethodForSymbol(
|
|||||||
containingPropertySymbol: KtPropertySymbol,
|
containingPropertySymbol: KtPropertySymbol,
|
||||||
lightMemberOrigin: LightMemberOrigin?,
|
lightMemberOrigin: LightMemberOrigin?,
|
||||||
containingClass: FirLightClassBase,
|
containingClass: FirLightClassBase,
|
||||||
isTopLevel: Boolean
|
isTopLevel: Boolean,
|
||||||
) : FirLightMethod(
|
) : FirLightMethod(
|
||||||
lightMemberOrigin,
|
lightMemberOrigin,
|
||||||
containingClass,
|
containingClass,
|
||||||
@@ -36,10 +41,11 @@ internal class FirLightAccessorMethodForSymbol(
|
|||||||
if (firPropertyAccessor is KtPropertyGetterSymbol) getterName(this)
|
if (firPropertyAccessor is KtPropertyGetterSymbol) getterName(this)
|
||||||
else setterName(this)
|
else setterName(this)
|
||||||
|
|
||||||
//TODO add JvmName
|
|
||||||
private val _name: String by lazyPub {
|
private val _name: String by lazyPub {
|
||||||
containingPropertySymbol.name.identifier
|
val defaultName = containingPropertySymbol.name.identifier.let {
|
||||||
.abiName(propertyAccessorSymbol)
|
if (containingClass.isAnnotationType) it else it.abiName(propertyAccessorSymbol)
|
||||||
|
}
|
||||||
|
containingPropertySymbol.computeJvmMethodName(defaultName, accessorSite)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String = _name
|
override fun getName(): String = _name
|
||||||
@@ -49,10 +55,12 @@ internal class FirLightAccessorMethodForSymbol(
|
|||||||
override val kotlinOrigin: KtDeclaration? =
|
override val kotlinOrigin: KtDeclaration? =
|
||||||
(propertyAccessorSymbol.psi ?: containingPropertySymbol.psi) as? KtDeclaration
|
(propertyAccessorSymbol.psi ?: containingPropertySymbol.psi) as? KtDeclaration
|
||||||
|
|
||||||
private val _annotations: List<PsiAnnotation> by lazyPub {
|
private val accessorSite
|
||||||
val accessorSite =
|
get() =
|
||||||
if (propertyAccessorSymbol is KtPropertyGetterSymbol) AnnotationUseSiteTarget.PROPERTY_GETTER
|
if (propertyAccessorSymbol is KtPropertyGetterSymbol) AnnotationUseSiteTarget.PROPERTY_GETTER
|
||||||
else AnnotationUseSiteTarget.PROPERTY_SETTER
|
else AnnotationUseSiteTarget.PROPERTY_SETTER
|
||||||
|
|
||||||
|
private val _annotations: List<PsiAnnotation> by lazyPub {
|
||||||
containingPropertySymbol.computeAnnotations(
|
containingPropertySymbol.computeAnnotations(
|
||||||
parent = this,
|
parent = this,
|
||||||
nullability = NullabilityType.Unknown,
|
nullability = NullabilityType.Unknown,
|
||||||
@@ -61,17 +69,28 @@ internal class FirLightAccessorMethodForSymbol(
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val _modifiers: Set<String> by lazyPub {
|
private val _modifiers: Set<String> by lazyPub {
|
||||||
|
val isOverrideMethod = propertyAccessorSymbol.isOverride || containingPropertySymbol.isOverride
|
||||||
|
val isInterfaceMethod = containingClass.isInterface
|
||||||
|
|
||||||
val isOverride = propertyAccessorSymbol.isOverride || containingPropertySymbol.isOverride
|
val visibility = isOverrideMethod.ifTrue {
|
||||||
val modifiers = propertyAccessorSymbol.computeModalityForMethod(isTopLevel, isOverride) +
|
(containingClass as? FirLightClassForSymbol)
|
||||||
propertyAccessorSymbol.computeVisibility(isTopLevel)
|
?.tryGetEffectiveVisibility(containingPropertySymbol)
|
||||||
|
?.toPsiVisibility(isTopLevel)
|
||||||
|
} ?: propertyAccessorSymbol.computeVisibility(isTopLevel)
|
||||||
|
|
||||||
val isJvmStatic =
|
val modifiers = containingPropertySymbol.computeModalityForMethod(
|
||||||
_annotations.any { it.qualifiedName == "kotlin.jvm.JvmStatic" }
|
isTopLevel = isTopLevel,
|
||||||
|
suppressFinal = isOverrideMethod || isInterfaceMethod
|
||||||
if (isJvmStatic) return@lazyPub modifiers + PsiModifier.STATIC
|
) + visibility
|
||||||
|
|
||||||
modifiers
|
modifiers
|
||||||
|
.add(
|
||||||
|
what = PsiModifier.STATIC,
|
||||||
|
`if` = _annotations.any { it.qualifiedName == "kotlin.jvm.JvmStatic" }
|
||||||
|
).add(
|
||||||
|
what = PsiModifier.ABSTRACT,
|
||||||
|
`if` = isInterfaceMethod
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _modifierList: PsiModifierList by lazyPub {
|
private val _modifierList: PsiModifierList by lazyPub {
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ import org.jetbrains.kotlin.asJava.classes.KotlinLightReferenceListBuilder
|
|||||||
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
import org.jetbrains.kotlin.asJava.classes.KtLightClass
|
||||||
import org.jetbrains.kotlin.asJava.classes.cannotModify
|
import org.jetbrains.kotlin.asJava.classes.cannotModify
|
||||||
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
import org.jetbrains.kotlin.asJava.elements.KtLightMethod
|
||||||
|
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
|
||||||
|
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtAnnotatedSymbol
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolVisibility
|
||||||
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibility
|
||||||
|
import org.jetbrains.kotlin.idea.util.module
|
||||||
|
|
||||||
internal abstract class FirLightMethod(
|
internal abstract class FirLightMethod(
|
||||||
lightMemberOrigin: LightMemberOrigin?,
|
lightMemberOrigin: LightMemberOrigin?,
|
||||||
@@ -74,4 +80,19 @@ internal abstract class FirLightMethod(
|
|||||||
KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) //TODO()
|
KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) //TODO()
|
||||||
|
|
||||||
override fun getDefaultValue(): PsiAnnotationMemberValue? = null //TODO()
|
override fun getDefaultValue(): PsiAnnotationMemberValue? = null //TODO()
|
||||||
|
|
||||||
|
protected fun <T> T.computeJvmMethodName(
|
||||||
|
defaultName: String,
|
||||||
|
annotationUseSiteTarget: AnnotationUseSiteTarget? = null
|
||||||
|
): String where T : KtAnnotatedSymbol, T : KtSymbolWithVisibility {
|
||||||
|
getJvmNameFromAnnotation(annotationUseSiteTarget)?.let { return it }
|
||||||
|
|
||||||
|
if (visibility != KtSymbolVisibility.INTERNAL) return defaultName
|
||||||
|
|
||||||
|
val moduleName = module?.name ?: return defaultName
|
||||||
|
|
||||||
|
if (hasPublishedApiAnnotation(annotationUseSiteTarget)) return defaultName
|
||||||
|
|
||||||
|
return KotlinTypeMapper.InternalNameMapper.mangleInternalName(defaultName, moduleName)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
+1
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.asJava.classes.KotlinLightReferenceListBuilder
|
|||||||
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
import org.jetbrains.kotlin.asJava.classes.lazyPub
|
||||||
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
|
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
|
|||||||
+27
-10
@@ -14,6 +14,8 @@ import org.jetbrains.kotlin.asJava.classes.lazyPub
|
|||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.types.isUnit
|
import org.jetbrains.kotlin.idea.frontend.api.types.isUnit
|
||||||
|
import org.jetbrains.kotlin.idea.util.ifTrue
|
||||||
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
internal class FirLightSimpleMethodForSymbol(
|
internal class FirLightSimpleMethodForSymbol(
|
||||||
@@ -32,7 +34,7 @@ internal class FirLightSimpleMethodForSymbol(
|
|||||||
) {
|
) {
|
||||||
|
|
||||||
private val _name: String by lazyPub {
|
private val _name: String by lazyPub {
|
||||||
functionSymbol.getJvmNameFromAnnotation(null) ?: functionSymbol.name.asString()
|
functionSymbol.computeJvmMethodName(functionSymbol.name.asString())
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getName(): String = _name
|
override fun getName(): String = _name
|
||||||
@@ -51,16 +53,34 @@ internal class FirLightSimpleMethodForSymbol(
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
open class X {
|
||||||
|
open val x: Int = 2
|
||||||
|
open fun u() = 2
|
||||||
|
}
|
||||||
|
|
||||||
private val _modifiers: Set<String> by lazyPub {
|
private val _modifiers: Set<String> by lazyPub {
|
||||||
|
|
||||||
if (functionSymbol.hasInlineOnlyAnnotation()) return@lazyPub setOf(PsiModifier.FINAL, PsiModifier.PRIVATE)
|
if (functionSymbol.hasInlineOnlyAnnotation()) return@lazyPub setOf(PsiModifier.FINAL, PsiModifier.PRIVATE)
|
||||||
|
|
||||||
val modifiers = functionSymbol.computeModalityForMethod(isTopLevel = isTopLevel, functionSymbol.isOverride) +
|
val isOverrideMethod = functionSymbol.isOverride
|
||||||
functionSymbol.computeVisibility(isTopLevel = isTopLevel)
|
|
||||||
|
|
||||||
if (functionSymbol.hasJvmStaticAnnotation()) return@lazyPub modifiers + PsiModifier.STATIC
|
val visibility = isOverrideMethod.ifTrue {
|
||||||
|
(containingClass as? FirLightClassForSymbol)
|
||||||
|
?.tryGetEffectiveVisibility(functionSymbol)
|
||||||
|
?.toPsiVisibility(isTopLevel)
|
||||||
|
} ?: functionSymbol.computeVisibility(isTopLevel = isTopLevel)
|
||||||
|
|
||||||
modifiers
|
val finalModifier = kotlinOrigin?.hasModifier(KtTokens.FINAL_KEYWORD) == true
|
||||||
|
|
||||||
|
val modifiers = functionSymbol.computeModalityForMethod(
|
||||||
|
isTopLevel = isTopLevel,
|
||||||
|
suppressFinal = !finalModifier && isOverrideMethod
|
||||||
|
) + visibility
|
||||||
|
|
||||||
|
modifiers.add(
|
||||||
|
what = PsiModifier.STATIC,
|
||||||
|
`if` = functionSymbol.hasJvmStaticAnnotation()
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val _modifierList: PsiModifierList by lazyPub {
|
private val _modifierList: PsiModifierList by lazyPub {
|
||||||
@@ -79,10 +99,7 @@ internal class FirLightSimpleMethodForSymbol(
|
|||||||
override fun getReturnType(): PsiType = _returnedType
|
override fun getReturnType(): PsiType = _returnedType
|
||||||
|
|
||||||
override fun equals(other: Any?): Boolean =
|
override fun equals(other: Any?): Boolean =
|
||||||
this === other ||
|
this === other || (other is FirLightSimpleMethodForSymbol && functionSymbol == other.functionSymbol)
|
||||||
(other is FirLightSimpleMethodForSymbol &&
|
|
||||||
kotlinOrigin == other.kotlinOrigin &&
|
|
||||||
functionSymbol == other.functionSymbol)
|
|
||||||
|
|
||||||
override fun hashCode(): Int = kotlinOrigin.hashCode()
|
override fun hashCode(): Int = functionSymbol.hashCode()
|
||||||
}
|
}
|
||||||
+23
-19
@@ -6,6 +6,7 @@
|
|||||||
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
package org.jetbrains.kotlin.idea.frontend.api.fir.components
|
||||||
|
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
|
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirClass
|
import org.jetbrains.kotlin.fir.declarations.FirClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.fir.resolve.scope
|
import org.jetbrains.kotlin.fir.resolve.scope
|
||||||
@@ -29,7 +30,6 @@ import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirClassOrObjectSymb
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirEnumEntrySymbol
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.KtFirEnumEntrySymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
|
import org.jetbrains.kotlin.idea.frontend.api.fir.types.KtFirType
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EnclosingDeclarationContext
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.EnclosingDeclarationContext
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.FirRefWithValidityCheck
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.buildCompletionContext
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.buildCompletionContext
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.weakRef
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.scopes.*
|
import org.jetbrains.kotlin.idea.frontend.api.scopes.*
|
||||||
@@ -57,38 +57,42 @@ internal class KtFirScopeProvider(
|
|||||||
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithDeclarations, KtDeclaredMemberScope>()
|
private val declaredMemberScopeCache = IdentityHashMap<KtSymbolWithDeclarations, KtDeclaredMemberScope>()
|
||||||
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtPackageScope>()
|
private val packageMemberScopeCache = IdentityHashMap<KtPackageSymbol, KtPackageScope>()
|
||||||
|
|
||||||
private fun KtSymbolWithDeclarations.firRef(): FirRefWithValidityCheck<out FirClass<*>>? = when (this) {
|
private inline fun <T> KtSymbolWithDeclarations.withFirForScope(crossinline body: (FirClass<*>) -> T): T? = when (this) {
|
||||||
is KtFirClassOrObjectSymbol -> this.firRef
|
is KtFirClassOrObjectSymbol -> firRef.withFir(FirResolvePhase.SUPER_TYPES, body)
|
||||||
is KtFirEnumEntrySymbol -> this.initializerFirRef
|
is KtFirEnumEntrySymbol -> firRef.withFir(FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE) {
|
||||||
|
val initializer = it.initializer
|
||||||
|
check(initializer is FirAnonymousObject)
|
||||||
|
body(initializer)
|
||||||
|
}
|
||||||
else -> error { "Unknown KtSymbolWithDeclarations implementation ${this::class.qualifiedName}" }
|
else -> error { "Unknown KtSymbolWithDeclarations implementation ${this::class.qualifiedName}" }
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMemberScope(classSymbol: KtSymbolWithDeclarations): KtMemberScope = withValidityAssertion {
|
override fun getMemberScope(classSymbol: KtSymbolWithDeclarations): KtMemberScope = withValidityAssertion {
|
||||||
memberScopeCache.getOrPut(classSymbol) {
|
memberScopeCache.getOrPut(classSymbol) {
|
||||||
|
|
||||||
val firRef = classSymbol.firRef()
|
val firScope = classSymbol.withFirForScope { fir ->
|
||||||
?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
|
val firSession = fir.session
|
||||||
|
fir.unsubstitutedScope(
|
||||||
|
firSession,
|
||||||
|
firResolveState.firTransformerProvider.getScopeSession(firSession),
|
||||||
|
withForcedTypeCalculator = false
|
||||||
|
)
|
||||||
|
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
|
||||||
|
|
||||||
|
firScopeStorage.register(firScope)
|
||||||
|
|
||||||
val firScope =
|
|
||||||
firRef.withFir(FirResolvePhase.SUPER_TYPES) { fir ->
|
|
||||||
val firSession = fir.session
|
|
||||||
fir.unsubstitutedScope(
|
|
||||||
firSession,
|
|
||||||
firResolveState.firTransformerProvider.getScopeSession(firSession),
|
|
||||||
withForcedTypeCalculator = false
|
|
||||||
)
|
|
||||||
}.also(firScopeStorage::register)
|
|
||||||
KtFirMemberScope(classSymbol, firScope, token, builder)
|
KtFirMemberScope(classSymbol, firScope, token, builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithDeclarations): KtDeclaredMemberScope = withValidityAssertion {
|
override fun getDeclaredMemberScope(classSymbol: KtSymbolWithDeclarations): KtDeclaredMemberScope = withValidityAssertion {
|
||||||
declaredMemberScopeCache.getOrPut(classSymbol) {
|
declaredMemberScopeCache.getOrPut(classSymbol) {
|
||||||
val firRef = classSymbol.firRef()
|
val firScope = classSymbol.withFirForScope {
|
||||||
?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
|
declaredMemberScope(it)
|
||||||
|
} ?: return@getOrPut KtFirEmptyMemberScope(classSymbol)
|
||||||
|
|
||||||
|
firScopeStorage.register(firScope)
|
||||||
|
|
||||||
val firScope = firRef.withFir(FirResolvePhase.SUPER_TYPES) { declaredMemberScope(it) }
|
|
||||||
.also(firScopeStorage::register)
|
|
||||||
KtFirDeclaredMemberScope(classSymbol, firScope, token, builder)
|
KtFirDeclaredMemberScope(classSymbol, firScope, token, builder)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
@@ -9,7 +9,9 @@ import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
|
|||||||
import org.jetbrains.kotlin.fir.isSubstitutionOverride
|
import org.jetbrains.kotlin.fir.isSubstitutionOverride
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
import org.jetbrains.kotlin.fir.scopes.FirContainingNamesAwareScope
|
||||||
import org.jetbrains.kotlin.fir.scopes.FirScope
|
import org.jetbrains.kotlin.fir.scopes.FirScope
|
||||||
|
import org.jetbrains.kotlin.fir.scopes.getDeclaredConstructors
|
||||||
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
import org.jetbrains.kotlin.fir.scopes.processClassifiersByName
|
||||||
|
import org.jetbrains.kotlin.fir.symbols.impl.FirConstructorSymbol
|
||||||
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||||
@@ -73,6 +75,15 @@ internal fun FirScope.getCallableSymbols(callableNames: Collection<Name>, builde
|
|||||||
}
|
}
|
||||||
callables.add(symbol)
|
callables.add(symbol)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (name.isSpecial && name.asString() == "<init>") {
|
||||||
|
processDeclaredConstructors { firConstructor ->
|
||||||
|
firConstructor.fir.let { fir ->
|
||||||
|
callables.add(builder.buildConstructorSymbol(fir))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
yieldAll(callables)
|
yieldAll(callables)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
-4
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
|
|||||||
|
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import org.jetbrains.kotlin.fir.containingClass
|
import org.jetbrains.kotlin.fir.containingClass
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirAnonymousObject
|
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
import org.jetbrains.kotlin.fir.declarations.FirEnumEntry
|
||||||
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
|
||||||
import org.jetbrains.kotlin.idea.fir.findPsi
|
import org.jetbrains.kotlin.idea.fir.findPsi
|
||||||
@@ -16,7 +15,6 @@ import org.jetbrains.kotlin.idea.frontend.api.ValidityToken
|
|||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
import org.jetbrains.kotlin.idea.frontend.api.fir.KtSymbolByFirBuilder
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirEnumEntrySymbolPointer
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.KtFirEnumEntrySymbolPointer
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
|
import org.jetbrains.kotlin.idea.frontend.api.fir.symbols.pointers.createSignature
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.FirRefWithValidityCheck
|
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
|
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtEnumEntrySymbol
|
||||||
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
|
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
|
||||||
@@ -41,8 +39,6 @@ internal class KtFirEnumEntrySymbol(
|
|||||||
override val containingEnumClassIdIfNonLocal: ClassId?
|
override val containingEnumClassIdIfNonLocal: ClassId?
|
||||||
get() = firRef.withFir { it.containingClass()?.classId?.takeUnless { it.isLocal } }
|
get() = firRef.withFir { it.containingClass()?.classId?.takeUnless { it.isLocal } }
|
||||||
|
|
||||||
override val hasBody: Boolean get() = firRef.withFir { it.initializer != null }
|
|
||||||
|
|
||||||
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> {
|
override fun createPointer(): KtSymbolPointer<KtEnumEntrySymbol> {
|
||||||
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
|
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
|
||||||
return KtFirEnumEntrySymbolPointer(containingEnumClassIdIfNonLocal!!, firRef.withFir { it.createSignature() })
|
return KtFirEnumEntrySymbolPointer(containingEnumClassIdIfNonLocal!!, firRef.withFir { it.createSignature() })
|
||||||
|
|||||||
+1
-1
@@ -22,7 +22,7 @@ internal inline fun <reified M : KtSymbolModality> Modality?.getSymbolModality()
|
|||||||
Modality.OPEN -> KtCommonSymbolModality.OPEN
|
Modality.OPEN -> KtCommonSymbolModality.OPEN
|
||||||
Modality.ABSTRACT -> KtCommonSymbolModality.ABSTRACT
|
Modality.ABSTRACT -> KtCommonSymbolModality.ABSTRACT
|
||||||
Modality.SEALED -> KtSymbolModality.SEALED
|
Modality.SEALED -> KtSymbolModality.SEALED
|
||||||
null -> KtCommonSymbolModality.UNKNOWN
|
null -> error("Symbol modality should not be null, looks like the fir symbol was not properly resolved")
|
||||||
} as? M ?: error("Sealed modality can only be applied to class")
|
} as? M ?: error("Sealed modality can only be applied to class")
|
||||||
|
|
||||||
internal inline fun <F : FirMemberDeclaration, reified M : KtSymbolModality> KtFirSymbol<F>.getModality() =
|
internal inline fun <F : FirMemberDeclaration, reified M : KtSymbolModality> KtFirSymbol<F>.getModality() =
|
||||||
|
|||||||
Reference in New Issue
Block a user