diff --git a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt index 78fb7b74872..8251fc7d84b 100644 --- a/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt +++ b/compiler/fir/java/src/org/jetbrains/kotlin/fir/java/JavaSymbolProvider.kt @@ -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 diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/HighlightingUtils.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/HighlightingUtils.kt index d13e9d28dd7..0444d6a9176 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/HighlightingUtils.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/HighlightingUtils.kt @@ -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 diff --git a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/TypeHighlightingVisitor.kt b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/TypeHighlightingVisitor.kt index a26c4da1fa7..864ad028088 100644 --- a/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/TypeHighlightingVisitor.kt +++ b/idea/idea-fir/src/org/jetbrains/kotlin/idea/fir/highlighter/visitors/TypeHighlightingVisitor.kt @@ -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" diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt index 0427b25fe00..a768ed8d6d5 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/KtAnalysisSession.kt @@ -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 = diagnosticProvider.getDiagnosticsForElement(this) diff --git a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt index 4b46fd1cc68..38bcd0906d7 100644 --- a/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt +++ b/idea/idea-frontend-api/src/org/jetbrains/kotlin/idea/frontend/api/components/KtTypeProvider.kt @@ -15,7 +15,7 @@ abstract class KtTypeProvider : KtAnalysisSessionComponent() { abstract val builtinTypes: KtBuiltinTypes - abstract fun buildTypeForSymbol(symbol: KtClassOrObjectSymbol): KtType + abstract fun buildSelfClassType(symbol: KtClassOrObjectSymbol): KtType } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirElementBuilder.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirElementBuilder.kt index 021415680d3..cdc1ae24ac0 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirElementBuilder.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/element/builder/FirElementBuilder.kt @@ -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(withSelf = false).all { it.isNonAnonymousClassOrObject() } - internal fun PsiElement.getNonLocalContainingInBodyDeclarationWith(): KtNamedDeclaration? = getNonLocalContainingOrThisDeclaration { declaration -> when (declaration) { diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt index fe01b3a6557..f90e7e4746a 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructure.kt @@ -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 ) diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructureElement.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructureElement.kt index 80aae13852a..d5e36707d4e 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructureElement.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/file/structure/FileStructureElement.kt @@ -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) { 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) { 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) } } diff --git a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt index b364ea19056..a01ee03a91d 100644 --- a/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt +++ b/idea/idea-frontend-fir/idea-fir-low-level-api/src/org/jetbrains/kotlin/idea/fir/low/level/api/util/utils.kt @@ -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(withSelf = false).all { it.isNonAnonymousClassOrObject() } + +internal fun KtDeclaration.isNonAnonymousClassOrObject() = + this is KtClassOrObject + && !this.isObjectLiteral() diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt index 38ddfbea1ed..6506d34c3c3 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/classes/firLightClassUtils.kt @@ -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) } } diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt index cd4fb1772f1..ed58a6588f2 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/asJava/firLightUtils.kt @@ -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) diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt index 5bb0135b9ce..1bf05a63ae6 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/frontend/api/fir/components/KtFirTypeProvider.kt @@ -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( diff --git a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt index 48c020c1936..479a71a5696 100644 --- a/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt +++ b/idea/idea-frontend-fir/src/org/jetbrains/kotlin/idea/references/FirSimpleNameReference.kt @@ -18,14 +18,16 @@ internal class KtFirSimpleNameReference( expression: KtSimpleNameExpression ) : KtSimpleNameReference(expression), KtFirReference { - private fun KtAnalysisSession.fixUpAnnotationCallResolveToCtor(resultsToFix: Collection): Collection { - 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): Collection { + 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 { 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) } diff --git a/idea/testData/highlighter/NamedArguments.kt b/idea/testData/highlighter/NamedArguments.kt index ac55f360951..1cdf62e521c 100644 --- a/idea/testData/highlighter/NamedArguments.kt +++ b/idea/testData/highlighter/NamedArguments.kt @@ -5,6 +5,4 @@ fun foobar() { foo(1, p2 = "") -} - -// IGNORE_FIR \ No newline at end of file +} \ No newline at end of file