[FIR IDE] LC basic support for type arguments

+ small fixes for deprecation, etc.
This commit is contained in:
Igor Yakovlev
2020-11-20 02:04:36 +03:00
parent 2a8f783393
commit 3fc424246b
27 changed files with 504 additions and 56 deletions

View File

@@ -7,3 +7,5 @@ abstract class A<T : A<T>> : B<Collection<T>>(), C<T> {
inner class Inner2<X> : Inner<X>(), C<X>
}
// FIR_COMPARISON

View File

@@ -1,3 +1,5 @@
// NullableUnitReturnKt
fun foo(): Unit? = null
fun foo(): Unit? = null
// FIR_COMPARISON

View File

@@ -6,3 +6,5 @@ class C {
@[kotlin.jvm.JvmField] public val foo: String = { "A" }()
}
}
// FIR_COMPARISON

View File

@@ -12,4 +12,6 @@ class Foo {
}
}
}
}
}
// FIR_COMPARISON

View File

@@ -15,6 +15,8 @@ sealed class KtClassifierSymbol : KtSymbol, KtNamedSymbol
abstract class KtTypeParameterSymbol : KtClassifierSymbol(), KtNamedSymbol {
abstract override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol>
abstract val bounds: List<KtType>
}
sealed class KtClassLikeSymbol : KtClassifierSymbol(), KtNamedSymbol, KtSymbolWithKind {

View File

@@ -40,11 +40,11 @@ internal class FirLazyDeclarationResolver(
) {
if (declaration.resolvePhase >= toPhase) return
if (declaration is FirPropertyAccessor) {
if (declaration is FirPropertyAccessor || declaration is FirTypeParameter) {
val ktContainingProperty = when (val ktDeclaration = declaration.ktDeclaration) {
is KtPropertyAccessor -> ktDeclaration.property
is KtProperty -> ktDeclaration
is KtParameter -> ktDeclaration.getNonLocalContainingOrThisDeclaration()
is KtParameter, is KtTypeParameter -> ktDeclaration.getNonLocalContainingOrThisDeclaration()
?: error("Cannot find containing declaration for KtParameter")
else -> error("Invalid source of property accessor ${ktDeclaration::class}")
}

View File

@@ -0,0 +1,54 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.asJava.elements
import com.intellij.openapi.util.TextRange
import com.intellij.psi.PsiCompiledElement
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.psi.PsiNameIdentifierOwner
import com.intellij.psi.impl.light.LightIdentifier
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtNamedSymbol
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
open class FirLightIdentifier(
private val lightOwner: PsiElement,
private val firSymbol: KtSymbol
) : LightIdentifier(lightOwner.manager, (firSymbol as? KtNamedSymbol)?.name?.identifier), PsiCompiledElement,
PsiElementWithOrigin<PsiElement> {
override val origin: PsiElement?
get() = when (val ktDeclaration = firSymbol.psi) {
is KtSecondaryConstructor -> ktDeclaration.getConstructorKeyword()
is KtPrimaryConstructor -> ktDeclaration.getConstructorKeyword()
?: ktDeclaration.valueParameterList
?: ktDeclaration.containingClassOrObject?.nameIdentifier
is KtPropertyAccessor -> ktDeclaration.namePlaceholder
is KtNamedDeclaration -> ktDeclaration.nameIdentifier
else -> null
}
override fun getMirror(): PsiElement? = null
override fun isPhysical(): Boolean = true
override fun getParent(): PsiElement = lightOwner
override fun getContainingFile(): PsiFile = lightOwner.containingFile
override fun getTextRange(): TextRange = origin?.textRange ?: TextRange.EMPTY_RANGE
override fun getTextOffset(): Int = origin?.textOffset ?: -1
}

View File

@@ -27,21 +27,19 @@ internal abstract class FirLightMemberImpl<T : PsiMember>(
override val clsDelegate: T
get() = invalidAccess()
private val lightIdentifier by lazyPub { KtLightIdentifier(this, kotlinOrigin as? KtNamedDeclaration) }
override fun hasModifierProperty(name: String): Boolean = modifierList?.hasModifierProperty(name) ?: false
override fun toString(): String = "${this::class.java.simpleName}:$name"
override fun getContainingClass() = containingClass
override fun getNameIdentifier(): PsiIdentifier = lightIdentifier
abstract override fun getNameIdentifier(): PsiIdentifier?
override val kotlinOrigin: KtDeclaration? get() = lightMemberOrigin?.originalElement
override fun getDocComment(): PsiDocComment? = null //TODO()
override fun isDeprecated(): Boolean = false //TODO()
abstract override fun isDeprecated(): Boolean
abstract override fun getName(): String

View File

@@ -0,0 +1,74 @@
/*
* 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.elements
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightElement
import com.intellij.psi.scope.PsiScopeProcessor
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.asJava.basicIsEquivalentTo
import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithTypeParameters
internal class FirLightTypeParameterListForSymbol(
internal val owner: PsiTypeParameterListOwner,
private val symbolWithTypeParameterList: KtSymbolWithTypeParameters,
private val innerShiftCount: Int
) : LightElement(owner.manager, KotlinLanguage.INSTANCE), PsiTypeParameterList {
override fun accept(visitor: PsiElementVisitor) {
if (visitor is JavaElementVisitor) {
visitor.visitTypeParameterList(this)
} else {
visitor.visitElement(this)
}
}
override fun processDeclarations(
processor: PsiScopeProcessor,
state: ResolveState,
lastParent: PsiElement?,
place: PsiElement
): Boolean {
return typeParameters.all { processor.execute(it, state) }
}
private val _typeParameters: Array<PsiTypeParameter> by lazyPub {
symbolWithTypeParameterList.typeParameters.let { list ->
list.take(list.count() - innerShiftCount).mapIndexed { index, parameter ->
FirLightTypeParameter(
parent = this@FirLightTypeParameterListForSymbol,
index = index,
typeParameterSymbol = parameter
)
}.toTypedArray()
}
}
override fun getTypeParameters(): Array<PsiTypeParameter> = _typeParameters
override fun getTypeParameterIndex(typeParameter: PsiTypeParameter?): Int =
_typeParameters.indexOf(typeParameter)
override fun toString(): String = "FirLightTypeParameterList"
override fun equals(other: Any?): Boolean =
this === other ||
(other is FirLightTypeParameterListForSymbol && symbolWithTypeParameterList == other.symbolWithTypeParameterList)
override fun hashCode(): Int = symbolWithTypeParameterList.hashCode()
override fun isEquivalentTo(another: PsiElement?): Boolean =
basicIsEquivalentTo(this, another)
override fun getParent(): PsiElement = owner
override fun getContainingFile(): PsiFile = parent.containingFile
override fun getText(): String? = ""
override fun getTextOffset(): Int = 0
override fun getStartOffsetInParent(): Int = 0
}

View File

@@ -69,6 +69,9 @@ internal fun KtAnnotatedSymbol.hasJvmFieldAnnotation(): Boolean =
internal fun KtAnnotatedSymbol.hasPublishedApiAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation("kotlin/PublishedApi", annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasDeprecatedAnnotation(annotationUseSiteTarget: AnnotationUseSiteTarget? = null): Boolean =
hasAnnotation("kotlin/Deprecated", annotationUseSiteTarget)
internal fun KtAnnotatedSymbol.hasJvmOverloadsAnnotation(): Boolean =
hasAnnotation("kotlin/jvm/JvmOverloads", null)

View File

@@ -16,18 +16,19 @@ 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.FirLightIdentifier
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.asJava.elements.FirLightTypeParameterListForSymbol
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.idea.util.ifTrue
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
@@ -41,21 +42,52 @@ internal abstract class FirLightClassForClassOrObjectSymbol(
private val isTopLevel: Boolean = classOrObjectSymbol.symbolKind == KtSymbolKind.TOP_LEVEL
private val _isDeprecated: Boolean by lazyPub {
classOrObjectSymbol.hasDeprecatedAnnotation()
}
override fun isDeprecated(): Boolean = _isDeprecated
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()
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, classOrObjectSymbol)
}
override fun getNameIdentifier(): PsiIdentifier? = _identifier
abstract override fun getExtendsList(): PsiReferenceList?
abstract override fun getImplementsList(): PsiReferenceList?
override fun getTypeParameterList(): PsiTypeParameterList? = null //TODO()
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray() //TODO()
private val _typeParameterList: PsiTypeParameterList? by lazyPub {
hasTypeParameters().ifTrue {
val shiftCount = classOrObjectSymbol.isInner.ifTrue {
(parent as? FirLightClassForClassOrObjectSymbol)?.classOrObjectSymbol?.typeParameters?.count()
} ?: 0
FirLightTypeParameterListForSymbol(
owner = this,
symbolWithTypeParameterList = classOrObjectSymbol,
innerShiftCount = shiftCount
)
}
}
override fun hasTypeParameters(): Boolean =
classOrObjectSymbol.typeParameters.isNotEmpty()
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
override fun getTypeParameters(): Array<PsiTypeParameter> =
_typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
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 fun isWritable() = false
override val kotlinOrigin: KtClassOrObject? = classOrObjectSymbol.psi as? KtClassOrObject
protected fun createInheritanceList(forExtendsList: Boolean): PsiReferenceList {
@@ -131,9 +163,6 @@ internal abstract class FirLightClassForClassOrObjectSymbol(
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 =

View File

@@ -93,10 +93,6 @@ internal class FirLightClassForSymbol(
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) }
@@ -163,7 +159,7 @@ internal class FirLightClassForSymbol(
val propertySymbols = classOrObjectSymbol.getDeclaredMemberScope().getCallableSymbols()
.filterIsInstance<KtPropertySymbol>()
.applyIf(classOrObjectSymbol.classKind == KtClassKind.COMPANION_OBJECT) {
filter { it.hasJvmFieldAnnotation() || it.isConst }
filterNot { it.hasJvmFieldAnnotation() || it.isConst }
}
createFields(propertySymbols, isTopLevel = false, result)

View File

@@ -15,10 +15,13 @@ 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.fir.declarations.FirResolvePhase
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.fir.symbols.KtFirSymbol
import org.jetbrains.kotlin.idea.frontend.api.fir.utils.firRef
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
@@ -27,7 +30,9 @@ import org.jetbrains.kotlin.idea.frontend.api.symbols.markers.KtSymbolWithVisibi
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClass
import org.jetbrains.kotlin.psi.psiUtil.isLambdaOutsideParentheses
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.util.containingNonLocalDeclaration
import java.util.*
fun getOrCreateFirLightClass(classOrObject: KtClassOrObject): KtLightClass? =
@@ -53,10 +58,19 @@ fun createFirLightClassNoCache(classOrObject: KtClassOrObject): KtLightClass? {
return null
}
if (classOrObject.isLocal) {
val nonLocalDeclaration = classOrObject.containingNonLocalDeclaration() ?: return null
analyze(nonLocalDeclaration) {
(nonLocalDeclaration.getSymbol() as? KtFirSymbol<*>)?.run {
this.firRef.withFir(FirResolvePhase.BODY_RESOLVE) { }
}
} ?: return null
}
return when {
classOrObject is KtEnumEntry -> lightClassForEnumEntry(classOrObject)
classOrObject.isObjectLiteral() -> return null //TODO
classOrObject.safeIsLocal() -> return null //TODO
//classOrObject.safeIsLocal() -> return null //TODO
classOrObject.hasModifier(KtTokens.INLINE_KEYWORD) -> return null //TODO
else -> {
analyze(classOrObject) {

View File

@@ -8,7 +8,9 @@ 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.asJava.elements.FirLightIdentifier
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.asJava.*
import org.jetbrains.kotlin.idea.asJava.FirLightClassForSymbol
import org.jetbrains.kotlin.idea.asJava.FirLightClassModifierList
import org.jetbrains.kotlin.idea.asJava.FirLightField
@@ -35,6 +37,8 @@ internal class FirLightFieldForEnumEntry(
override val kotlinOrigin: KtEnumEntry? = enumEntrySymbol.psi as? KtEnumEntry
override fun isDeprecated(): Boolean = false
//TODO Make with KtSymbols
private val hasBody: Boolean get() = kotlinOrigin?.let { it.body != null } ?: true
@@ -73,6 +77,13 @@ internal class FirLightFieldForEnumEntry(
override fun hashCode(): Int = enumEntrySymbol.hashCode()
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, enumEntrySymbol)
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
override fun equals(other: Any?): Boolean =
other is FirLightFieldForEnumEntry &&
enumEntrySymbol == other.enumEntrySymbol

View File

@@ -5,13 +5,12 @@
package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.KtLightClass
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassKind
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtClassOrObjectSymbol
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -33,12 +32,25 @@ internal class FirLightFieldForObjectSymbol(
FirLightClassModifierList(this, modifiers, listOf(notNullAnnotation))
}
private val _isDeprecated: Boolean by lazyPub {
objectSymbol.hasDeprecatedAnnotation()
}
override fun isDeprecated(): Boolean = _isDeprecated
override fun getModifierList(): PsiModifierList? = _modifierList
private val _type: PsiType by lazyPub {
objectSymbol.typeForClassSymbol(this@FirLightFieldForObjectSymbol)
}
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, objectSymbol)
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
override fun getType(): PsiType = _type
override fun getInitializer(): PsiExpression? = null //TODO

View File

@@ -5,12 +5,10 @@
package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.PsiExpression
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtPropertySymbol
@@ -34,6 +32,18 @@ internal class FirLightFieldForPropertySymbol(
)
}
private val _isDeprecated: Boolean by lazyPub {
propertySymbol.hasDeprecatedAnnotation(AnnotationUseSiteTarget.FIELD)
}
override fun isDeprecated(): Boolean = _isDeprecated
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, propertySymbol)
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
override fun getType(): PsiType = _returnedType
private val _name = propertySymbol.name.asString()

View File

@@ -11,6 +11,7 @@ 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_SETTER
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.codegen.state.KotlinTypeMapper
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
@@ -50,6 +51,10 @@ internal class FirLightAccessorMethodForSymbol(
override fun getName(): String = _name
override fun hasTypeParameters(): Boolean = false
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
override fun isVarArgs(): Boolean = false
override val kotlinOrigin: KtDeclaration? =
@@ -103,6 +108,18 @@ internal class FirLightAccessorMethodForSymbol(
override fun isConstructor(): Boolean = false
private val _isDeprecated: Boolean by lazyPub {
containingPropertySymbol.hasDeprecatedAnnotation(accessorSite)
}
override fun isDeprecated(): Boolean = _isDeprecated
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, containingPropertySymbol)
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
private val _returnedType: PsiType? by lazyPub {
if (propertyAccessorSymbol !is KtPropertyGetterSymbol) return@lazyPub PsiType.VOID
return@lazyPub containingPropertySymbol.type.asPsiType(

View File

@@ -5,12 +5,9 @@
package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtConstructorSymbol
internal class FirLightConstructorForSymbol(
@@ -26,6 +23,10 @@ internal class FirLightConstructorForSymbol(
override fun isConstructor(): Boolean = true
override fun hasTypeParameters(): Boolean = false
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
private val _annotations: List<PsiAnnotation> by lazyPub {
constructorSymbol.computeAnnotations(
parent = this,
@@ -34,6 +35,12 @@ internal class FirLightConstructorForSymbol(
)
}
private val _isDeprecated: Boolean by lazyPub {
constructorSymbol.hasDeprecatedAnnotation()
}
override fun isDeprecated(): Boolean = _isDeprecated
private val _modifiers: Set<String> by lazyPub {
setOf(constructorSymbol.computeVisibility(isTopLevel = false))
}

View File

@@ -72,11 +72,9 @@ internal abstract class FirLightMethod(
override val isMangled: Boolean = false
override fun getTypeParameters(): Array<PsiTypeParameter> = emptyArray() //TODO
override fun hasTypeParameters(): Boolean = false //TODO
override fun getTypeParameterList(): PsiTypeParameterList? = null //TODO
abstract override fun getTypeParameters(): Array<PsiTypeParameter>
abstract override fun hasTypeParameters(): Boolean
abstract override fun getTypeParameterList(): PsiTypeParameterList?
override fun getThrowsList(): PsiReferenceList =
KotlinLightReferenceListBuilder(manager, language, PsiReferenceList.Role.THROWS_LIST) //TODO()

View File

@@ -8,9 +8,8 @@ package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.*
import com.intellij.psi.impl.light.LightParameterListBuilder
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.KotlinLightReferenceListBuilder
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KotlinLightTypeParameterListBuilder
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionLikeSymbol
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.KtDeclaration
@@ -53,6 +52,12 @@ internal abstract class FirLightMethodForSymbol(
builder
}
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, functionSymbol)
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
override fun getParameterList(): PsiParameterList = _parametersList
override val kotlinOrigin: KtDeclaration? = functionSymbol.psi as? KtDeclaration

View File

@@ -5,13 +5,11 @@
package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiModifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.builder.LightMemberOrigin
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.asJava.elements.FirLightTypeParameterListForSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtFunctionSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.isUnit
import org.jetbrains.kotlin.idea.util.ifTrue
@@ -39,13 +37,32 @@ internal class FirLightSimpleMethodForSymbol(
override fun getName(): String = _name
private val _typeParameterList: PsiTypeParameterList? by lazyPub {
hasTypeParameters().ifTrue {
FirLightTypeParameterListForSymbol(
owner = this,
symbolWithTypeParameterList = functionSymbol,
innerShiftCount = 0
)
}
}
override fun hasTypeParameters(): Boolean =
functionSymbol.typeParameters.isNotEmpty()
override fun getTypeParameterList(): PsiTypeParameterList? = _typeParameterList
override fun getTypeParameters(): Array<PsiTypeParameter> =
_typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
private val _annotations: List<PsiAnnotation> by lazyPub {
val needUnknownNullability =
isVoidReturnType || (_visibility == PsiModifier.PRIVATE)
val needUnknownNullability = functionSymbol.type.isUnit || (_visibility == PsiModifier.PRIVATE)
val nullability = if (needUnknownNullability) NullabilityType.Unknown else functionSymbol.type.getTypeNullability(
functionSymbol,
FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE
val nullability = if (needUnknownNullability)
NullabilityType.Unknown
else functionSymbol.type.getTypeNullability(
context = functionSymbol,
phase = FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE
)
functionSymbol.computeAnnotations(
@@ -80,6 +97,12 @@ internal class FirLightSimpleMethodForSymbol(
)
}
private val _isDeprecated: Boolean by lazyPub {
functionSymbol.hasDeprecatedAnnotation()
}
override fun isDeprecated(): Boolean = _isDeprecated
private val _modifierList: PsiModifierList by lazyPub {
FirLightClassModifierList(this, _modifiers, _annotations)
}
@@ -88,8 +111,13 @@ internal class FirLightSimpleMethodForSymbol(
override fun isConstructor(): Boolean = false
private val isVoidReturnType: Boolean
get() = functionSymbol.type.run {
isUnit && nullabilityType != NullabilityType.Nullable
}
private val _returnedType: PsiType by lazyPub {
if (functionSymbol.type.isUnit) return@lazyPub PsiType.VOID
if (isVoidReturnType) return@lazyPub PsiType.VOID
functionSymbol.asPsiType(this@FirLightSimpleMethodForSymbol, FirResolvePhase.IMPLICIT_TYPES_BODY_RESOLVE)
}

View File

@@ -26,7 +26,8 @@ internal abstract class FirLightParameter(containingDeclaration: FirLightMethod)
override fun getInitializer(): PsiExpression? = null
override fun hasInitializer(): Boolean = false
override fun computeConstantValue(): Any? = null
override fun getNameIdentifier(): PsiIdentifier? = null
abstract override fun getNameIdentifier(): PsiIdentifier?
abstract override fun getName(): String

View File

@@ -6,6 +6,7 @@
package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.PsiAnnotation
import com.intellij.psi.PsiIdentifier
import com.intellij.psi.PsiModifierList
import com.intellij.psi.PsiType
import org.jetbrains.kotlin.asJava.classes.lazyPub
@@ -53,6 +54,8 @@ internal class FirLightParameterForReceiver private constructor(
AsmUtil.getLabeledThisName(methodName, AsmUtil.LABELED_THIS_PARAMETER, AsmUtil.RECEIVER_PARAMETER_NAME)
}
override fun getNameIdentifier(): PsiIdentifier? = null
override fun getName(): String = _name
override fun isVarArgs() = false

View File

@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.asJava
import com.intellij.psi.*
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.FirLightIdentifier
import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtParameterSymbol
@@ -46,6 +47,12 @@ internal class FirLightParameterForSymbol(
FirLightClassModifierList(this, emptySet(), _annotations)
}
private val _identifier: PsiIdentifier by lazyPub {
FirLightIdentifier(this, parameterSymbol)
}
override fun getNameIdentifier(): PsiIdentifier = _identifier
private val _type by lazyPub {
val convertedType = parameterSymbol.asPsiType(this, FirResolvePhase.TYPES)

View File

@@ -0,0 +1,163 @@
/*
* 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.elements
import com.intellij.lang.Language
import com.intellij.openapi.util.Pair
import com.intellij.openapi.util.TextRange
import com.intellij.psi.*
import com.intellij.psi.impl.PsiClassImplUtil
import com.intellij.psi.impl.light.LightElement
import com.intellij.psi.impl.light.LightReferenceListBuilder
import com.intellij.psi.javadoc.PsiDocComment
import com.intellij.psi.search.SearchScope
import org.jetbrains.kotlin.asJava.classes.KotlinSuperTypeListBuilder
import org.jetbrains.kotlin.asJava.classes.cannotModify
import org.jetbrains.kotlin.asJava.classes.lazyPub
import org.jetbrains.kotlin.asJava.elements.KtLightAbstractAnnotation
import org.jetbrains.kotlin.asJava.elements.KtLightDeclaration
import org.jetbrains.kotlin.fir.symbols.StandardClassIds
import org.jetbrains.kotlin.idea.KotlinLanguage
import org.jetbrains.kotlin.idea.asJava.basicIsEquivalentTo
import org.jetbrains.kotlin.idea.asJava.invalidAccess
import org.jetbrains.kotlin.idea.asJava.mapSupertype
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.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.types.KtClassType
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.psi.KtTypeParameter
import org.jetbrains.kotlin.psi.psiUtil.startOffset
internal class FirLightTypeParameter(
private val parent: FirLightTypeParameterListForSymbol,
private val index: Int,
private val typeParameterSymbol: KtTypeParameterSymbol
) : LightElement(parent.manager, KotlinLanguage.INSTANCE), PsiTypeParameter,
KtLightDeclaration<KtTypeParameter, PsiTypeParameter> {
override val clsDelegate: PsiTypeParameter get() = invalidAccess()
override val givenAnnotations: List<KtLightAbstractAnnotation>? get() = invalidAccess()
override val kotlinOrigin: KtTypeParameter? = typeParameterSymbol.psi as? KtTypeParameter
override fun copy(): PsiElement =
FirLightTypeParameter(parent, index, typeParameterSymbol)
override fun accept(visitor: PsiElementVisitor) {
if (visitor is JavaElementVisitor) {
visitor.visitTypeParameter(this)
} else {
super<LightElement>.accept(visitor)
}
}
private val _extendsList: PsiReferenceList by lazyPub {
val listBuilder = KotlinSuperTypeListBuilder(
kotlinOrigin = null,
manager = manager,
language = language,
role = PsiReferenceList.Role.EXTENDS_LIST
)
typeParameterSymbol.bounds
.filterIsInstance<KtClassType>()
.filter { it.classId != StandardClassIds.Any }
.mapNotNull { it.mapSupertype(this, kotlinCollectionAsIs = true) }
.forEach { listBuilder.addReference(it) }
listBuilder
}
override fun getExtendsList(): PsiReferenceList = _extendsList
override fun getExtendsListTypes(): Array<PsiClassType> =
PsiClassImplUtil.getExtendsListTypes(this)
//PsiClass simple implementation
override fun getImplementsList(): PsiReferenceList? = null
override fun getImplementsListTypes(): Array<PsiClassType> = PsiClassType.EMPTY_ARRAY
override fun getSuperClass(): PsiClass? = null
override fun getInterfaces(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
override fun getSupers(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
override fun getSuperTypes(): Array<PsiClassType> = PsiClassType.EMPTY_ARRAY
override fun getConstructors(): Array<PsiMethod> = PsiMethod.EMPTY_ARRAY
override fun getInitializers(): Array<PsiClassInitializer> = PsiClassInitializer.EMPTY_ARRAY
override fun getAllFields(): Array<PsiField> = PsiField.EMPTY_ARRAY
override fun getAllMethods(): Array<PsiMethod> = PsiMethod.EMPTY_ARRAY
override fun getAllInnerClasses(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
override fun findFieldByName(name: String?, checkBases: Boolean): PsiField? = null
override fun findMethodBySignature(patternMethod: PsiMethod?, checkBases: Boolean): PsiMethod? = null
override fun findMethodsBySignature(patternMethod: PsiMethod?, checkBases: Boolean): Array<PsiMethod> = PsiMethod.EMPTY_ARRAY
override fun findMethodsAndTheirSubstitutorsByName(name: String?, checkBases: Boolean)
: MutableList<Pair<PsiMethod, PsiSubstitutor>> = mutableListOf()
override fun getAllMethodsAndTheirSubstitutors()
: MutableList<Pair<PsiMethod, PsiSubstitutor>> = mutableListOf()
override fun findInnerClassByName(name: String?, checkBases: Boolean): PsiClass? = null
override fun getLBrace(): PsiElement? = null
override fun getRBrace(): PsiElement? = null
override fun getScope(): PsiElement = parent
override fun isInheritor(baseClass: PsiClass, checkDeep: Boolean): Boolean = false
override fun isInheritorDeep(baseClass: PsiClass?, classToByPass: PsiClass?): Boolean = false
override fun getVisibleSignatures(): MutableCollection<HierarchicalMethodSignature> = mutableListOf()
override fun setName(name: String): PsiElement = cannotModify()
override fun getNameIdentifier(): PsiIdentifier? = null
override fun getModifierList(): PsiModifierList? = null
override fun hasModifierProperty(name: String): Boolean = false
override fun getOwner(): PsiTypeParameterListOwner? = parent.owner
override fun getParent(): PsiElement = parent
override fun getAnnotations(): Array<PsiAnnotation> = PsiAnnotation.EMPTY_ARRAY
override fun getContainingClass(): PsiClass? = null
override fun getDocComment(): PsiDocComment? = null
override fun isDeprecated(): Boolean = false
override fun getTypeParameters(): Array<PsiTypeParameter> = PsiTypeParameter.EMPTY_ARRAY
override fun hasTypeParameters(): Boolean = false
override fun getTypeParameterList(): PsiTypeParameterList? = null
override fun getQualifiedName(): String? = null
override fun getMethods(): Array<PsiMethod> = PsiMethod.EMPTY_ARRAY
override fun findMethodsByName(name: String?, checkBases: Boolean): Array<PsiMethod> = PsiMethod.EMPTY_ARRAY
override fun getFields(): Array<PsiField> = PsiField.EMPTY_ARRAY
override fun getInnerClasses(): Array<PsiClass> = PsiClass.EMPTY_ARRAY
override fun isInterface(): Boolean = false
override fun isAnnotationType(): Boolean = false
override fun isEnum(): Boolean = false
override fun findAnnotation(qualifiedName: String): PsiAnnotation? = null
override fun addAnnotation(qualifiedName: String): PsiAnnotation = cannotModify()
//End of PsiClass simple implementation
override fun getText(): String = kotlinOrigin?.text ?: ""
override fun getName(): String? = typeParameterSymbol.name.asString()
override fun getIndex(): Int = index
override fun getApplicableAnnotations(): Array<PsiAnnotation> = PsiAnnotation.EMPTY_ARRAY //TODO
override fun toString(): String = "FirLightTypeParameter:$name"
override fun getNavigationElement(): PsiElement =
kotlinOrigin ?: parent.navigationElement
override fun getLanguage(): Language = KotlinLanguage.INSTANCE
override fun getUseScope(): SearchScope =
kotlinOrigin?.useScope ?: parent.useScope
override fun equals(other: Any?): Boolean =
this === other ||
(other is FirLightTypeParameter && index == other.index && typeParameterSymbol == other.typeParameterSymbol)
override fun hashCode(): Int = typeParameterSymbol.hashCode() + index
override fun isEquivalentTo(another: PsiElement): Boolean =
basicIsEquivalentTo(this, another)
override fun getTextRange(): TextRange? = kotlinOrigin?.textRange
override fun getContainingFile(): PsiFile = parent.containingFile
override fun getTextOffset(): Int = kotlinOrigin?.startOffset ?: super.getTextOffset()
override fun getStartOffsetInParent(): Int = kotlinOrigin?.startOffsetInParent ?: super.getStartOffsetInParent()
}

View File

@@ -127,7 +127,7 @@ internal class KtSymbolByFirBuilder private constructor(
}
fun buildConstructorSymbol(fir: FirConstructor) = symbolsCache.cache(fir) { KtFirConstructorSymbol(fir, resolveState, token, this) }
fun buildTypeParameterSymbol(fir: FirTypeParameter) = symbolsCache.cache(fir) { KtFirTypeParameterSymbol(fir, resolveState, token) }
fun buildTypeParameterSymbol(fir: FirTypeParameter) = symbolsCache.cache(fir) { KtFirTypeParameterSymbol(fir, resolveState, token, this) }
fun buildTypeAliasSymbol(fir: FirTypeAlias) = symbolsCache.cache(fir) { KtFirTypeAliasSymbol(fir, resolveState, token) }
fun buildEnumEntrySymbol(fir: FirEnumEntry) = symbolsCache.cache(fir) { KtFirEnumEntrySymbol(fir, resolveState, token, this) }

View File

@@ -6,26 +6,34 @@
package org.jetbrains.kotlin.idea.frontend.api.fir.symbols
import com.intellij.psi.PsiElement
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirTypeParameter
import org.jetbrains.kotlin.idea.fir.findPsi
import org.jetbrains.kotlin.idea.fir.low.level.api.api.FirModuleResolveState
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.utils.firRef
import org.jetbrains.kotlin.idea.frontend.api.symbols.KtTypeParameterSymbol
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtPsiBasedSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.symbols.pointers.KtSymbolPointer
import org.jetbrains.kotlin.idea.frontend.api.types.KtType
import org.jetbrains.kotlin.name.Name
internal class KtFirTypeParameterSymbol(
fir: FirTypeParameter,
resolveState: FirModuleResolveState,
override val token: ValidityToken
override val token: ValidityToken,
private val builder: KtSymbolByFirBuilder
) : KtTypeParameterSymbol(), KtFirSymbol<FirTypeParameter> {
override val firRef = firRef(fir, resolveState)
override val psi: PsiElement? by firRef.withFirAndCache { it.findPsi(fir.session) }
override val name: Name get() = firRef.withFir { it.name }
override val bounds: List<KtType> by firRef.withFirAndCache(FirResolvePhase.TYPES) { fir ->
fir.bounds.map { type -> builder.buildKtType(type) }
}
override fun createPointer(): KtSymbolPointer<KtTypeParameterSymbol> {
KtPsiBasedSymbolPointer.createForSymbolFromSource(this)?.let { return it }
TODO("Creating symbols for library type parameters is not supported yet")