[FIR IDE] Codereview minor refactoring

https://jetbrains.team/p/kt/review/2069/
https://jetbrains.team/p/kt/review/2070/
This commit is contained in:
Igor Yakovlev
2021-01-29 19:53:36 +03:00
parent e529a7bf9b
commit 18cebe5131
14 changed files with 45 additions and 42 deletions
@@ -310,7 +310,7 @@ class JavaSymbolProvider(
if (classIsAnnotation) { if (classIsAnnotation) {
declarations += declarations +=
buildConstructorForAnnotationClass( buildConstructorForAnnotationClass(
classSource = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement(FirFakeSourceElementKind.ImplicitConstructor), classSource = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement(FirFakeSourceElementKind.ImplicitConstructor) as? FirFakeSourceElement,
constructorId = constructorId, constructorId = constructorId,
ownerClassBuilder = this, ownerClassBuilder = this,
valueParametersForAnnotationConstructor = valueParametersForAnnotationConstructor valueParametersForAnnotationConstructor = valueParametersForAnnotationConstructor
@@ -511,7 +511,7 @@ class JavaSymbolProvider(
} }
private fun buildConstructorForAnnotationClass( private fun buildConstructorForAnnotationClass(
classSource: FirSourceElement?, classSource: FirFakeSourceElement<*>?,
constructorId: CallableId, constructorId: CallableId,
ownerClassBuilder: FirJavaClassBuilder, ownerClassBuilder: FirJavaClassBuilder,
valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor
@@ -49,6 +49,7 @@ internal fun textAttributesKeyForTypeDeclaration(declaration: PsiElement): TextA
declaration is KtClass -> textAttributesForClass(declaration) declaration is KtClass -> textAttributesForClass(declaration)
declaration is PsiClass && declaration.isInterface && !declaration.isAnnotationType -> Colors.TRAIT declaration is PsiClass && declaration.isInterface && !declaration.isAnnotationType -> Colors.TRAIT
declaration.isAnnotationClass() -> Colors.ANNOTATION declaration.isAnnotationClass() -> Colors.ANNOTATION
declaration is KtPrimaryConstructor && declaration.parent.isAnnotationClass() -> Colors.ANNOTATION
declaration is KtObjectDeclaration -> Colors.OBJECT declaration is KtObjectDeclaration -> Colors.OBJECT
declaration is PsiEnumConstant -> Colors.ENUM_ENTRY declaration is PsiEnumConstant -> Colors.ENUM_ENTRY
declaration is PsiClass && declaration.hasModifier(JvmModifier.ABSTRACT) -> Colors.ABSTRACT_CLASS declaration is PsiClass && declaration.hasModifier(JvmModifier.ABSTRACT) -> Colors.ABSTRACT_CLASS
@@ -44,7 +44,8 @@ internal class TypeHighlightingVisitor(
private fun computeHighlightingRangeForUsage(expression: KtSimpleNameExpression, target: PsiElement): TextRange { private fun computeHighlightingRangeForUsage(expression: KtSimpleNameExpression, target: PsiElement): TextRange {
val expressionRange = expression.textRange val expressionRange = expression.textRange
if (!target.isAnnotationClass()) return expressionRange val isKotlinAnnotation = target is KtPrimaryConstructor && target.parent.isAnnotationClass()
if (!isKotlinAnnotation && !target.isAnnotationClass()) return expressionRange
// include '@' symbol if the reference is the first segment of KtAnnotationEntry // include '@' symbol if the reference is the first segment of KtAnnotationEntry
// if "Deprecated" is highlighted then '@' should be highlighted too in "@Deprecated" // if "Deprecated" is highlighted then '@' should be highlighted too in "@Deprecated"
@@ -80,7 +80,7 @@ abstract class KtAnalysisSession(final override val token: ValidityToken) : Vali
val builtinTypes: KtBuiltinTypes get() = typeProvider.builtinTypes val builtinTypes: KtBuiltinTypes get() = typeProvider.builtinTypes
fun KtClassOrObjectSymbol.buildTypeForSymbol(): KtType = typeProvider.buildTypeForSymbol(this) fun KtClassOrObjectSymbol.buildSelfClassType(): KtType = typeProvider.buildSelfClassType(this)
fun KtElement.getDiagnostics(): Collection<Diagnostic> = diagnosticProvider.getDiagnosticsForElement(this) fun KtElement.getDiagnostics(): Collection<Diagnostic> = diagnosticProvider.getDiagnosticsForElement(this)
@@ -15,7 +15,7 @@ abstract class KtTypeProvider : KtAnalysisSessionComponent() {
abstract val builtinTypes: KtBuiltinTypes abstract val builtinTypes: KtBuiltinTypes
abstract fun buildTypeForSymbol(symbol: KtClassOrObjectSymbol): KtType abstract fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType
} }
@@ -6,7 +6,6 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.element.builder package org.jetbrains.kotlin.idea.fir.low.level.api.element.builder
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentsOfType
import org.jetbrains.annotations.TestOnly import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirFile import org.jetbrains.kotlin.fir.declarations.FirFile
@@ -16,11 +15,12 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureCache
import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement import org.jetbrains.kotlin.idea.fir.low.level.api.file.structure.FileStructureElement
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
import org.jetbrains.kotlin.idea.fir.low.level.api.util.isNonAnonymousClassOrObject
import org.jetbrains.kotlin.idea.util.getElementTextInContext import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.isAncestor import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.psi2ir.deparenthesize import org.jetbrains.kotlin.psi2ir.deparenthesize
/** /**
@@ -123,14 +123,6 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate:
return null return null
} }
private fun KtDeclaration.isNonAnonymousClassOrObject() =
this is KtClassOrObject
&& !this.isObjectLiteral()
private fun KtDeclaration.hasFqName(): Boolean =
parentsOfType<KtDeclaration>(withSelf = false).all { it.isNonAnonymousClassOrObject() }
internal fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? = internal fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? =
getNonLocalContainingOrThisDeclaration { declaration -> getNonLocalContainingOrThisDeclaration { declaration ->
when (declaration) { when (declaration) {
@@ -6,7 +6,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.FirFile
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.FirTowerDataContextCollector
import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.element.builder.getNonLocalContainingOrThisDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.FirFileBuilder
@@ -15,8 +16,10 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarati
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider import org.jetbrains.kotlin.idea.fir.low.level.api.providers.firIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import java.util.concurrent.ConcurrentHashMap import java.util.concurrent.ConcurrentHashMap
@@ -89,6 +92,7 @@ internal class FileStructure(
val firFile = firFileBuilder.getFirFileResolvedToPhaseWithCaching( val firFile = firFileBuilder.getFirFileResolvedToPhaseWithCaching(
container, container,
moduleFileCache, moduleFileCache,
//TODO: Make resolve whole file into TYPES only for top level declarations or annotations with `file` site
FirResolvePhase.TYPES, FirResolvePhase.TYPES,
checkPCE = true checkPCE = true
) )
@@ -8,10 +8,8 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
import org.jetbrains.kotlin.diagnostics.Diagnostic import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorDeclarationAction import org.jetbrains.kotlin.fir.analysis.collectors.DiagnosticCollectorDeclarationAction
import org.jetbrains.kotlin.fir.containingClass
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.psi import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol import org.jetbrains.kotlin.fir.symbols.impl.FirPropertySymbol
@@ -19,9 +17,9 @@ import org.jetbrains.kotlin.idea.fir.low.level.api.diagnostics.FirIdeStructureEl
import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache import org.jetbrains.kotlin.idea.fir.low.level.api.file.builder.ModuleFileCache
import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver import org.jetbrains.kotlin.idea.fir.low.level.api.lazy.resolve.FirLazyDeclarationResolver
import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider import org.jetbrains.kotlin.idea.fir.low.level.api.providers.FirIdeProvider
import org.jetbrains.kotlin.idea.fir.low.level.api.util.hasFqName
import org.jetbrains.kotlin.idea.fir.low.level.api.util.isGeneratedDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.util.isGeneratedDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.util.ktDeclaration import org.jetbrains.kotlin.idea.fir.low.level.api.util.ktDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.util.replaceFirst
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
internal class FileStructureElementDiagnostics( internal class FileStructureElementDiagnostics(
@@ -183,14 +181,14 @@ internal class NonReanalyzableDeclarationStructureElement(
private val recorder = object : FirElementsRecorder() { private val recorder = object : FirElementsRecorder() {
override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) { override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) {
val psi = property.psi as? KtProperty ?: return super.visitProperty(property, data) val psi = property.psi as? KtProperty ?: return super.visitProperty(property, data)
if (!FileElementFactory.isReanalyzableContainer(psi) || KtPsiUtil.isLocal(psi)) { if (!FileElementFactory.isReanalyzableContainer(psi) || !psi.hasFqName()) {
super.visitProperty(property, data) super.visitProperty(property, data)
} }
} }
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) { override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) {
val psi = simpleFunction.psi as? KtNamedFunction ?: return super.visitSimpleFunction(simpleFunction, data) val psi = simpleFunction.psi as? KtNamedFunction ?: return super.visitSimpleFunction(simpleFunction, data)
if (!FileElementFactory.isReanalyzableContainer(psi) || KtPsiUtil.isLocal(psi)) { if (!FileElementFactory.isReanalyzableContainer(psi) || !psi.hasFqName()) {
super.visitSimpleFunction(simpleFunction, data) super.visitSimpleFunction(simpleFunction, data)
} }
} }
@@ -7,6 +7,7 @@ package org.jetbrains.kotlin.idea.fir.low.level.api.util
import com.intellij.openapi.progress.ProcessCanceledException import com.intellij.openapi.progress.ProcessCanceledException
import com.intellij.openapi.progress.ProgressManager import com.intellij.openapi.progress.ProgressManager
import com.intellij.psi.util.parentsOfType
import org.jetbrains.kotlin.fir.FirElement import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirDeclaration import org.jetbrains.kotlin.fir.declarations.FirDeclaration
import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder import org.jetbrains.kotlin.fir.diagnostics.FirDiagnosticHolder
@@ -14,10 +15,8 @@ import org.jetbrains.kotlin.fir.psi
import org.jetbrains.kotlin.fir.render import org.jetbrains.kotlin.fir.render
import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo import org.jetbrains.kotlin.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.util.getElementTextInContext import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import java.util.concurrent.TimeUnit import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.Lock import java.util.concurrent.locks.Lock
@@ -91,4 +90,11 @@ internal fun IdeaModuleInfo.collectTransitiveDependenciesWithSelf(): List<IdeaMo
} }
collect(this) collect(this)
return result.toList() return result.toList()
} }
internal fun KtDeclaration.hasFqName(): Boolean =
parentsOfType<KtDeclaration>(withSelf = false).all { it.isNonAnonymousClassOrObject() }
internal fun KtDeclaration.isNonAnonymousClassOrObject() =
this is KtClassOrObject
&& !this.isObjectLiteral()
@@ -337,10 +337,10 @@ internal fun KtClassOrObject.checkIsInheritor(baseClassOrigin: KtClassOrObject,
if (thisSymbol == baseSymbol) return@analyze false if (thisSymbol == baseSymbol) return@analyze false
val baseType = baseSymbol.buildTypeForSymbol() val baseType = baseSymbol.buildSelfClassType()
if (checkDeep) { if (checkDeep) {
thisSymbol.buildTypeForSymbol().isSubTypeOf(baseType) thisSymbol.buildSelfClassType().isSubTypeOf(baseType)
} else { } else {
thisSymbol.superTypes.any { baseType.isEqualTo(it.type) } thisSymbol.superTypes.any { baseType.isEqualTo(it.type) }
} }
@@ -66,7 +66,7 @@ internal fun KtClassOrObjectSymbol.typeForClassSymbol(psiElement: PsiElement): P
require(this is KtFirClassOrObjectSymbol) require(this is KtFirClassOrObjectSymbol)
val types = analyzeWithSymbolAsContext(this) { val types = analyzeWithSymbolAsContext(this) {
this@typeForClassSymbol.buildTypeForSymbol() this@typeForClassSymbol.buildSelfClassType()
} }
require(types is KtFirType) require(types is KtFirType)
@@ -31,7 +31,7 @@ internal class KtFirTypeProvider(
override val builtinTypes: KtBuiltinTypes = override val builtinTypes: KtBuiltinTypes =
KtFirBuiltInTypes(analysisSession.firResolveState.rootModuleSession.builtinTypes, analysisSession.firSymbolBuilder, token) KtFirBuiltInTypes(analysisSession.firResolveState.rootModuleSession.builtinTypes, analysisSession.firSymbolBuilder, token)
override fun buildTypeForSymbol(symbol: KtClassOrObjectSymbol): KtType { override fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType {
require(symbol is KtFirClassOrObjectSymbol) require(symbol is KtFirClassOrObjectSymbol)
val type = symbol.firRef.withFir(FirResolvePhase.TYPES) { firClass -> val type = symbol.firRef.withFir(FirResolvePhase.TYPES) { firClass ->
ConeClassLikeTypeImpl( ConeClassLikeTypeImpl(
@@ -18,14 +18,16 @@ internal class KtFirSimpleNameReference(
expression: KtSimpleNameExpression expression: KtSimpleNameExpression
) : KtSimpleNameReference(expression), KtFirReference { ) : KtSimpleNameReference(expression), KtFirReference {
private fun KtAnalysisSession.fixUpAnnotationCallResolveToCtor(resultsToFix: Collection<KtSymbol>): Collection<KtSymbol> { private val isAnnotationCall: Boolean
if (resultsToFix.isEmpty()) return resultsToFix get() {
val ktUserType = expression.parent as? KtUserType ?: return false
val ktTypeReference = ktUserType.parent as? KtTypeReference ?: return false
val ktConstructorCalleeExpression = ktTypeReference.parent as? KtConstructorCalleeExpression ?: return false
return ktConstructorCalleeExpression.parent is KtAnnotationEntry
}
val isAnnotationCall = (((expression.parent as? KtUserType) private fun KtAnalysisSession.fixUpAnnotationCallResolveToCtor(resultsToFix: Collection<KtSymbol>): Collection<KtSymbol> {
?.parent as? KtTypeReference) if (resultsToFix.isEmpty() || !isAnnotationCall) return resultsToFix
?.parent as? KtConstructorCalleeExpression)
?.parent is KtAnnotationEntry
if (!isAnnotationCall) return resultsToFix
return resultsToFix.map { targetSymbol -> return resultsToFix.map { targetSymbol ->
if (targetSymbol is KtFirClassOrObjectSymbol && targetSymbol.classKind == KtClassKind.ANNOTATION_CLASS) { if (targetSymbol is KtFirClassOrObjectSymbol && targetSymbol.classKind == KtClassKind.ANNOTATION_CLASS) {
@@ -37,6 +39,7 @@ internal class KtFirSimpleNameReference(
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> { override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
check(this is KtFirAnalysisSession) check(this is KtFirAnalysisSession)
val results = FirReferenceResolveHelper.resolveSimpleNameReference(this@KtFirSimpleNameReference, this) val results = FirReferenceResolveHelper.resolveSimpleNameReference(this@KtFirSimpleNameReference, this)
//This fix-up needed to resolve annotation call into annotation constructor (but not into the annotation type)
return fixUpAnnotationCallResolveToCtor(results) return fixUpAnnotationCallResolveToCtor(results)
} }
+1 -3
View File
@@ -5,6 +5,4 @@ fun <info descr="null" textAttributesKey="KOTLIN_FUNCTION_DECLARATION">foo</info
fun <info descr="null" textAttributesKey="KOTLIN_FUNCTION_DECLARATION">bar</info>() { fun <info descr="null" textAttributesKey="KOTLIN_FUNCTION_DECLARATION">bar</info>() {
<info descr="null" textAttributesKey="KOTLIN_PACKAGE_FUNCTION_CALL">foo</info>(1, <info descr="null" textAttributesKey="KOTLIN_NAMED_ARGUMENT">p2 =</info> "") <info descr="null" textAttributesKey="KOTLIN_PACKAGE_FUNCTION_CALL">foo</info>(1, <info descr="null" textAttributesKey="KOTLIN_NAMED_ARGUMENT">p2 =</info> "")
} }
// IGNORE_FIR