From fec2d08d226df3187b6030c94edf67b310018733 Mon Sep 17 00:00:00 2001 From: Alexey Tsvetkov Date: Fri, 1 Dec 2017 16:07:40 +0300 Subject: [PATCH] Compile actual and expected declarations together #KT-20840 fixed --- .../jetbrains/kotlin/cli/js/K2JSCompiler.java | 6 ++ .../jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt | 5 ++ .../compiler/TopDownAnalyzerFacadeForJVM.kt | 6 +- .../kotlin/frontend/java/di/injection.kt | 11 ++- .../kotlin/resolve/jvm/JvmAnalyzerFacade.kt | 2 + .../analyzer/common/CommonAnalyzerFacade.kt | 2 + .../kotlin/config/CommonConfigurationKeys.kt | 4 + .../jetbrains/kotlin/frontend/di/injection.kt | 2 + .../kotlin/resolve/ModifiersChecker.java | 10 ++- .../resolve/checkers/DeclarationChecker.kt | 8 +- .../resolve/checkers/DelegationChecker.kt | 4 +- .../ExpectedActualDeclarationChecker.kt | 37 ++++++++- ...tlinVersionStringAnnotationValueChecker.kt | 4 +- .../resolve/checkers/UnderscoreChecker.kt | 4 +- .../incremental/ExpectActualTrackerImpl.kt | 31 +++++++ .../incremental/IncrementalCompilerRunner.kt | 9 ++- .../IncrementalJsCompilerRunner.kt | 4 +- .../IncrementalJvmCompilerRunner.kt | 4 +- .../kotlin/incremental/InputsCache.kt | 81 +++++++++++++------ ...mentalMultiplatformJsCompilerRunnerTest.kt | 29 +++++++ ...entalMultiplatformJvmCompilerRunnerTest.kt | 28 +++++++ ...platformJsCompilerRunnerTestGenerated.java | 50 ++++++++++++ ...latformJvmCompilerRunnerTestGenerated.java | 50 ++++++++++++ .../checkers/AbstractDiagnosticsTest.kt | 2 + .../components/ExpectActualTracker.kt | 30 +++++++ .../kotlin/generators/tests/GenerateTests.kt | 9 +++ .../lightClasses/IDELightClassContexts.kt | 2 + .../highlighter/PlatformExpectedAnnotator.kt | 4 +- .../multiplatform/touchActual/X.kt | 3 + .../multiplatform/touchActual/X.kt.touch.1 | 0 .../multiplatform/touchActual/Y.kt | 3 + .../multiplatform/touchActual/Z.kt | 3 + .../multiplatform/touchActual/build.log | 19 +++++ .../multiplatform/touchActual/commonX.kt | 5 ++ .../multiplatform/touchActual/commonY.kt | 5 ++ .../multiplatform/touchActual/commonZ.kt | 5 ++ .../multiplatform/touchActual/dummy.kt | 1 + .../multiplatform/touchActual/useX.kt | 3 + .../multiplatform/touchActual/useYZ.kt | 7 ++ .../touchActual/useYZ.kt.touch.2 | 0 .../multiplatform/touchExpect/X.kt | 3 + .../multiplatform/touchExpect/Y.kt | 3 + .../multiplatform/touchExpect/Z.kt | 3 + .../multiplatform/touchExpect/build.log | 19 +++++ .../multiplatform/touchExpect/commonX.kt | 5 ++ .../touchExpect/commonX.kt.touch.1 | 0 .../multiplatform/touchExpect/commonY.kt | 5 ++ .../touchExpect/commonY.kt.touch.2 | 0 .../multiplatform/touchExpect/commonZ.kt | 5 ++ .../multiplatform/touchExpect/dummy.kt | 1 + .../multiplatform/touchExpect/useX.kt | 3 + .../touchExpect/useXIncompatible.kt | 2 + .../multiplatform/touchExpect/useYZ.kt | 7 ++ .../kotlin/frontend/js/di/injection.kt | 3 + .../js/analyze/TopDownAnalyzerFacadeForJS.kt | 3 + .../diagnostic/CliNoArgDeclarationChecker.kt | 4 +- 56 files changed, 515 insertions(+), 43 deletions(-) create mode 100644 compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt create mode 100644 compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJsCompilerRunnerTest.kt create mode 100644 compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJvmCompilerRunnerTest.kt create mode 100644 compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java create mode 100644 compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java create mode 100644 core/descriptors/src/org/jetbrains/kotlin/incremental/components/ExpectActualTracker.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/X.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/X.kt.touch.1 create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/Y.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/Z.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/build.log create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/commonX.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/commonY.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/commonZ.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/dummy.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/useX.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt.touch.2 create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/X.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/Y.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/Z.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/build.log create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt.touch.1 create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt.touch.2 create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/commonZ.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/dummy.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/useX.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/useXIncompatible.kt create mode 100644 jps-plugin/testData/incremental/multiplatform/touchExpect/useYZ.kt diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java index a6bdfadf4a4..98a676f1796 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/js/K2JSCompiler.java @@ -45,6 +45,7 @@ import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser; import org.jetbrains.kotlin.config.*; +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker; import org.jetbrains.kotlin.incremental.components.LookupTracker; import org.jetbrains.kotlin.incremental.js.IncrementalDataProvider; import org.jetbrains.kotlin.incremental.js.IncrementalResultsConsumer; @@ -418,6 +419,11 @@ public class K2JSCompiler extends CLICompiler { configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, lookupTracker); } + ExpectActualTracker expectActualTracker = services.get(ExpectActualTracker.class); + if (expectActualTracker != null) { + configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, expectActualTracker); + } + String sourceMapEmbedContentString = arguments.getSourceMapEmbedSources(); SourceMapSourceEmbedding sourceMapContentEmbedding = sourceMapEmbedContentString != null ? sourceMapContentEmbeddingMap.get(sourceMapEmbedContentString) : diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt index 0cbe32b9e2f..2c54f902fa8 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/K2JVMCompiler.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.cli.jvm.plugins.PluginCliParser import org.jetbrains.kotlin.cli.jvm.repl.ReplFromTerminal import org.jetbrains.kotlin.codegen.CompilationException import org.jetbrains.kotlin.config.* +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.javac.JavacWrapper import org.jetbrains.kotlin.load.java.JavaClassesTracker @@ -300,6 +301,10 @@ class K2JVMCompiler : CLICompiler() { configuration.put(CommonConfigurationKeys.LOOKUP_TRACKER, it) } + services.get(ExpectActualTracker::class.java)?.let { + configuration.put(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER, it) + } + services.get(IncrementalCompilationComponents::class.java)?.let { configuration.put(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS, it) } diff --git a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt index 5bbcd5ed25c..684b5d7907c 100644 --- a/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt +++ b/compiler/cli/src/org/jetbrains/kotlin/cli/jvm/compiler/TopDownAnalyzerFacadeForJVM.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.descriptors.impl.ModuleDependenciesImpl import org.jetbrains.kotlin.frontend.java.di.createContainerForTopDownAnalyzerForJvm import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis import org.jetbrains.kotlin.frontend.java.di.initialize +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.javac.components.JavacBasedClassFinder import org.jetbrains.kotlin.javac.components.JavacBasedSourceElementFactory @@ -133,6 +134,7 @@ object TopDownAnalyzerFacadeForJVM { val incrementalComponents = configuration.get(JVMConfigurationKeys.INCREMENTAL_COMPILATION_COMPONENTS) val lookupTracker = configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING + val expectActualTracker = configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing val targetIds = configuration.get(JVMConfigurationKeys.MODULES)?.map(::TargetId) val separateModules = !configuration.getBoolean(JVMConfigurationKeys.USE_SINGLE_MODULE) @@ -171,7 +173,7 @@ object TopDownAnalyzerFacadeForJVM { val dependencyScope = GlobalSearchScope.notScope(sourceScope) val dependenciesContainer = createContainerForTopDownAnalyzerForJvm( - dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker, + dependenciesContext, trace, DeclarationProviderFactory.EMPTY, dependencyScope, lookupTracker, expectActualTracker, packagePartProvider(dependencyScope), moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder ) @@ -196,7 +198,7 @@ object TopDownAnalyzerFacadeForJVM { // to be stored in CliLightClassGenerationSupport, and it better be the source one (otherwise light classes would not be found) // TODO: get rid of duplicate invocation of CodeAnalyzerInitializer#initialize, or refactor CliLightClassGenerationSupport val container = createContainerForTopDownAnalyzerForJvm( - moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker, + moduleContext, trace, declarationProviderFactory(storageManager, files), sourceScope, lookupTracker, expectActualTracker, partProvider, moduleClassResolver, jvmTarget, languageVersionSettings, configureJavaClassFinder, javaClassTracker = configuration[JVMConfigurationKeys.JAVA_CLASSES_TRACKER] ).apply { diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt index 8a138ef6a42..04bd41c35a1 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/frontend/java/di/injection.kt @@ -29,6 +29,7 @@ import org.jetbrains.kotlin.contracts.ContractDeserializerImpl import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PackagePartProvider 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.java.AbstractJavaClassFinder import org.jetbrains.kotlin.load.java.InternalFlexibleTypeTransformer @@ -49,10 +50,12 @@ import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory private fun StorageComponentContainer.configureJavaTopDownAnalysis( moduleContentScope: GlobalSearchScope, project: Project, - lookupTracker: LookupTracker + lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker ) { useInstance(moduleContentScope) useInstance(lookupTracker) + useInstance(expectActualTracker) useImpl() useImpl() @@ -79,6 +82,7 @@ fun createContainerForLazyResolveWithJava( moduleClassResolver: ModuleClassResolver, targetEnvironment: TargetEnvironment, lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker, packagePartProvider: PackagePartProvider, jvmTarget: JvmTarget, languageVersionSettings: LanguageVersionSettings, @@ -87,7 +91,7 @@ fun createContainerForLazyResolveWithJava( javaClassTracker: JavaClassesTracker? = null ): StorageComponentContainer = createContainer("LazyResolveWithJava", JvmPlatform) { configureModule(moduleContext, JvmPlatform, jvmTarget, bindingTrace) - configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker) + configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker, expectActualTracker) if (configureJavaClassFinder != null) { configureJavaClassFinder() @@ -127,6 +131,7 @@ fun createContainerForTopDownAnalyzerForJvm( declarationProviderFactory: DeclarationProviderFactory, moduleContentScope: GlobalSearchScope, lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker, packagePartProvider: PackagePartProvider, moduleClassResolver: ModuleClassResolver, jvmTarget: JvmTarget, @@ -135,7 +140,7 @@ fun createContainerForTopDownAnalyzerForJvm( javaClassTracker: JavaClassesTracker? = null ): ComponentProvider = createContainerForLazyResolveWithJava( moduleContext, bindingTrace, declarationProviderFactory, moduleContentScope, moduleClassResolver, - CompilerEnvironment, lookupTracker, packagePartProvider, jvmTarget, languageVersionSettings, + CompilerEnvironment, lookupTracker, expectActualTracker, packagePartProvider, jvmTarget, languageVersionSettings, useBuiltInsProvider = true, configureJavaClassFinder = configureJavaClassFinder, javaClassTracker = javaClassTracker diff --git a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt index d8af40f73c8..8be962d643d 100644 --- a/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt +++ b/compiler/frontend.java/src/org/jetbrains/kotlin/resolve/jvm/JvmAnalyzerFacade.kt @@ -25,6 +25,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.java.di.createContainerForLazyResolveWithJava +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl import org.jetbrains.kotlin.load.java.structure.JavaClass @@ -92,6 +93,7 @@ object JvmAnalyzerFacade : AnalyzerFacade() { moduleClassResolver, targetEnvironment, lookupTracker, + ExpectActualTracker.DoNothing, packagePartProvider, jvmTarget, languageVersionSettings, diff --git a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt index dfbfb950ca3..03d087945c5 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/analyzer/common/CommonAnalyzerFacade.kt @@ -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() useImpl() useInstance(languageVersionSettings) diff --git a/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt b/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt index 9567eb58f7c..27a6e068df6 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/config/CommonConfigurationKeys.kt @@ -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("lookup tracker") + + @JvmField + val EXPECT_ACTUAL_TRACKER = CompilerConfigurationKey.create("expect actual tracker") } var CompilerConfiguration.languageVersionSettings: LanguageVersionSettings diff --git a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt index e987c467531..c9b6b962013 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/frontend/di/injection.kt @@ -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() diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java index 55e86b86514..d77be07247e 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/ModifiersChecker.java @@ -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 declarationCheckers, - @NotNull LanguageVersionSettings languageVersionSettings + @NotNull LanguageVersionSettings languageVersionSettings, + @NotNull ExpectActualTracker expectActualTracker ) { this.annotationChecker = annotationChecker; this.declarationCheckers = declarationCheckers; this.languageVersionSettings = languageVersionSettings; + this.expectActualTracker = expectActualTracker; } @NotNull diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeclarationChecker.kt index 8677d6f7395..f9e623cc214 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DeclarationChecker.kt @@ -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( diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DelegationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DelegationChecker.kt index 1e2a540790e..693c6c69061 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DelegationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/DelegationChecker.kt @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt index e9e50139e13..f988083534a 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExpectedActualDeclarationChecker.kt @@ -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> 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) { + 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() + ?.run { VfsUtilCore.virtualToIoFile(psiFile.virtualFile) } + fun Map>.allStrongIncompatibilities(): Boolean = this.keys.all { it is Incompatible && it.kind == Compatibility.IncompatibilityKind.STRONG } diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/KotlinVersionStringAnnotationValueChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/KotlinVersionStringAnnotationValueChecker.kt index 994afbfe0df..121e571abeb 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/KotlinVersionStringAnnotationValueChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/KotlinVersionStringAnnotationValueChecker.kt @@ -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 diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/UnderscoreChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/UnderscoreChecker.kt index b0d3d6f7d79..3a12fb6fd72 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/UnderscoreChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/UnderscoreChecker.kt @@ -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) { diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt new file mode 100644 index 00000000000..2fe9360b836 --- /dev/null +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/ExpectActualTrackerImpl.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.incremental + +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker +import java.io.File + +internal class ExpectActualTrackerImpl : ExpectActualTracker { + private val expectToActual = hashMapOf>() + + val expectToActualMap: Map> + get() = expectToActual + + override fun report(expectedFile: File, actualFile: File) { + expectToActual.getOrPut(expectedFile) { hashSetOf() }.add(actualFile) + } +} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt index fb780110ff7..73476fb4bdd 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalCompilerRunner.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.compilerRunner.OutputItemsCollectorImpl import org.jetbrains.kotlin.compilerRunner.SimpleOutputItem import org.jetbrains.kotlin.compilerRunner.toGeneratedFile import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry @@ -153,11 +154,13 @@ abstract class IncrementalCompilerRunner< protected open fun makeServices( args: Args, lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker, caches: CacheManager, compilationMode: CompilationMode ): Services.Builder = Services.Builder().apply { register(LookupTracker::class.java, lookupTracker) + register(ExpectActualTracker::class.java, expectActualTracker) register(CompilationCanceledStatus::class.java, EmptyCompilationCanceledStatus) } @@ -191,10 +194,13 @@ abstract class IncrementalCompilerRunner< var exitCode = ExitCode.OK while (dirtySources.any() || runWithNoDirtyKotlinSources(caches)) { + val complementaryFiles = caches.inputsCache.clearComplementaryFilesMapping(dirtySources) + dirtySources.addAll(complementaryFiles) caches.platformCache.markDirty(dirtySources) caches.inputsCache.removeOutputForSourceFiles(dirtySources) val lookupTracker = LookupTrackerImpl(LookupTracker.DO_NOTHING) + val expectActualTracker = ExpectActualTrackerImpl() val (sourcesToCompile, removedKotlinSources) = dirtySources.partition(File::exists) // todo: more optimal to save only last iteration, but it will require adding standalone-ic specific logs @@ -203,7 +209,7 @@ abstract class IncrementalCompilerRunner< val text = allSourcesToCompile.joinToString(separator = System.getProperty("line.separator")) { it.canonicalPath } dirtySourcesSinceLastTimeFile.writeText(text) - val services = makeServices(args, lookupTracker, caches, compilationMode).build() + val services = makeServices(args, lookupTracker, expectActualTracker, caches, compilationMode).build() args.reportOutputFiles = true val outputItemsCollector = OutputItemsCollectorImpl() @@ -227,6 +233,7 @@ abstract class IncrementalCompilerRunner< } } + caches.inputsCache.registerComplementaryFiles(expectActualTracker) caches.inputsCache.registerOutputForSourceFiles(generatedFiles) caches.lookupCache.update(lookupTracker, sourcesToCompile, removedKotlinSources) val changesCollector = ChangesCollector() diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt index b40bd835f03..13b2c1c3911 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJsCompilerRunner.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.cli.js.K2JSCompiler import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.js.* import java.io.File @@ -97,10 +98,11 @@ class IncrementalJsCompilerRunner( override fun makeServices( args: K2JSCompilerArguments, lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker, caches: IncrementalJsCachesManager, compilationMode: CompilationMode ): Services.Builder = - super.makeServices(args, lookupTracker, caches, compilationMode).apply { + super.makeServices(args, lookupTracker, expectActualTracker, caches, compilationMode).apply { register(IncrementalResultsConsumer::class.java, IncrementalResultsConsumerImpl()) if (compilationMode is CompilationMode.Incremental) { diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt index 1cc4c5bed34..e02a12195cc 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/IncrementalJvmCompilerRunner.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.compilerRunner.ArgumentUtils import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.IncrementalCompilation import org.jetbrains.kotlin.config.Services +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.multiproject.ArtifactChangesProvider import org.jetbrains.kotlin.incremental.multiproject.ChangesRegistry @@ -401,10 +402,11 @@ class IncrementalJvmCompilerRunner( override fun makeServices( args: K2JVMCompilerArguments, lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker, caches: IncrementalJvmCachesManager, compilationMode: CompilationMode ): Services.Builder = - super.makeServices(args, lookupTracker, caches, compilationMode).apply { + super.makeServices(args, lookupTracker, expectActualTracker, caches, compilationMode).apply { val targetId = TargetId(args.moduleName!!, "java-production") val targetToCache = mapOf(targetId to caches.platformCache) val incrementalComponents = IncrementalCompilationComponentsImpl(targetToCache) diff --git a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt index d02c25fba6c..4656f3d6a34 100644 --- a/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt +++ b/compiler/incremental-compilation-impl/src/org/jetbrains/kotlin/incremental/InputsCache.kt @@ -23,20 +23,63 @@ import org.jetbrains.kotlin.incremental.storage.BasicMapsOwner import org.jetbrains.kotlin.incremental.storage.BasicStringMap import org.jetbrains.kotlin.incremental.storage.PathStringDescriptor import org.jetbrains.kotlin.incremental.storage.StringCollectionExternalizer -import org.jetbrains.kotlin.modules.TargetId import java.io.File +import java.util.* +import kotlin.collections.HashSet class InputsCache( workingDir: File, private val reporter: ICReporter ) : BasicMapsOwner(workingDir) { companion object { - private val SOURCE_TO_OUTPUT_FILES = "source-to-output" private val SOURCE_SNAPSHOTS = "source-snapshot" + private val SOURCE_TO_OUTPUT_FILES = "source-to-output" + private val COMPLEMENTARY_FILES = "complementary-files" } - internal val sourceToOutputMap = registerMap(SourceToOutputFilesMap(SOURCE_TO_OUTPUT_FILES.storageFile)) internal val sourceSnapshotMap = registerMap(FileSnapshotMap(SOURCE_SNAPSHOTS.storageFile)) + private val sourceToOutputMap = registerMap(FilesMap(SOURCE_TO_OUTPUT_FILES.storageFile)) + /** + * A file X is a complementary to a file Y if they contain corresponding expect/actual declarations. + * Complementary files should be compiled together during IC so the compiler does not complain + * about missing parts. + * TODO: provide a better solution (maintain an index of expect/actual declarations akin to IncrementalPackagePartProvider) + */ + private val complementaryFilesMap = registerMap(FilesMap(COMPLEMENTARY_FILES.storageFile)) + + fun clearComplementaryFilesMapping(dirtyFiles: Collection): Collection { + val complementaryFiles = HashSet() + val filesQueue = ArrayDeque(dirtyFiles) + while (filesQueue.isNotEmpty()) { + val file = filesQueue.pollFirst() + complementaryFilesMap.remove(file).filterTo(filesQueue) { complementaryFiles.add(it) } + } + complementaryFiles.removeAll(dirtyFiles) + return complementaryFiles + } + + internal fun registerComplementaryFiles(expectActualTracker: ExpectActualTrackerImpl) { + val actualToExpect = hashMapOf>() + for ((expect, actuals) in expectActualTracker.expectToActualMap) { + for (actual in actuals) { + actualToExpect.getOrPut(actual) { hashSetOf() }.add(expect) + } + complementaryFilesMap[expect] = actuals + } + + for ((actual, expects) in actualToExpect) { + complementaryFilesMap[actual] = expects + } + } + + fun removeOutputForSourceFiles(sources: Iterable) { + for (sourceFile in sources) { + sourceToOutputMap.remove(sourceFile).forEach { it -> + reporter.report { "Deleting $it on clearing cache for $sourceFile" } + it.delete() + } + } + } // generatedFiles can contain multiple entries with the same source file // for example Kapt3 IC will generate a .java stub and .class stub for each source file @@ -53,29 +96,21 @@ class InputsCache( sourceToOutputMap[source] = outputs } } +} - fun removeOutputForSourceFiles(sources: Iterable) { - sources.forEach { sourceToOutputMap.remove(it) } +private class FilesMap(storageFile: File) + : BasicStringMap>(storageFile, PathStringDescriptor, StringCollectionExternalizer) { + + operator fun set(sourceFile: File, outputFiles: Collection) { + storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath } } - inner class SourceToOutputFilesMap(storageFile: File) : BasicStringMap>(storageFile, PathStringDescriptor, StringCollectionExternalizer) { - operator fun set(sourceFile: File, outputFiles: Collection) { - storage[sourceFile.absolutePath] = outputFiles.map { it.absolutePath } - } + operator fun get(sourceFile: File): Collection = + storage[sourceFile.absolutePath].orEmpty().map(::File) - operator fun get(sourceFile: File): Collection = - storage[sourceFile.absolutePath].orEmpty().map(::File) + override fun dumpValue(value: Collection) = + value.dumpCollection() - override fun dumpValue(value: Collection) = value.dumpCollection() - - fun remove(file: File) { - // TODO: do it in the code that uses cache, since cache should not generally delete anything outside of it! - // but for a moment it is an easiest solution to implement - get(file).forEach { - reporter.report { "Deleting $it on clearing cache for $file" } - it.delete() - } - storage.remove(file.absolutePath) - } - } + fun remove(file: File): Collection = + get(file).also { storage.remove(file.absolutePath) } } \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJsCompilerRunnerTest.kt b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJsCompilerRunnerTest.kt new file mode 100644 index 00000000000..cc073396d09 --- /dev/null +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJsCompilerRunnerTest.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.incremental + +import org.jetbrains.kotlin.cli.common.arguments.K2JSCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import java.io.File + +abstract class AbstractIncrementalMultiplatformJsCompilerRunnerTest : AbstractIncrementalJsCompilerRunnerTest() { + override fun createCompilerArguments(destinationDir: File, testDir: File): K2JSCompilerArguments { + return super.createCompilerArguments(destinationDir, testDir).apply { + multiPlatform = true + } + } +} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJvmCompilerRunnerTest.kt b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJvmCompilerRunnerTest.kt new file mode 100644 index 00000000000..0423ea7fad7 --- /dev/null +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/AbstractIncrementalMultiplatformJvmCompilerRunnerTest.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.incremental + +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments +import java.io.File + +abstract class AbstractIncrementalMultiplatformJvmCompilerRunnerTest : AbstractIncrementalJvmCompilerRunnerTest() { + override fun createCompilerArguments(destinationDir: File, testDir: File): K2JVMCompilerArguments { + return super.createCompilerArguments(destinationDir, testDir).apply { + multiPlatform = true + } + } +} \ No newline at end of file diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java new file mode 100644 index 00000000000..e049b9fb9bc --- /dev/null +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJsCompilerRunnerTestGenerated.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.incremental; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("jps-plugin/testData/incremental/multiplatform") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class IncrementalMultiplatformJsCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJsCompilerRunnerTest { + public void testAllFilesPresentInMultiplatform() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + + @TestMetadata("touchActual") + public void testTouchActual() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchActual/"); + doTest(fileName); + } + + @TestMetadata("touchExpect") + public void testTouchExpect() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect/"); + doTest(fileName); + } +} diff --git a/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java new file mode 100644 index 00000000000..73feb3f3fbc --- /dev/null +++ b/compiler/incremental-compilation-impl/test/org/jetbrains/kotlin/incremental/IncrementalMultiplatformJvmCompilerRunnerTestGenerated.java @@ -0,0 +1,50 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.incremental; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TargetBackend; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("jps-plugin/testData/incremental/multiplatform") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class IncrementalMultiplatformJvmCompilerRunnerTestGenerated extends AbstractIncrementalMultiplatformJvmCompilerRunnerTest { + public void testAllFilesPresentInMultiplatform() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadata(this.getClass(), new File("jps-plugin/testData/incremental/multiplatform"), Pattern.compile("^([^\\.]+)$"), TargetBackend.ANY, true); + } + + @TestMetadata("touchActual") + public void testTouchActual() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchActual/"); + doTest(fileName); + } + + @TestMetadata("touchExpect") + public void testTouchExpect() throws Exception { + String fileName = KotlinTestUtils.navigationMetadata("jps-plugin/testData/incremental/multiplatform/touchExpect/"); + doTest(fileName); + } +} diff --git a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt index f8a1dcb0f4d..5199eb1fa14 100644 --- a/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt +++ b/compiler/tests-common/tests/org/jetbrains/kotlin/checkers/AbstractDiagnosticsTest.kt @@ -41,6 +41,7 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticUtils import org.jetbrains.kotlin.diagnostics.Errors.* import org.jetbrains.kotlin.frontend.java.di.createContainerForTopDownAnalyzerForJvm import org.jetbrains.kotlin.frontend.java.di.initJvmBuiltInsForTopDownAnalysis +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.load.java.lazy.SingleModuleClassResolver import org.jetbrains.kotlin.name.FqName @@ -322,6 +323,7 @@ abstract class AbstractDiagnosticsTest : BaseDiagnosticsTest() { FileBasedDeclarationProviderFactory(moduleContext.storageManager, files), moduleContentScope, LookupTracker.DO_NOTHING, + ExpectActualTracker.DoNothing, environment.createPackagePartProvider(moduleContentScope), moduleClassResolver, JvmTarget.JVM_1_6, diff --git a/core/descriptors/src/org/jetbrains/kotlin/incremental/components/ExpectActualTracker.kt b/core/descriptors/src/org/jetbrains/kotlin/incremental/components/ExpectActualTracker.kt new file mode 100644 index 00000000000..5b0564eab3d --- /dev/null +++ b/core/descriptors/src/org/jetbrains/kotlin/incremental/components/ExpectActualTracker.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2017 JetBrains s.r.o. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.jetbrains.kotlin.incremental.components + +import org.jetbrains.kotlin.container.DefaultImplementation +import java.io.File + +@DefaultImplementation(ExpectActualTracker.DoNothing::class) +interface ExpectActualTracker { + fun report(expectedFile: File, actualFile: File) + + object DoNothing : ExpectActualTracker { + override fun report(expectedFile: File, actualFile: File) { + } + } +} \ No newline at end of file diff --git a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index 16fd46e383c..368d60863b2 100755 --- a/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/src/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -137,6 +137,8 @@ import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest import org.jetbrains.kotlin.idea.stubs.AbstractStubBuilderTest import org.jetbrains.kotlin.incremental.AbstractIncrementalJsCompilerRunnerTest import org.jetbrains.kotlin.incremental.AbstractIncrementalJvmCompilerRunnerTest +import org.jetbrains.kotlin.incremental.AbstractIncrementalMultiplatformJsCompilerRunnerTest +import org.jetbrains.kotlin.incremental.AbstractIncrementalMultiplatformJvmCompilerRunnerTest import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterForWebDemoTest import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterMultiFileTest import org.jetbrains.kotlin.j2k.AbstractJavaToKotlinConverterSingleFileTest @@ -920,6 +922,13 @@ fun main(args: Array) { model("incremental/pureKotlin", extension = null, recursive = false) model("incremental/classHierarchyAffected", extension = null, recursive = false) } + + testClass { + model("incremental/multiplatform", extension = null, excludeParentDirs = true) + } + testClass { + model("incremental/multiplatform", extension = null, excludeParentDirs = true) + } } testGroup("plugins/android-extensions/android-extensions-compiler/test", "plugins/android-extensions/android-extensions-compiler/testData") { diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt index 6c730570820..1c0078f7b81 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/caches/resolve/lightClasses/IDELightClassContexts.kt @@ -42,6 +42,7 @@ import org.jetbrains.kotlin.idea.compiler.IDELanguageSettingsProvider import org.jetbrains.kotlin.idea.project.IdeaEnvironment import org.jetbrains.kotlin.idea.project.ResolveElementCache import org.jetbrains.kotlin.idea.stubindex.KotlinOverridableInternalMembersShortNameIndex +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.lexer.KtTokens @@ -288,6 +289,7 @@ object IDELightClassContexts { useInstance(GlobalSearchScope.EMPTY_SCOPE) useInstance(LookupTracker.DO_NOTHING) + useInstance(ExpectActualTracker.DoNothing) useImpl() useInstance(IDELanguageSettingsProvider.getLanguageVersionSettings(moduleInfo, project)) useInstance(FileBasedDeclarationProviderFactory(sm, files)) diff --git a/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt index 48958c6163b..fd9dd0996da 100644 --- a/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt +++ b/idea/src/org/jetbrains/kotlin/idea/highlighter/PlatformExpectedAnnotator.kt @@ -25,6 +25,7 @@ import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor import org.jetbrains.kotlin.idea.core.toDescriptor import org.jetbrains.kotlin.idea.facet.implementingDescriptors import org.jetbrains.kotlin.idea.project.TargetPlatformDetector +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.psi.KtClassOrObject import org.jetbrains.kotlin.psi.KtDeclaration import org.jetbrains.kotlin.psi.KtNamedDeclaration @@ -50,7 +51,8 @@ class PlatformExpectedAnnotator : Annotator { val trace = BindingTraceContext() for (module in implementingModules) { - ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module) + ExpectedActualDeclarationChecker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module, + ExpectActualTracker.DoNothing) } val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache() diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt new file mode 100644 index 00000000000..2e6edf9d000 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt @@ -0,0 +1,3 @@ +actual class X { + actual fun foo(): Any = 0 +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt.touch.1 b/jps-plugin/testData/incremental/multiplatform/touchActual/X.kt.touch.1 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/Y.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/Y.kt new file mode 100644 index 00000000000..8fea6dc0dfe --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/Y.kt @@ -0,0 +1,3 @@ +actual class Y { + actual fun foo(): Any = 0 +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/Z.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/Z.kt new file mode 100644 index 00000000000..e350bdc939c --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/Z.kt @@ -0,0 +1,3 @@ +actual class Z { + actual fun foo(): Any = 0 +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/build.log b/jps-plugin/testData/incremental/multiplatform/touchActual/build.log new file mode 100644 index 00000000000..dd0d111cbc8 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/build.log @@ -0,0 +1,19 @@ +================ Step #1 ================= + +Compiling files: + src/X.kt + src/commonX.kt + src/useX.kt +End of files +Exit code: SUCCESS + +================ Step #2 ================= + +Compiling files: + src/Y.kt + src/Z.kt + src/commonY.kt + src/commonZ.kt + src/useYZ.kt +End of files +Exit code: SUCCESS diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/commonX.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/commonX.kt new file mode 100644 index 00000000000..7fc73e5ec89 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/commonX.kt @@ -0,0 +1,5 @@ +expect class X { + fun foo(): Any +} + +expect fun useX(x: X): Unit \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/commonY.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/commonY.kt new file mode 100644 index 00000000000..ef8ae049d66 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/commonY.kt @@ -0,0 +1,5 @@ +expect class Y { + fun foo(): Any +} + +expect fun useY(y: Y): Unit \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/commonZ.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/commonZ.kt new file mode 100644 index 00000000000..80e902ffb27 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/commonZ.kt @@ -0,0 +1,5 @@ +expect class Z { + fun foo(): Any +} + +expect fun useZ(z: Z): Unit \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/dummy.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/dummy.kt new file mode 100644 index 00000000000..3f0c1c77242 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/dummy.kt @@ -0,0 +1 @@ +fun dummy() {} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/useX.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/useX.kt new file mode 100644 index 00000000000..ffb13ada9a6 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/useX.kt @@ -0,0 +1,3 @@ +actual fun useX(x: X): Unit { + x.foo() +} diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt b/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt new file mode 100644 index 00000000000..859c12dd85b --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt @@ -0,0 +1,7 @@ +actual fun useY(y: Y): Unit { + y.foo() +} + +actual fun useZ(z: Z): Unit { + z.foo() +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt.touch.2 b/jps-plugin/testData/incremental/multiplatform/touchActual/useYZ.kt.touch.2 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/X.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/X.kt new file mode 100644 index 00000000000..2e6edf9d000 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/X.kt @@ -0,0 +1,3 @@ +actual class X { + actual fun foo(): Any = 0 +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/Y.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/Y.kt new file mode 100644 index 00000000000..8fea6dc0dfe --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/Y.kt @@ -0,0 +1,3 @@ +actual class Y { + actual fun foo(): Any = 0 +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/Z.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/Z.kt new file mode 100644 index 00000000000..e350bdc939c --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/Z.kt @@ -0,0 +1,3 @@ +actual class Z { + actual fun foo(): Any = 0 +} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/build.log b/jps-plugin/testData/incremental/multiplatform/touchExpect/build.log new file mode 100644 index 00000000000..dd0d111cbc8 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/build.log @@ -0,0 +1,19 @@ +================ Step #1 ================= + +Compiling files: + src/X.kt + src/commonX.kt + src/useX.kt +End of files +Exit code: SUCCESS + +================ Step #2 ================= + +Compiling files: + src/Y.kt + src/Z.kt + src/commonY.kt + src/commonZ.kt + src/useYZ.kt +End of files +Exit code: SUCCESS diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt new file mode 100644 index 00000000000..7fc73e5ec89 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt @@ -0,0 +1,5 @@ +expect class X { + fun foo(): Any +} + +expect fun useX(x: X): Unit \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt.touch.1 b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonX.kt.touch.1 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt new file mode 100644 index 00000000000..ef8ae049d66 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt @@ -0,0 +1,5 @@ +expect class Y { + fun foo(): Any +} + +expect fun useY(y: Y): Unit \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt.touch.2 b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonY.kt.touch.2 new file mode 100644 index 00000000000..e69de29bb2d diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/commonZ.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonZ.kt new file mode 100644 index 00000000000..80e902ffb27 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/commonZ.kt @@ -0,0 +1,5 @@ +expect class Z { + fun foo(): Any +} + +expect fun useZ(z: Z): Unit \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/dummy.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/dummy.kt new file mode 100644 index 00000000000..3f0c1c77242 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/dummy.kt @@ -0,0 +1 @@ +fun dummy() {} \ No newline at end of file diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/useX.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/useX.kt new file mode 100644 index 00000000000..ffb13ada9a6 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/useX.kt @@ -0,0 +1,3 @@ +actual fun useX(x: X): Unit { + x.foo() +} diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/useXIncompatible.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/useXIncompatible.kt new file mode 100644 index 00000000000..55bd63557c9 --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/useXIncompatible.kt @@ -0,0 +1,2 @@ +fun useX(x: String): Int = + x.length diff --git a/jps-plugin/testData/incremental/multiplatform/touchExpect/useYZ.kt b/jps-plugin/testData/incremental/multiplatform/touchExpect/useYZ.kt new file mode 100644 index 00000000000..859c12dd85b --- /dev/null +++ b/jps-plugin/testData/incremental/multiplatform/touchExpect/useYZ.kt @@ -0,0 +1,7 @@ +actual fun useY(y: Y): Unit { + y.foo() +} + +actual fun useZ(z: Z): Unit { + z.foo() +} \ No newline at end of file diff --git a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt index 181429d41f5..7659a87b1da 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/frontend/js/di/injection.kt @@ -26,6 +26,7 @@ import org.jetbrains.kotlin.descriptors.PackageFragmentProvider 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.js.resolve.JsPlatform import org.jetbrains.kotlin.resolve.* @@ -42,6 +43,7 @@ fun createTopDownAnalyzerForJs( declarationProviderFactory: DeclarationProviderFactory, languageVersionSettings: LanguageVersionSettings, lookupTracker: LookupTracker, + expectActualTracker: ExpectActualTracker, fallbackPackage: PackageFragmentProvider? ): LazyTopDownAnalyzer { val storageComponentContainer = createContainer("TopDownAnalyzerForJs", JsPlatform) { @@ -52,6 +54,7 @@ fun createTopDownAnalyzerForJs( CompilerEnvironment.configure(this) useInstance(lookupTracker) + useInstance(expectActualTracker) useInstance(languageVersionSettings) useImpl() diff --git a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt index b3ad1c43e8c..698dd9791fe 100644 --- a/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt +++ b/js/js.frontend/src/org/jetbrains/kotlin/js/analyze/TopDownAnalyzerFacadeForJS.kt @@ -22,6 +22,7 @@ import org.jetbrains.kotlin.context.ContextForNewModule import org.jetbrains.kotlin.context.ModuleContext import org.jetbrains.kotlin.context.ProjectContext import org.jetbrains.kotlin.frontend.js.di.createTopDownAnalyzerForJs +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.js.analyzer.JsAnalysisResult import org.jetbrains.kotlin.js.config.JSConfigurationKeys @@ -66,6 +67,7 @@ object TopDownAnalyzerFacadeForJS { config: JsConfig ): JsAnalysisResult { val lookupTracker = config.configuration.get(CommonConfigurationKeys.LOOKUP_TRACKER) ?: LookupTracker.DO_NOTHING + val expectActualTracker = config.configuration.get(CommonConfigurationKeys.EXPECT_ACTUAL_TRACKER) ?: ExpectActualTracker.DoNothing val languageVersionSettings = config.configuration.languageVersionSettings val packageFragment = config.configuration[JSConfigurationKeys.INCREMENTAL_DATA_PROVIDER]?.let { val metadata = PackagesWithHeaderMetadata(it.headerMetadata, it.compiledPackageParts.values.map { it.metadata }) @@ -79,6 +81,7 @@ object TopDownAnalyzerFacadeForJS { FileBasedDeclarationProviderFactory(moduleContext.storageManager, files), languageVersionSettings, lookupTracker, + expectActualTracker, packageFragment ) analyzerForJs.analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files) diff --git a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt index 918ca8984d0..4246c6884ed 100644 --- a/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt +++ b/plugins/noarg/noarg-cli/src/org/jetbrains/kotlin/noarg/diagnostic/CliNoArgDeclarationChecker.kt @@ -24,6 +24,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.diagnostics.DiagnosticSink import org.jetbrains.kotlin.diagnostics.reportFromPlugin import org.jetbrains.kotlin.extensions.AnnotationBasedExtension +import org.jetbrains.kotlin.incremental.components.ExpectActualTracker import org.jetbrains.kotlin.noarg.NO_ARG_CLASS_KEY import org.jetbrains.kotlin.psi.KtClass import org.jetbrains.kotlin.psi.KtDeclaration @@ -43,7 +44,8 @@ abstract class AbstractNoArgDeclarationChecker : DeclarationChecker, AnnotationB descriptor: DeclarationDescriptor, diagnosticHolder: DiagnosticSink, bindingContext: BindingContext, - languageVersionSettings: LanguageVersionSettings + languageVersionSettings: LanguageVersionSettings, + expectActualTracker: ExpectActualTracker ) { // Handle only classes if (descriptor !is ClassDescriptor || declaration !is KtClass) return