[Expect/Actual] Remove PlatformExpectedAnnotator
This commit is contained in:
+73
-63
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.platform.CommonPlatforms
|
||||
import org.jetbrains.kotlin.platform.TargetPlatform
|
||||
import org.jetbrains.kotlin.psi.KtFile
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
|
||||
@@ -54,67 +55,7 @@ class CommonAnalysisParameters(
|
||||
* A facade that is used to analyze common (platform-independent) modules in multi-platform projects.
|
||||
* See [CommonPlatform]
|
||||
*/
|
||||
object CommonResolverForModuleFactory : ResolverForModuleFactory() {
|
||||
private class SourceModuleInfo(
|
||||
override val name: Name,
|
||||
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>,
|
||||
private val dependOnOldBuiltIns: Boolean
|
||||
) : ModuleInfo {
|
||||
override fun dependencies() = listOf(this)
|
||||
|
||||
override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns =
|
||||
if (dependOnOldBuiltIns) ModuleInfo.DependencyOnBuiltIns.LAST else ModuleInfo.DependencyOnBuiltIns.NONE
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = CommonPlatforms.defaultCommonPlatform
|
||||
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||
get() = CommonPlatformAnalyzerServices
|
||||
}
|
||||
|
||||
fun analyzeFiles(
|
||||
files: Collection<KtFile>, moduleName: Name, dependOnBuiltIns: Boolean, languageVersionSettings: LanguageVersionSettings,
|
||||
capabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap(),
|
||||
metadataPartProviderFactory: (ModuleContent<ModuleInfo>) -> MetadataPartProvider
|
||||
): AnalysisResult {
|
||||
val moduleInfo = SourceModuleInfo(moduleName, capabilities, dependOnBuiltIns)
|
||||
val project = files.firstOrNull()?.project ?: throw AssertionError("No files to analyze")
|
||||
|
||||
val multiplatformLanguageSettings = object : LanguageVersionSettings by languageVersionSettings {
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
|
||||
if (feature == LanguageFeature.MultiPlatformProjects) LanguageFeature.State.ENABLED
|
||||
else languageVersionSettings.getFeatureSupport(feature)
|
||||
}
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val resolver = ResolverForProjectImpl(
|
||||
"sources for metadata serializer",
|
||||
ProjectContext(project, "metadata serializer"),
|
||||
listOf(moduleInfo),
|
||||
modulesContent = { ModuleContent(it, files, GlobalSearchScope.allScope(project)) },
|
||||
moduleLanguageSettingsProvider = object : LanguageSettingsProvider {
|
||||
override fun getLanguageVersionSettings(
|
||||
moduleInfo: ModuleInfo,
|
||||
project: Project,
|
||||
isReleaseCoroutines: Boolean?
|
||||
) = multiplatformLanguageSettings
|
||||
|
||||
override fun getTargetPlatform(
|
||||
moduleInfo: ModuleInfo,
|
||||
project: Project
|
||||
) = TargetPlatformVersion.NoVersion
|
||||
},
|
||||
resolverForModuleFactoryByPlatform = { CommonResolverForModuleFactory },
|
||||
platformParameters = { _ -> CommonAnalysisParameters(metadataPartProviderFactory) }
|
||||
)
|
||||
|
||||
val moduleDescriptor = resolver.descriptorForModule(moduleInfo)
|
||||
val container = resolver.resolverForModule(moduleInfo).componentProvider
|
||||
|
||||
container.get<LazyTopDownAnalyzer>().analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files)
|
||||
|
||||
return AnalysisResult.success(container.get<BindingTrace>().bindingContext, moduleDescriptor)
|
||||
}
|
||||
class CommonResolverForModuleFactory(private val shouldCheckExpectActual: Boolean) : ResolverForModuleFactory() {
|
||||
|
||||
override fun <M : ModuleInfo> createResolverForModule(
|
||||
moduleDescriptor: ModuleDescriptorImpl,
|
||||
@@ -137,7 +78,7 @@ object CommonResolverForModuleFactory : ResolverForModuleFactory() {
|
||||
val trace = CodeAnalyzerInitializer.getInstance(project).createTrace()
|
||||
val container = createContainerToResolveCommonCode(
|
||||
moduleContext, trace, declarationProviderFactory, moduleContentScope, targetEnvironment, metadataPartProvider,
|
||||
languageVersionSettings, CommonPlatforms.defaultCommonPlatform, CommonPlatformAnalyzerServices
|
||||
languageVersionSettings, CommonPlatforms.defaultCommonPlatform, CommonPlatformAnalyzerServices, shouldCheckExpectActual
|
||||
)
|
||||
|
||||
val packageFragmentProviders = listOf(
|
||||
@@ -147,6 +88,70 @@ object CommonResolverForModuleFactory : ResolverForModuleFactory() {
|
||||
|
||||
return ResolverForModule(CompositePackageFragmentProvider(packageFragmentProviders), container)
|
||||
}
|
||||
|
||||
companion object {
|
||||
private class SourceModuleInfo(
|
||||
override val name: Name,
|
||||
override val capabilities: Map<ModuleDescriptor.Capability<*>, Any?>,
|
||||
private val dependOnOldBuiltIns: Boolean
|
||||
) : ModuleInfo {
|
||||
override fun dependencies() = listOf(this)
|
||||
|
||||
override fun dependencyOnBuiltIns(): ModuleInfo.DependencyOnBuiltIns =
|
||||
if (dependOnOldBuiltIns) ModuleInfo.DependencyOnBuiltIns.LAST else ModuleInfo.DependencyOnBuiltIns.NONE
|
||||
|
||||
override val platform: TargetPlatform
|
||||
get() = CommonPlatforms.defaultCommonPlatform
|
||||
|
||||
override val analyzerServices: PlatformDependentAnalyzerServices
|
||||
get() = CommonPlatformAnalyzerServices
|
||||
}
|
||||
|
||||
fun analyzeFiles(
|
||||
files: Collection<KtFile>, moduleName: Name, dependOnBuiltIns: Boolean, languageVersionSettings: LanguageVersionSettings,
|
||||
capabilities: Map<ModuleDescriptor.Capability<*>, Any?> = emptyMap(),
|
||||
shouldCheckExpectActual: Boolean = false,
|
||||
metadataPartProviderFactory: (ModuleContent<ModuleInfo>) -> MetadataPartProvider
|
||||
): AnalysisResult {
|
||||
val moduleInfo = SourceModuleInfo(moduleName, capabilities, dependOnBuiltIns)
|
||||
val project = files.firstOrNull()?.project ?: throw AssertionError("No files to analyze")
|
||||
|
||||
val multiplatformLanguageSettings = object : LanguageVersionSettings by languageVersionSettings {
|
||||
override fun getFeatureSupport(feature: LanguageFeature): LanguageFeature.State =
|
||||
if (feature == LanguageFeature.MultiPlatformProjects) LanguageFeature.State.ENABLED
|
||||
else languageVersionSettings.getFeatureSupport(feature)
|
||||
}
|
||||
|
||||
@Suppress("NAME_SHADOWING")
|
||||
val resolver = ResolverForProjectImpl(
|
||||
"sources for metadata serializer",
|
||||
ProjectContext(project, "metadata serializer"),
|
||||
listOf(moduleInfo),
|
||||
modulesContent = { ModuleContent(it, files, GlobalSearchScope.allScope(project)) },
|
||||
moduleLanguageSettingsProvider = object : LanguageSettingsProvider {
|
||||
override fun getLanguageVersionSettings(
|
||||
moduleInfo: ModuleInfo,
|
||||
project: Project,
|
||||
isReleaseCoroutines: Boolean?
|
||||
) = multiplatformLanguageSettings
|
||||
|
||||
override fun getTargetPlatform(
|
||||
moduleInfo: ModuleInfo,
|
||||
project: Project
|
||||
) = TargetPlatformVersion.NoVersion
|
||||
},
|
||||
resolverForModuleFactoryByPlatform = { CommonResolverForModuleFactory(shouldCheckExpectActual) },
|
||||
platformParameters = { _ -> CommonAnalysisParameters(metadataPartProviderFactory) }
|
||||
)
|
||||
|
||||
val moduleDescriptor = resolver.descriptorForModule(moduleInfo)
|
||||
val container = resolver.resolverForModule(moduleInfo).componentProvider
|
||||
|
||||
container.get<LazyTopDownAnalyzer>().analyzeDeclarations(TopDownAnalysisMode.TopLevelDeclarations, files)
|
||||
|
||||
return AnalysisResult.success(container.get<BindingTrace>().bindingContext, moduleDescriptor)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private fun createContainerToResolveCommonCode(
|
||||
@@ -158,7 +163,8 @@ private fun createContainerToResolveCommonCode(
|
||||
metadataPartProvider: MetadataPartProvider,
|
||||
languageVersionSettings: LanguageVersionSettings,
|
||||
platform: TargetPlatform,
|
||||
analyzerServices: PlatformDependentAnalyzerServices
|
||||
analyzerServices: PlatformDependentAnalyzerServices,
|
||||
shouldCheckExpectActual: Boolean
|
||||
): StorageComponentContainer =
|
||||
createContainer("ResolveCommonCode", analyzerServices) {
|
||||
configureModule(moduleContext, platform, analyzerServices, bindingTrace, languageVersionSettings)
|
||||
@@ -179,6 +185,10 @@ private fun createContainerToResolveCommonCode(
|
||||
useInstance(metadataFinderFactory.create(moduleContentScope))
|
||||
|
||||
targetEnvironment.configure(this)
|
||||
|
||||
if (shouldCheckExpectActual) {
|
||||
useImpl<ExpectedActualDeclarationChecker>()
|
||||
}
|
||||
}
|
||||
|
||||
fun StorageComponentContainer.configureCommonSpecificComponents() {
|
||||
|
||||
@@ -27,10 +27,12 @@ import org.jetbrains.kotlin.extensions.StorageComponentContainerContributor
|
||||
import org.jetbrains.kotlin.incremental.components.ExpectActualTracker
|
||||
import org.jetbrains.kotlin.incremental.components.LookupTracker
|
||||
import org.jetbrains.kotlin.platform.TargetPlatformVersion
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.resolve.*
|
||||
import org.jetbrains.kotlin.resolve.calls.components.ClassicTypeSystemContextForCS
|
||||
import org.jetbrains.kotlin.resolve.calls.smartcasts.DataFlowValueFactoryImpl
|
||||
import org.jetbrains.kotlin.resolve.calls.tower.KotlinResolutionStatelessCallbacksImpl
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker
|
||||
import org.jetbrains.kotlin.resolve.lazy.*
|
||||
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
|
||||
@@ -140,6 +142,12 @@ fun createContainerForLazyBodyResolve(
|
||||
useImpl<LazyTopDownAnalyzer>()
|
||||
useImpl<BasicAbsentDescriptorHandler>()
|
||||
useInstance(moduleStructureOracle)
|
||||
|
||||
// All containers except common inject ExpectedActualDeclarationChecker, so for common we do that
|
||||
// explicitly.
|
||||
// Note that it is not possible to move this code to [CommonPlatformConfigurator], because during
|
||||
// compilation of common-module to metadata we should skip those checks
|
||||
if (platform.isCommon()) useImpl<ExpectedActualDeclarationChecker>()
|
||||
}
|
||||
|
||||
fun createContainerForLazyLocalClassifierAnalyzer(
|
||||
|
||||
+1
-1
@@ -28,7 +28,7 @@ class CommonPlatformKindResolution : IdePlatformKindResolution {
|
||||
override val kind get() = CommonIdePlatformKind
|
||||
|
||||
override val resolverForModuleFactory: ResolverForModuleFactory
|
||||
get() = CommonResolverForModuleFactory
|
||||
get() = CommonResolverForModuleFactory(shouldCheckExpectActual = true)
|
||||
|
||||
override fun createBuiltIns(settings: PlatformAnalysisSettings, projectContext: ProjectContext): KotlinBuiltIns {
|
||||
return DefaultBuiltIns.Instance
|
||||
|
||||
+1
-1
@@ -34,7 +34,7 @@ object CommonIdePlatformKindTooling : IdePlatformKindTooling() {
|
||||
|
||||
override fun compilerArgumentsForProject(project: Project): CommonCompilerArguments? = null
|
||||
|
||||
override val resolverForModuleFactory = CommonResolverForModuleFactory
|
||||
override val resolverForModuleFactory = CommonResolverForModuleFactory(true)
|
||||
|
||||
override val mavenLibraryIds = listOf(MAVEN_COMMON_STDLIB_ID)
|
||||
override val gradlePluginId = "kotlin-platform-common"
|
||||
|
||||
@@ -594,7 +594,6 @@
|
||||
|
||||
<annotator language="kotlin" implementationClass="org.jetbrains.kotlin.idea.highlighter.DebugInfoAnnotator"/>
|
||||
<annotator language="kotlin" implementationClass="org.jetbrains.kotlin.idea.highlighter.DuplicateJvmSignatureAnnotator"/>
|
||||
<annotator language="kotlin" implementationClass="org.jetbrains.kotlin.idea.highlighter.PlatformExpectedAnnotator"/>
|
||||
<problemHighlightFilter implementation="org.jetbrains.kotlin.idea.highlighter.KotlinProblemHighlightFilter"/>
|
||||
|
||||
<highlightVisitor implementation="org.jetbrains.kotlin.idea.highlighter.KotlinRainbowVisitor"/>
|
||||
|
||||
@@ -1,74 +0,0 @@
|
||||
/*
|
||||
* 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.idea.highlighter
|
||||
|
||||
import com.intellij.lang.annotation.AnnotationHolder
|
||||
import com.intellij.lang.annotation.Annotator
|
||||
import com.intellij.psi.PsiElement
|
||||
import org.jetbrains.kotlin.caches.resolve.KotlinCacheService
|
||||
import org.jetbrains.kotlin.descriptors.MemberDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.project.implementingDescriptors
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.findModuleDescriptor
|
||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||
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
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier
|
||||
import org.jetbrains.kotlin.resolve.BindingTraceContext
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
import org.jetbrains.kotlin.resolve.diagnostics.SimpleDiagnostics
|
||||
import org.jetbrains.kotlin.platform.isCommon
|
||||
import org.jetbrains.kotlin.resolve.jvm.multiplatform.JavaActualAnnotationArgumentExtractor
|
||||
|
||||
class PlatformExpectedAnnotator : Annotator {
|
||||
override fun annotate(element: PsiElement, holder: AnnotationHolder) {
|
||||
val declaration = element as? KtNamedDeclaration ?: return
|
||||
if (!isExpectedDeclaration(declaration)) return
|
||||
|
||||
if (!TargetPlatformDetector.getPlatform(declaration.containingKtFile).isCommon()) return
|
||||
|
||||
val implementingModules = declaration.findModuleDescriptor().implementingDescriptors
|
||||
if (implementingModules.isEmpty()) return
|
||||
|
||||
val descriptor = declaration.toDescriptor() as? MemberDescriptor ?: return
|
||||
if (!descriptor.isExpect) return
|
||||
|
||||
// TODO: obtain the list of annotation argument extractors from platform somehow
|
||||
val checker = ExpectedActualDeclarationChecker(listOf(JavaActualAnnotationArgumentExtractor()))
|
||||
|
||||
val trace = BindingTraceContext()
|
||||
for (module in implementingModules) {
|
||||
checker.checkExpectedDeclarationHasActual(declaration, descriptor, trace, module, ExpectActualTracker.DoNothing)
|
||||
}
|
||||
|
||||
val suppressionCache = KotlinCacheService.getInstance(declaration.project).getSuppressionCache()
|
||||
val filteredList = trace.bindingContext.diagnostics.filter { diagnostic ->
|
||||
!suppressionCache.isSuppressed(declaration, diagnostic.factory.name, diagnostic.severity)
|
||||
}
|
||||
if (filteredList.isEmpty()) return
|
||||
|
||||
KotlinPsiChecker().annotateElement(declaration, holder, SimpleDiagnostics(filteredList))
|
||||
}
|
||||
|
||||
private fun isExpectedDeclaration(declaration: KtDeclaration): Boolean {
|
||||
return declaration.hasExpectModifier() ||
|
||||
declaration is KtClassOrObject && KtPsiUtil.getOutermostClassOrObject(declaration)?.hasExpectModifier() == true
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user