[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) {
declarations +=
buildConstructorForAnnotationClass(
classSource = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement(FirFakeSourceElementKind.ImplicitConstructor),
classSource = (javaClass as? JavaElementImpl<*>)?.psi?.toFirPsiSourceElement(FirFakeSourceElementKind.ImplicitConstructor) as? FirFakeSourceElement,
constructorId = constructorId,
ownerClassBuilder = this,
valueParametersForAnnotationConstructor = valueParametersForAnnotationConstructor
@@ -511,7 +511,7 @@ class JavaSymbolProvider(
}
private fun buildConstructorForAnnotationClass(
classSource: FirSourceElement?,
classSource: FirFakeSourceElement<*>?,
constructorId: CallableId,
ownerClassBuilder: FirJavaClassBuilder,
valueParametersForAnnotationConstructor: ValueParametersForAnnotationConstructor
@@ -49,6 +49,7 @@ internal fun textAttributesKeyForTypeDeclaration(declaration: PsiElement): TextA
declaration is KtClass -> textAttributesForClass(declaration)
declaration is PsiClass && declaration.isInterface && !declaration.isAnnotationType -> Colors.TRAIT
declaration.isAnnotationClass() -> Colors.ANNOTATION
declaration is KtPrimaryConstructor && declaration.parent.isAnnotationClass() -> Colors.ANNOTATION
declaration is KtObjectDeclaration -> Colors.OBJECT
declaration is PsiEnumConstant -> Colors.ENUM_ENTRY
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 {
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
// 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
fun KtClassOrObjectSymbol.buildTypeForSymbol(): KtType = typeProvider.buildTypeForSymbol(this)
fun KtClassOrObjectSymbol.buildSelfClassType(): KtType = typeProvider.buildSelfClassType(this)
fun KtElement.getDiagnostics(): Collection<Diagnostic> = diagnosticProvider.getDiagnosticsForElement(this)
@@ -15,7 +15,7 @@ abstract class KtTypeProvider : KtAnalysisSessionComponent() {
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
import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentsOfType
import org.jetbrains.annotations.TestOnly
import org.jetbrains.kotlin.fir.FirElement
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.structure.FileStructureCache
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.psi.*
import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import org.jetbrains.kotlin.psi2ir.deparenthesize
/**
@@ -123,14 +123,6 @@ internal inline fun PsiElement.getNonLocalContainingOrThisDeclaration(predicate:
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? =
getNonLocalContainingOrThisDeclaration { declaration ->
when (declaration) {
@@ -6,7 +6,8 @@
package org.jetbrains.kotlin.idea.fir.low.level.api.file.structure
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.getNonLocalContainingOrThisDeclaration
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.util.findSourceNonLocalFirDeclaration
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
import org.jetbrains.kotlin.psi.KtAnnotated
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import java.util.concurrent.ConcurrentHashMap
@@ -89,6 +92,7 @@ internal class FileStructure(
val firFile = firFileBuilder.getFirFileResolvedToPhaseWithCaching(
container,
moduleFileCache,
//TODO: Make resolve whole file into TYPES only for top level declarations or annotations with `file` site
FirResolvePhase.TYPES,
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.fir.FirElement
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.psi
import org.jetbrains.kotlin.fir.resolve.toSymbol
import org.jetbrains.kotlin.fir.symbols.AbstractFirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.FirFunctionSymbol
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.lazy.resolve.FirLazyDeclarationResolver
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.ktDeclaration
import org.jetbrains.kotlin.idea.fir.low.level.api.util.replaceFirst
import org.jetbrains.kotlin.psi.*
internal class FileStructureElementDiagnostics(
@@ -183,14 +181,14 @@ internal class NonReanalyzableDeclarationStructureElement(
private val recorder = object : FirElementsRecorder() {
override fun visitProperty(property: FirProperty, data: MutableMap<KtElement, FirElement>) {
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)
}
}
override fun visitSimpleFunction(simpleFunction: FirSimpleFunction, data: MutableMap<KtElement, FirElement>) {
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)
}
}
@@ -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.ProgressManager
import com.intellij.psi.util.parentsOfType
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.declarations.FirDeclaration
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.idea.caches.project.IdeaModuleInfo
import org.jetbrains.kotlin.idea.util.getElementTextInContext
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.psi.KtObjectLiteralExpression
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.isObjectLiteral
import java.util.concurrent.TimeUnit
import java.util.concurrent.locks.Lock
@@ -91,4 +90,11 @@ internal fun IdeaModuleInfo.collectTransitiveDependenciesWithSelf(): List<IdeaMo
}
collect(this)
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
val baseType = baseSymbol.buildTypeForSymbol()
val baseType = baseSymbol.buildSelfClassType()
if (checkDeep) {
thisSymbol.buildTypeForSymbol().isSubTypeOf(baseType)
thisSymbol.buildSelfClassType().isSubTypeOf(baseType)
} else {
thisSymbol.superTypes.any { baseType.isEqualTo(it.type) }
}
@@ -66,7 +66,7 @@ internal fun KtClassOrObjectSymbol.typeForClassSymbol(psiElement: PsiElement): P
require(this is KtFirClassOrObjectSymbol)
val types = analyzeWithSymbolAsContext(this) {
this@typeForClassSymbol.buildTypeForSymbol()
this@typeForClassSymbol.buildSelfClassType()
}
require(types is KtFirType)
@@ -31,7 +31,7 @@ internal class KtFirTypeProvider(
override val builtinTypes: KtBuiltinTypes =
KtFirBuiltInTypes(analysisSession.firResolveState.rootModuleSession.builtinTypes, analysisSession.firSymbolBuilder, token)
override fun buildTypeForSymbol(symbol: KtClassOrObjectSymbol): KtType {
override fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType {
require(symbol is KtFirClassOrObjectSymbol)
val type = symbol.firRef.withFir(FirResolvePhase.TYPES) { firClass ->
ConeClassLikeTypeImpl(
@@ -18,14 +18,16 @@ internal class KtFirSimpleNameReference(
expression: KtSimpleNameExpression
) : KtSimpleNameReference(expression), KtFirReference {
private fun KtAnalysisSession.fixUpAnnotationCallResolveToCtor(resultsToFix: Collection<KtSymbol>): Collection<KtSymbol> {
if (resultsToFix.isEmpty()) return resultsToFix
private val isAnnotationCall: Boolean
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)
?.parent as? KtTypeReference)
?.parent as? KtConstructorCalleeExpression)
?.parent is KtAnnotationEntry
if (!isAnnotationCall) return resultsToFix
private fun KtAnalysisSession.fixUpAnnotationCallResolveToCtor(resultsToFix: Collection<KtSymbol>): Collection<KtSymbol> {
if (resultsToFix.isEmpty() || !isAnnotationCall) return resultsToFix
return resultsToFix.map { targetSymbol ->
if (targetSymbol is KtFirClassOrObjectSymbol && targetSymbol.classKind == KtClassKind.ANNOTATION_CLASS) {
@@ -37,6 +39,7 @@ internal class KtFirSimpleNameReference(
override fun KtAnalysisSession.resolveToSymbols(): Collection<KtSymbol> {
check(this is KtFirAnalysisSession)
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)
}
+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>() {
<info descr="null" textAttributesKey="KOTLIN_PACKAGE_FUNCTION_CALL">foo</info>(1, <info descr="null" textAttributesKey="KOTLIN_NAMED_ARGUMENT">p2 =</info> "")
}
// IGNORE_FIR
}