[FIR] Improve locations for DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED, DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL, DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE and other diagnostics, refactor

This commit is contained in:
Ivan Kochurkin
2021-05-11 21:12:38 +03:00
committed by TeamCityServer
parent 52c32d3d85
commit 598501aaf0
16 changed files with 49 additions and 56 deletions
@@ -159,9 +159,9 @@ object DIAGNOSTICS_LIST : DiagnosticList() {
} }
val DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS by error<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS by error<PsiElement>()
val DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS by error<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS by error<PsiElement>()
val DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED by error<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL by error<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error<PsiElement>() val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error<PsiElement>(PositioningStrategy.REFERENCED_NAME_BY_QUALIFIED)
} }
val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") { val EXPOSED_VISIBILITY by object : DiagnosticGroup("Exposed visibility") {
@@ -165,9 +165,9 @@ object FirErrors {
val NEWER_VERSION_IN_SINCE_KOTLIN by warning1<KtExpression, String>() val NEWER_VERSION_IN_SINCE_KOTLIN by warning1<KtExpression, String>()
val DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS by error0<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITH_UNORDERED_VERSIONS by error0<PsiElement>()
val DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS by error0<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS by error0<PsiElement>()
val DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED by error0<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL by error0<PsiElement>() val DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error0<PsiElement>() val DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE by error0<PsiElement>(SourceElementPositioningStrategies.REFERENCED_NAME_BY_QUALIFIED)
// Exposed visibility // Exposed visibility
val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME) val EXPOSED_TYPEALIAS_EXPANDED_TYPE by error3<KtNamedDeclaration, EffectiveVisibility, FirMemberDeclaration, EffectiveVisibility>(SourceElementPositioningStrategies.DECLARATION_NAME)
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.fir.expressions.FirAnnotationCall
import org.jetbrains.kotlin.fir.expressions.argumentMapping import org.jetbrains.kotlin.fir.expressions.argumentMapping
import org.jetbrains.kotlin.fir.resolve.fqName import org.jetbrains.kotlin.fir.resolve.fqName
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.StandardClassIds
object FirAnnotationChecker : FirAnnotatedDeclarationChecker() { object FirAnnotationChecker : FirAnnotatedDeclarationChecker() {
private val deprecatedClassId = FqName("kotlin.Deprecated") private val deprecatedClassId = FqName("kotlin.Deprecated")
@@ -40,33 +41,27 @@ object FirAnnotationChecker : FirAnnotatedDeclarationChecker() {
if (deprecatedSinceKotlinCall != null) { if (deprecatedSinceKotlinCall != null) {
val closestFirFile = context.findClosest<FirFile>() val closestFirFile = context.findClosest<FirFile>()
if (closestFirFile != null) { if (closestFirFile != null && !closestFirFile.packageFqName.startsWith(StandardClassIds.BASE_KOTLIN_PACKAGE.shortName())) {
val packageName = closestFirFile.packageFqName.asString() reporter.reportOn(
if (packageName != "kotlin" && !packageName.startsWith("kotlin.")) { deprecatedSinceKotlinCall.source,
reporter.reportOn( FirErrors.DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE,
deprecatedSinceKotlinCall.source, context
FirErrors.DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE, )
context
)
}
} }
if (deprecatedCall == null) { if (deprecatedCall == null) {
reporter.reportOn(deprecatedSinceKotlinCall.source, FirErrors.DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED, context) reporter.reportOn(deprecatedSinceKotlinCall.source, FirErrors.DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED, context)
} else { } else {
val argumentMapping = deprecatedCall.argumentMapping ?: return val argumentMapping = deprecatedCall.argumentMapping ?: return
var report = false for (value in argumentMapping.values) {
for ((_, value) in argumentMapping) { if (value.name.identifier == "level") {
report = value.name.identifier == "level" reporter.reportOn(
if (report) deprecatedSinceKotlinCall.source,
FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL,
context
)
break break
} }
if (report) {
reporter.reportOn(
deprecatedSinceKotlinCall.source,
FirErrors.DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL,
context
)
} }
} }
} }
@@ -501,6 +501,15 @@ object LightTreePositioningStrategies {
if (node.tokenType == KtNodeTypes.PROPERTY_DELEGATE) { if (node.tokenType == KtNodeTypes.PROPERTY_DELEGATE) {
return markElement(tree.findExpressionDeep(node) ?: node, startOffset, endOffset, tree, node) return markElement(tree.findExpressionDeep(node) ?: node, startOffset, endOffset, tree, node)
} }
if (node.tokenType == KtNodeTypes.ANNOTATION_ENTRY) {
return markElement(
tree.findDescendantByType(node, KtNodeTypes.CONSTRUCTOR_CALLEE) ?: node,
startOffset,
endOffset,
tree,
node
)
}
if (node.tokenType in nodeTypesWithOperation) { if (node.tokenType in nodeTypesWithOperation) {
return markElement(tree.operationReference(node) ?: node, startOffset, endOffset, tree, node) return markElement(tree.operationReference(node) ?: node, startOffset, endOffset, tree, node)
} }
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.analysis.checkers.syntax.FirAnonymousFunctionSyn
object CommonExpressionCheckers : ExpressionCheckers() { object CommonExpressionCheckers : ExpressionCheckers() {
override val annotationCallCheckers: Set<FirAnnotationCallChecker> override val annotationCallCheckers: Set<FirAnnotationCallChecker>
get() = setOf( get() = setOf(
FirAnnotationArgumentChecker FirAnnotationArgumentChecker,
) )
override val basicExpressionCheckers: Set<FirBasicExpressionChecker> override val basicExpressionCheckers: Set<FirBasicExpressionChecker>
@@ -101,4 +101,4 @@ class NullForNotNullType(
class ManyLambdaExpressionArguments( class ManyLambdaExpressionArguments(
val argument: FirExpression val argument: FirExpression
) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR) ) : ResolutionDiagnostic(INAPPLICABLE_ARGUMENTS_MAPPING_ERROR)
@@ -9,7 +9,9 @@ import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.fir.FirSymbolOwner import org.jetbrains.kotlin.fir.FirSymbolOwner
import org.jetbrains.kotlin.fir.FirVisibilityChecker import org.jetbrains.kotlin.fir.FirVisibilityChecker
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.* import org.jetbrains.kotlin.fir.expressions.FirExpression
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.expressions.FirResolvedQualifier
import org.jetbrains.kotlin.fir.references.FirSuperReference import org.jetbrains.kotlin.fir.references.FirSuperReference
import org.jetbrains.kotlin.fir.resolve.inference.* import org.jetbrains.kotlin.fir.resolve.inference.*
import org.jetbrains.kotlin.fir.resolve.toSymbol import org.jetbrains.kotlin.fir.resolve.toSymbol
@@ -20,7 +22,6 @@ import org.jetbrains.kotlin.fir.symbols.impl.FirRegularClassSymbol
import org.jetbrains.kotlin.fir.typeContext import org.jetbrains.kotlin.fir.typeContext
import org.jetbrains.kotlin.fir.types.* import org.jetbrains.kotlin.fir.types.*
import org.jetbrains.kotlin.fir.visibilityChecker import org.jetbrains.kotlin.fir.visibilityChecker
import org.jetbrains.kotlin.name.CallableId
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -143,7 +144,6 @@ internal object CheckArguments : CheckerStage() {
override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) { override suspend fun check(candidate: Candidate, callInfo: CallInfo, sink: CheckerSink, context: ResolutionContext) {
val argumentMapping = val argumentMapping =
candidate.argumentMapping ?: error("Argument should be already mapped while checking arguments!") candidate.argumentMapping ?: error("Argument should be already mapped while checking arguments!")
for (argument in callInfo.arguments) { for (argument in callInfo.arguments) {
val parameter = argumentMapping[argument] val parameter = argumentMapping[argument]
candidate.resolveArgument( candidate.resolveArgument(
@@ -155,17 +155,10 @@ internal object CheckArguments : CheckerStage() {
context = context context = context
) )
} }
if (candidate.system.hasContradiction && callInfo.arguments.isNotEmpty()) { if (candidate.system.hasContradiction && callInfo.arguments.isNotEmpty()) {
sink.yieldDiagnostic(InapplicableCandidate) sink.yieldDiagnostic(InapplicableCandidate)
} }
} }
private val deprecatedSinceKotlin = CallableId(
FqName("kotlin"),
FqName("DeprecatedSinceKotlin"),
Name.identifier("DeprecatedSinceKotlin")
)
} }
internal object EagerResolveOfCallableReferences : CheckerStage() { internal object EagerResolveOfCallableReferences : CheckerStage() {
@@ -885,6 +885,7 @@ object PositioningStrategies {
is KtSuperTypeCallEntry -> element.calleeExpression is KtSuperTypeCallEntry -> element.calleeExpression
is KtOperationExpression -> element.operationReference is KtOperationExpression -> element.operationReference
is KtWhenConditionInRange -> element.operationReference is KtWhenConditionInRange -> element.operationReference
is KtAnnotationEntry -> element.calleeExpression ?: element
else -> element else -> element
} }
while (locateReferencedName && result is KtParenthesizedExpression) { while (locateReferencedName && result is KtParenthesizedExpression) {
@@ -1,4 +1,3 @@
// FIR_IDENTICAL
@file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE") @file:Suppress("INVISIBLE_MEMBER", "INVISIBLE_REFERENCE")
package test package test
@@ -5,23 +5,23 @@ package kotlin.sub
@DeprecatedSinceKotlin(warningSince = "1.0", errorSince = "1.1", hiddenSince = "1.2") @DeprecatedSinceKotlin(warningSince = "1.0", errorSince = "1.1", hiddenSince = "1.2")
fun good() {} fun good() {}
<!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS, DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED!>@DeprecatedSinceKotlin()<!> <!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS!>@<!DEPRECATED_SINCE_KOTLIN_WITHOUT_DEPRECATED!>DeprecatedSinceKotlin<!>()<!>
class Clazz class Clazz
@Deprecated("", level = DeprecationLevel.WARNING) @Deprecated("", level = DeprecationLevel.WARNING)
<!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS, DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>@DeprecatedSinceKotlin()<!> <!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS!>@<!DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>DeprecatedSinceKotlin<!>()<!>
fun fooWarning() {} fun fooWarning() {}
@Deprecated("", ReplaceWith(""), DeprecationLevel.WARNING) @Deprecated("", ReplaceWith(""), DeprecationLevel.WARNING)
<!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS, DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>@DeprecatedSinceKotlin()<!> <!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS!>@<!DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>DeprecatedSinceKotlin<!>()<!>
fun fooDefaultWarning() {} fun fooDefaultWarning() {}
@Deprecated("", level = DeprecationLevel.ERROR) @Deprecated("", level = DeprecationLevel.ERROR)
<!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS, DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>@DeprecatedSinceKotlin()<!> <!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS!>@<!DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>DeprecatedSinceKotlin<!>()<!>
fun fooError() {} fun fooError() {}
@Deprecated("", level = DeprecationLevel.HIDDEN) @Deprecated("", level = DeprecationLevel.HIDDEN)
<!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS, DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>@DeprecatedSinceKotlin()<!> <!DEPRECATED_SINCE_KOTLIN_WITHOUT_ARGUMENTS!>@<!DEPRECATED_SINCE_KOTLIN_WITH_DEPRECATED_LEVEL!>DeprecatedSinceKotlin<!>()<!>
fun fooHidden() {} fun fooHidden() {}
@Deprecated("") @Deprecated("")
@@ -1,5 +0,0 @@
package foo.bar
@Deprecated("")
<!DEPRECATED_SINCE_KOTLIN_OUTSIDE_KOTLIN_SUBPACKAGE!>@DeprecatedSinceKotlin("1.3")<!>
fun test() {}
@@ -1,3 +1,4 @@
// FIR_IDENTICAL
package foo.bar package foo.bar
@Deprecated("") @Deprecated("")
@@ -1,7 +1,7 @@
// !CHECK_TYPE // !CHECK_TYPE
<!INVISIBLE_REFERENCE!>@kotlin.internal.InlineOnly<!> @<!INVISIBLE_REFERENCE!>kotlin.internal.InlineOnly<!>
public inline fun <C, R> C.ifEmpty(f: () -> R): R where C : Collection<*>, C : R = if (isEmpty()) f() else this public inline fun <C, R> C.ifEmpty(f: () -> R): R where C : Collection<*>, C : R = if (isEmpty()) f() else this
public fun <T> listOf(t: T): List<T> = TODO() public fun <T> listOf(t: T): List<T> = TODO()
@@ -17,11 +17,11 @@ class C1
// FILE: 2.kt // FILE: 2.kt
package pp package pp
<!INVISIBLE_REFERENCE!>@A(<!INVISIBLE_REFERENCE!>foo<!>)<!> @<!INVISIBLE_REFERENCE!>A<!>(<!INVISIBLE_REFERENCE!>foo<!>)
fun f2() {} fun f2() {}
<!INVISIBLE_REFERENCE!>@A(<!INVISIBLE_REFERENCE!>foo<!>)<!> @<!INVISIBLE_REFERENCE!>A<!>(<!INVISIBLE_REFERENCE!>foo<!>)
val p2 = "" val p2 = ""
<!INVISIBLE_REFERENCE!>@A(<!INVISIBLE_REFERENCE!>foo<!>)<!> @<!INVISIBLE_REFERENCE!>A<!>(<!INVISIBLE_REFERENCE!>foo<!>)
class C2 class C2
@@ -25,6 +25,6 @@ public @interface A {
@A fun test8() {} @A fun test8() {}
<!INAPPLICABLE_CANDIDATE!>@A(x = Any::class, *arrayOf("5", "6"), "7", y = 3)<!> fun test9() {} @<!INAPPLICABLE_CANDIDATE!>A<!>(x = Any::class, *arrayOf("5", "6"), "7", y = 3) fun test9() {}
<!INAPPLICABLE_CANDIDATE!>@A(x = Any::class, value = ["5", "6"], "7", y = 3)<!> fun test10() {} @<!INAPPLICABLE_CANDIDATE!>A<!>(x = Any::class, value = ["5", "6"], "7", y = 3) fun test10() {}
@A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {} @A(x = Any::class, value = ["5", "6", "7"], y = 3) fun test11() {}
@@ -2,5 +2,5 @@
package a.b package a.b
<error descr="[INVISIBLE_REFERENCE] Symbol kotlin/internal/InlineOnly.InlineOnly is invisible">@kotlin.internal.InlineOnly</error> @<error descr="[INVISIBLE_REFERENCE] Symbol kotlin/internal/InlineOnly.InlineOnly is invisible">kotlin.internal.InlineOnly</error>
inline fun foo() {} inline fun foo() {}