[Platform API] Introduce fundamental abstraction of Platform

This is a large commit, which introduces general API for working with
abstraction of Platform.

- Add new abstraction to 'core' - SimplePlatform - which represents
exactly one platform
  - Clients are strongly prohibited to create instances of SimplePlatform
  by hand, instead, corresponding *Platforms abstraction should be used
  (e.g. JvmPlatforms, JsPlatforms, KonanPlatforms)

- Move TargetPlatform to 'core', it represents now a collection of
SimplePlatforms
  - Clients are strongly encouraged to use TargetPlatform
    (not SimplePlatform) in API, to enforce checks for multiplatform

- Provide a helper-extensions to work with TargetPlatform
(in particular, for getting a specific component platform)

- Remove MultiTargetPlatform in favour of TargetPlatform
  - Notably, this commit leaves another widely used duplicated abstraction,
    namely, IdePlatform. For the sake sanity, removal of IdePlatform is
    extracted in the separate commit.
This commit is contained in:
Dmitry Savvinov
2019-04-24 11:59:07 +03:00
parent 451d14e504
commit d5fbe59a3e
162 changed files with 832 additions and 711 deletions
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.config
import org.jetbrains.kotlin.platform.TargetPlatformVersion
import org.jetbrains.org.objectweb.asm.Opcodes
enum class JvmTarget(override val description: String) : TargetPlatformVersion {
@@ -21,7 +21,6 @@ import com.intellij.psi.search.GlobalSearchScope
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltIns
import org.jetbrains.kotlin.builtins.jvm.JvmBuiltInsPackageFragmentProvider
import org.jetbrains.kotlin.config.JvmAnalysisFlags
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageFeature
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.container.*
@@ -41,9 +40,9 @@ import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolver
import org.jetbrains.kotlin.load.kotlin.DeserializationComponentsForJava
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.load.kotlin.VirtualFileFinderFactory
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.jvm.JavaDescriptorResolver
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatformCompilerServices
import org.jetbrains.kotlin.resolve.lazy.KotlinCodeAnalyzer
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
@@ -79,22 +78,22 @@ private fun StorageComponentContainer.configureJavaTopDownAnalysis(
}
fun createContainerForLazyResolveWithJava(
moduleContext: ModuleContext,
bindingTrace: BindingTrace,
declarationProviderFactory: DeclarationProviderFactory,
moduleContentScope: GlobalSearchScope,
moduleClassResolver: ModuleClassResolver,
targetEnvironment: TargetEnvironment,
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
packagePartProvider: PackagePartProvider,
jvmTarget: JvmTarget,
languageVersionSettings: LanguageVersionSettings,
useBuiltInsProvider: Boolean,
configureJavaClassFinder: (StorageComponentContainer.() -> Unit)? = null,
javaClassTracker: JavaClassesTracker? = null
jvmPlatform: TargetPlatform,
moduleContext: ModuleContext,
bindingTrace: BindingTrace,
declarationProviderFactory: DeclarationProviderFactory,
moduleContentScope: GlobalSearchScope,
moduleClassResolver: ModuleClassResolver,
targetEnvironment: TargetEnvironment,
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
packagePartProvider: PackagePartProvider,
languageVersionSettings: LanguageVersionSettings,
useBuiltInsProvider: Boolean,
configureJavaClassFinder: (StorageComponentContainer.() -> Unit)? = null,
javaClassTracker: JavaClassesTracker? = null
): StorageComponentContainer = createContainer("LazyResolveWithJava", JvmPlatformCompilerServices) {
configureModule(moduleContext, JvmPlatform, jvmTarget, JvmPlatformCompilerServices, bindingTrace)
configureModule(moduleContext, jvmPlatform, JvmPlatformCompilerServices, bindingTrace)
configureJavaTopDownAnalysis(moduleContentScope, moduleContext.project, lookupTracker, expectActualTracker)
if (configureJavaClassFinder != null) {
@@ -135,22 +134,22 @@ fun createContainerForLazyResolveWithJava(
fun createContainerForTopDownAnalyzerForJvm(
moduleContext: ModuleContext,
bindingTrace: BindingTrace,
declarationProviderFactory: DeclarationProviderFactory,
moduleContentScope: GlobalSearchScope,
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
packagePartProvider: PackagePartProvider,
moduleClassResolver: ModuleClassResolver,
targetEnvironment: TargetEnvironment,
jvmTarget: JvmTarget,
languageVersionSettings: LanguageVersionSettings,
configureJavaClassFinder: (StorageComponentContainer.() -> Unit)? = null,
javaClassTracker: JavaClassesTracker? = null
jvmPlatform: TargetPlatform,
moduleContext: ModuleContext,
bindingTrace: BindingTrace,
declarationProviderFactory: DeclarationProviderFactory,
moduleContentScope: GlobalSearchScope,
lookupTracker: LookupTracker,
expectActualTracker: ExpectActualTracker,
packagePartProvider: PackagePartProvider,
moduleClassResolver: ModuleClassResolver,
targetEnvironment: TargetEnvironment,
languageVersionSettings: LanguageVersionSettings,
configureJavaClassFinder: (StorageComponentContainer.() -> Unit)? = null,
javaClassTracker: JavaClassesTracker? = null
): ComponentProvider = createContainerForLazyResolveWithJava(
moduleContext, bindingTrace, declarationProviderFactory, moduleContentScope, moduleClassResolver,
targetEnvironment, lookupTracker, expectActualTracker, packagePartProvider, jvmTarget, languageVersionSettings,
jvmPlatform, moduleContext, bindingTrace, declarationProviderFactory, moduleContentScope, moduleClassResolver,
targetEnvironment, lookupTracker, expectActualTracker, packagePartProvider, languageVersionSettings,
useBuiltInsProvider = true,
configureJavaClassFinder = configureJavaClassFinder,
javaClassTracker = javaClassTracker
@@ -0,0 +1,44 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.platform.jvm
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.platform.SimplePlatform
import org.jetbrains.kotlin.platform.TargetPlatform
import org.jetbrains.kotlin.platform.toTargetPlatform
import org.jetbrains.kotlin.platform.TargetPlatformVersion
abstract class JvmPlatform : SimplePlatform("JVM") {
override val oldFashionedDescription: String
get() = "JVM "
}
object JvmPlatforms {
private val jvmTargetToJdkPlatform: Map<JvmTarget, TargetPlatform> =
JvmTarget.values().map { it to JdkPlatform(it).toTargetPlatform() }.toMap()
val defaultJvmPlatform: TargetPlatform = jvmTargetToJdkPlatform[JvmTarget.DEFAULT]!!
val jvm16: TargetPlatform = jvmTargetToJdkPlatform[JvmTarget.JVM_1_6]!!
val jvm18: TargetPlatform = jvmTargetToJdkPlatform[JvmTarget.JVM_1_8]!!
fun jvmPlatformByTargetVersion(targetVersion: JvmTarget): TargetPlatform =
jvmTargetToJdkPlatform[targetVersion]!!
val allJvmPlatforms: List<TargetPlatform> = jvmTargetToJdkPlatform.values.toList()
}
data class JdkPlatform(val targetVersion: JvmTarget) : JvmPlatform() {
override fun toString(): String = "$platformName ($targetVersion)"
override val oldFashionedDescription: String
get() = "JVM " + targetVersion.description
override val targetPlatformVersion: TargetPlatformVersion
get() = targetVersion
}
fun TargetPlatform?.isJvm(): Boolean = this?.singleOrNull() is JvmPlatform
@@ -17,9 +17,7 @@
package org.jetbrains.kotlin.resolve.jvm
import org.jetbrains.kotlin.analyzer.*
import org.jetbrains.kotlin.config.JvmTarget
import org.jetbrains.kotlin.config.LanguageVersionSettings
import org.jetbrains.kotlin.config.TargetPlatformVersion
import org.jetbrains.kotlin.container.get
import org.jetbrains.kotlin.context.ModuleContext
import org.jetbrains.kotlin.descriptors.impl.CompositePackageFragmentProvider
@@ -30,11 +28,10 @@ import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.load.java.lazy.ModuleClassResolverImpl
import org.jetbrains.kotlin.load.java.structure.JavaClass
import org.jetbrains.kotlin.load.kotlin.PackagePartProvider
import org.jetbrains.kotlin.platform.jvm.isJvm
import org.jetbrains.kotlin.resolve.CodeAnalyzerInitializer
import org.jetbrains.kotlin.resolve.TargetEnvironment
import org.jetbrains.kotlin.resolve.TargetPlatform
import org.jetbrains.kotlin.resolve.jvm.extensions.PackageFragmentProviderExtension
import org.jetbrains.kotlin.resolve.jvm.platform.JvmPlatform
import org.jetbrains.kotlin.resolve.lazy.ResolveSession
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactoryService
@@ -52,8 +49,7 @@ object JvmResolverForModuleFactory : ResolverForModuleFactory() {
platformParameters: PlatformAnalysisParameters,
targetEnvironment: TargetEnvironment,
resolverForProject: ResolverForProject<M>,
languageVersionSettings: LanguageVersionSettings,
targetPlatformVersion: TargetPlatformVersion
languageVersionSettings: LanguageVersionSettings
): ResolverForModule {
val (moduleInfo, syntheticFiles, moduleContentScope) = moduleContent
val project = moduleContext.project
@@ -73,7 +69,7 @@ object JvmResolverForModuleFactory : ResolverForModuleFactory() {
val resolverForReferencedModule = referencedClassModule?.let { resolverForProject.tryGetResolverForModule(it as M) }
val resolverForModule = resolverForReferencedModule?.takeIf {
referencedClassModule.platform == JvmPlatform || referencedClassModule.platform == null
referencedClassModule.platform.isJvm() || referencedClassModule.platform == null
} ?: run {
// in case referenced class lies outside of our resolver, resolve the class as if it is inside our module
// this leads to java class being resolved several times
@@ -82,12 +78,12 @@ object JvmResolverForModuleFactory : ResolverForModuleFactory() {
resolverForModule.componentProvider.get<JavaDescriptorResolver>()
}
val jvmTarget = targetPlatformVersion as? JvmTarget ?: JvmTarget.DEFAULT
val trace = CodeAnalyzerInitializer.getInstance(project).createTrace()
val lookupTracker = LookupTracker.DO_NOTHING
val packagePartProvider = (platformParameters as JvmPlatformParameters).packagePartProviderFactory(moduleContent)
val container = createContainerForLazyResolveWithJava(
moduleDescriptor.platform!!,
moduleContext,
trace,
declarationProviderFactory,
@@ -97,7 +93,6 @@ object JvmResolverForModuleFactory : ResolverForModuleFactory() {
lookupTracker,
ExpectActualTracker.DoNothing,
packagePartProvider,
jvmTarget,
languageVersionSettings,
useBuiltInsProvider = false // TODO: load built-ins from module dependencies in IDE
)
@@ -1,23 +0,0 @@
/*
* Copyright 2010-2015 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.resolve.jvm.platform
import org.jetbrains.kotlin.resolve.*
object JvmPlatform : TargetPlatform("JVM") {
override val platform = MultiTargetPlatform.Specific(platformName)
}