[FE, IR] Store PsiElement for mismatched annotation's actual target
There is IDE quick fix which suggests to copy mismatched annotation from `expect` to `actual` (see KTIJ-26633). It needs to find `actual` PsiElement where to add annotation. Before previous commit, it was easy - just get source of `Incompatibility.actualSymbol`. After previous commit, the problem might be in value parameter, while `actualSymbol` would contain function symbol. This is solved by adding new field `Incompatibility.actualAnnotationTargetElement`. `SourceElementMarker` introduced, because it's needed to be used in abstract checker. Existing `DeclarationSymbolMarker` doesn't fit because in next PR for this issue annotations set on types will be reported, and types are not declarations. ^KT-60671
This commit is contained in:
committed by
Space Team
parent
5c95f69aef
commit
420dceb7d8
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.calls.tower.CandidateApplicability;
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.WrongResolutionToClassifier;
|
||||
import org.jetbrains.kotlin.resolve.calls.util.BuilderLambdaLabelingInfo;
|
||||
import org.jetbrains.kotlin.resolve.deprecation.DescriptorBasedDeprecationInfo;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ClassicSourceElement;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualAnnotationsIncompatibilityType;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualCompatibility.Incompatible;
|
||||
import org.jetbrains.kotlin.resolve.multiplatform.ExpectActualMemberDiff;
|
||||
@@ -42,10 +43,7 @@ import org.jetbrains.kotlin.types.KotlinType;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Modifier;
|
||||
import java.util.Collection;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.*;
|
||||
|
||||
import static org.jetbrains.kotlin.diagnostics.ClassicPositioningStrategies.ACTUAL_DECLARATION_NAME;
|
||||
import static org.jetbrains.kotlin.diagnostics.ClassicPositioningStrategies.INCOMPATIBLE_DECLARATION;
|
||||
@@ -875,9 +873,9 @@ public interface Errors {
|
||||
DiagnosticFactory0<KtNamedDeclaration> EXPECT_ACTUAL_OPT_IN_ANNOTATION = DiagnosticFactory0.create(ERROR, EXPECT_ACTUAL_MODIFIER);
|
||||
DiagnosticFactory1<KtTypeAlias, ClassId> ACTUAL_TYPEALIAS_TO_SPECIAL_ANNOTATION =
|
||||
DiagnosticFactory1.create(ERROR, TYPEALIAS_TYPE_REFERENCE);
|
||||
DiagnosticFactory3<KtNamedDeclaration, DeclarationDescriptor, DeclarationDescriptor,
|
||||
DiagnosticFactory4<KtNamedDeclaration, DeclarationDescriptor, DeclarationDescriptor, Optional<SourceElement>,
|
||||
ExpectActualAnnotationsIncompatibilityType<AnnotationDescriptor>> ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT =
|
||||
DiagnosticFactory3.create(WARNING, DECLARATION_NAME_ONLY);
|
||||
DiagnosticFactory4.create(WARNING, DECLARATION_NAME_ONLY);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
+2
-1
@@ -444,10 +444,11 @@ public class DefaultErrorMessages {
|
||||
"`actual typealias` to annotation which affects code compilation can lead to incorrect behavior. Instead, use ''{0}'' annotation directly.",
|
||||
TO_STRING);
|
||||
MAP.put(ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT,
|
||||
"{2}.\n" +
|
||||
"{3}.\n" +
|
||||
"All annotations from expect `{0}` must be present with the same arguments on actual `{1}`, otherwise they might behave incorrectly.",
|
||||
ExpectActualAnnotationIncompatibilityDiagnosticRenderers.DESCRIPTOR_RENDERER,
|
||||
ExpectActualAnnotationIncompatibilityDiagnosticRenderers.DESCRIPTOR_RENDERER,
|
||||
NOT_RENDERED,
|
||||
ExpectActualAnnotationIncompatibilityDiagnosticRenderers.INCOMPATIBILITY);
|
||||
|
||||
MAP.put(PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT, "Projections are not allowed on type arguments of functions and properties");
|
||||
|
||||
@@ -69,6 +69,9 @@ object Renderers {
|
||||
element.toString()
|
||||
}
|
||||
|
||||
@JvmField
|
||||
val NOT_RENDERED = Renderer<Any?> { _ -> "" }
|
||||
|
||||
@JvmField
|
||||
val NAME = Renderer<Named> { it.name.asString() }
|
||||
|
||||
|
||||
+3
@@ -41,6 +41,7 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import java.io.File
|
||||
import java.util.*
|
||||
|
||||
private val implicitlyActualizedAnnotationFqn = StandardClassIds.Annotations.ImplicitlyActualizedByJvmDeclaration.asSingleFqName()
|
||||
|
||||
@@ -514,11 +515,13 @@ class ExpectedActualDeclarationChecker(
|
||||
val matchingContext = ClassicExpectActualMatchingContext(actualDescriptor.module)
|
||||
val incompatibility =
|
||||
AbstractExpectActualAnnotationMatchChecker.areAnnotationsCompatible(expectDescriptor, actualDescriptor, matchingContext) ?: return
|
||||
val actualAnnotationTargetSourceElement = (incompatibility.actualAnnotationTargetElement as ClassicSourceElement).element
|
||||
context.trace.report(
|
||||
Errors.ACTUAL_ANNOTATIONS_NOT_MATCH_EXPECT.on(
|
||||
reportOn,
|
||||
incompatibility.expectSymbol as DeclarationDescriptor,
|
||||
incompatibility.actualSymbol as DeclarationDescriptor,
|
||||
Optional.ofNullable(actualAnnotationTargetSourceElement),
|
||||
incompatibility.type.mapAnnotationType { it.annotationSymbol as AnnotationDescriptor }
|
||||
)
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user