Compile actual and expected declarations together
#KT-20840 fixed
This commit is contained in:
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.descriptors.PackagePartProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
|
||||
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
|
||||
import org.jetbrains.kotlin.frontend.di.configureModule
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.load.kotlin.MetadataFinderFactory
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
@@ -142,6 +143,7 @@ object CommonAnalyzerFacade : AnalyzerFacade() {
|
||||
|
||||
useInstance(moduleContentScope)
|
||||
useInstance(LookupTracker.DO_NOTHING)
|
||||
useInstance(ExpectActualTracker.DoNothing)
|
||||
useImpl<ResolveSession>()
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
useInstance(languageVersionSettings)
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.config
|
||||
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
|
||||
object CommonConfigurationKeys {
|
||||
@@ -33,6 +34,9 @@ object CommonConfigurationKeys {
|
||||
|
||||
@JvmField
|
||||
val LOOKUP_TRACKER = CompilerConfigurationKey.create<LookupTracker>("lookup tracker")
|
||||
|
||||
@JvmField
|
||||
val EXPECT_ACTUAL_TRACKER = CompilerConfigurationKey.create<ExpectActualTracker>("expect actual tracker")
|
||||
}
|
||||
|
||||
var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.container.useImpl
|
||||
import org.jetbrains.kotlin.container.useInstance
|
||||
import org.jetbrains.kotlin.context.ModuleContext
|
||||
import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
@@ -127,6 +128,7 @@ fun createContainerForLazyLocalClassifierAnalyzer(
|
||||
|
||||
useInstance(localClassDescriptorHolder)
|
||||
useInstance(lookupTracker)
|
||||
useInstance(ExpectActualTracker.DoNothing)
|
||||
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
|
||||
|
||||
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings;
|
||||
import org.jetbrains.kotlin.descriptors.*;
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1;
|
||||
import org.jetbrains.kotlin.extensions.DeclarationAttributeAltererExtension;
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker;
|
||||
import org.jetbrains.kotlin.lexer.KtKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken;
|
||||
import org.jetbrains.kotlin.lexer.KtTokens;
|
||||
@@ -280,7 +281,7 @@ public class ModifiersChecker {
|
||||
@NotNull DeclarationDescriptor descriptor
|
||||
) {
|
||||
for (DeclarationChecker checker : declarationCheckers) {
|
||||
checker.check(declaration, descriptor, trace, trace.getBindingContext(), languageVersionSettings);
|
||||
checker.check(declaration, descriptor, trace, trace.getBindingContext(), languageVersionSettings, expectActualTracker);
|
||||
}
|
||||
OperatorModifierChecker.INSTANCE.check(declaration, descriptor, trace, languageVersionSettings);
|
||||
PublishedApiUsageChecker.INSTANCE.check(declaration, descriptor, trace);
|
||||
@@ -304,14 +305,19 @@ public class ModifiersChecker {
|
||||
@NotNull
|
||||
private final LanguageVersionSettings languageVersionSettings;
|
||||
|
||||
@NotNull
|
||||
private final ExpectActualTracker expectActualTracker;
|
||||
|
||||
public ModifiersChecker(
|
||||
@NotNull AnnotationChecker annotationChecker,
|
||||
@NotNull Iterable<DeclarationChecker> declarationCheckers,
|
||||
@NotNull LanguageVersionSettings languageVersionSettings
|
||||
@NotNull LanguageVersionSettings languageVersionSettings,
|
||||
@NotNull ExpectActualTracker expectActualTracker
|
||||
) {
|
||||
this.annotationChecker = annotationChecker;
|
||||
this.declarationCheckers = declarationCheckers;
|
||||
this.languageVersionSettings = languageVersionSettings;
|
||||
this.expectActualTracker = expectActualTracker;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
|
||||
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.resolve.checkers
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -29,7 +30,8 @@ interface DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
)
|
||||
}
|
||||
|
||||
@@ -38,7 +40,9 @@ interface SimpleDeclarationChecker : DeclarationChecker {
|
||||
declaration: KtDeclaration,
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext, languageVersionSettings: LanguageVersionSettings
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) = check(declaration, descriptor, diagnosticHolder, bindingContext)
|
||||
|
||||
fun check(
|
||||
|
||||
@@ -23,6 +23,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors.DELEGATED_MEMBER_HIDES_SUPERTYPE_OVERRIDE
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtDelegatedSuperTypeEntry
|
||||
@@ -37,7 +38,8 @@ class DelegationChecker : DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
if (descriptor !is ClassDescriptor) return
|
||||
if (declaration !is KtClassOrObject) return
|
||||
|
||||
+34
-3
@@ -16,6 +16,7 @@
|
||||
|
||||
package org.jetbrains.kotlin.resolve.checkers
|
||||
|
||||
import com.intellij.openapi.vfs.VfsUtilCore
|
||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.config.AnalysisFlag
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
@@ -23,6 +24,7 @@ import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtConstructor
|
||||
@@ -40,6 +42,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module
|
||||
import org.jetbrains.kotlin.resolve.scopes.DescriptorKindFilter
|
||||
import org.jetbrains.kotlin.resolve.scopes.MemberScope
|
||||
import org.jetbrains.kotlin.resolve.scopes.getDescriptorsFiltered
|
||||
import org.jetbrains.kotlin.resolve.source.PsiSourceFile
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeConstructor
|
||||
import org.jetbrains.kotlin.types.TypeConstructorSubstitution
|
||||
@@ -48,7 +51,9 @@ import org.jetbrains.kotlin.types.checker.NewKotlinTypeChecker
|
||||
import org.jetbrains.kotlin.types.checker.TypeCheckerContext
|
||||
import org.jetbrains.kotlin.types.typeUtil.asTypeProjection
|
||||
import org.jetbrains.kotlin.utils.SmartList
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
import org.jetbrains.kotlin.utils.keysToMap
|
||||
import java.io.File
|
||||
|
||||
object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
override fun check(
|
||||
@@ -56,7 +61,8 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
if (!languageVersionSettings.supportsFeature(LanguageFeature.MultiPlatformProjects)) return
|
||||
|
||||
@@ -64,7 +70,7 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
if (descriptor !is MemberDescriptor || DescriptorUtils.isEnumEntry(descriptor)) return
|
||||
|
||||
if (descriptor.isExpect) {
|
||||
checkExpectedDeclarationHasActual(declaration, descriptor, diagnosticHolder, descriptor.module)
|
||||
checkExpectedDeclarationHasActual(declaration, descriptor, diagnosticHolder, descriptor.module, expectActualTracker)
|
||||
}
|
||||
else {
|
||||
val checkActual = !languageVersionSettings.getFlag(AnalysisFlag.multiPlatformDoNotCheckActual)
|
||||
@@ -76,7 +82,8 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
reportOn: KtNamedDeclaration,
|
||||
descriptor: MemberDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
platformModule: ModuleDescriptor
|
||||
platformModule: ModuleDescriptor,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
// Only look for top level actual members; class members will be handled as a part of that expected class
|
||||
if (descriptor.containingDeclaration !is PackageFragmentDescriptor) return
|
||||
@@ -96,8 +103,32 @@ object ExpectedActualDeclarationChecker : DeclarationChecker {
|
||||
val incompatibility = compatibility as Map<Incompatible, Collection<MemberDescriptor>>
|
||||
diagnosticHolder.report(Errors.NO_ACTUAL_FOR_EXPECT.on(reportOn, descriptor, platformModule, incompatibility))
|
||||
}
|
||||
else {
|
||||
val actualMembers = compatibility.asSequence()
|
||||
.filter { (compatibility, _) ->
|
||||
compatibility is Compatible || (compatibility is Incompatible && compatibility.kind != Compatibility.IncompatibilityKind.STRONG)
|
||||
}.flatMap { it.value.asSequence() }
|
||||
|
||||
expectActualTracker?.reportExpectActual(expected = descriptor, actualMembers = actualMembers)
|
||||
}
|
||||
}
|
||||
|
||||
private fun ExpectActualTracker.reportExpectActual(expected: MemberDescriptor, actualMembers: Sequence<MemberDescriptor>) {
|
||||
if (this is ExpectActualTracker.DoNothing) return
|
||||
|
||||
val expectedFile = sourceFile(expected) ?: return
|
||||
for (actual in actualMembers) {
|
||||
val actualFile = sourceFile(actual) ?: continue
|
||||
report(expectedFile = expectedFile, actualFile = actualFile)
|
||||
}
|
||||
}
|
||||
|
||||
private fun sourceFile(descriptor: MemberDescriptor): File? =
|
||||
descriptor.source
|
||||
.containingFile
|
||||
.safeAs<PsiSourceFile>()
|
||||
?.run { VfsUtilCore.virtualToIoFile(psiFile.virtualFile) }
|
||||
|
||||
fun Map<out Compatibility, Collection<MemberDescriptor>>.allStrongIncompatibilities(): Boolean =
|
||||
this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG }
|
||||
|
||||
|
||||
+3
-1
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
@@ -37,7 +38,8 @@ abstract class KotlinVersionStringAnnotationValueChecker(
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
val annotation = descriptor.annotations.findAnnotation(annotationFqName) ?: return
|
||||
val version = annotation.allValueArguments.values.singleOrNull()?.value as? String ?: return
|
||||
|
||||
@@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.VariableDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.FunctionExpressionDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.DiagnosticSink
|
||||
import org.jetbrains.kotlin.diagnostics.Errors
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
@@ -61,7 +62,8 @@ object UnderscoreChecker : DeclarationChecker {
|
||||
descriptor: DeclarationDescriptor,
|
||||
diagnosticHolder: DiagnosticSink,
|
||||
bindingContext: BindingContext,
|
||||
languageVersionSettings: LanguageVersionSettings
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
expectActualTracker: ExpectActualTracker
|
||||
) {
|
||||
if (declaration is KtProperty && descriptor !is VariableDescriptor) return
|
||||
if (declaration is KtCallableDeclaration) {
|
||||
|
||||
Reference in New Issue
Block a user