From 22e1221c755e35f333875ed28dcbeef40a82591b Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 10 Nov 2016 14:31:02 +0300 Subject: [PATCH] Support "default platform" in IDE via facet settings --- idea/idea-analysis/idea-analysis.iml | 1 + .../idea/project/AnalyzerFacadeProvider.kt | 4 ++- .../jetbrains/kotlin/idea/project/Platform.kt | 21 ++++++++++-- .../idea/project/ProjectStructureUtil.java | 4 +++ .../kotlin/config/KotlinFacetSettings.kt | 4 ++- ...kLibraryValidatorWithDynamicDescription.kt | 5 +++ .../jetbrains/kotlin/idea/facet/facetUtils.kt | 9 +++-- .../CommonStandardLibraryDescription.kt | 34 +++++++++++++++++++ .../idea/versions/KotlinRuntimeLibraryUtil.kt | 1 + 9 files changed, 76 insertions(+), 7 deletions(-) create mode 100644 idea/src/org/jetbrains/kotlin/idea/framework/CommonStandardLibraryDescription.kt diff --git a/idea/idea-analysis/idea-analysis.iml b/idea/idea-analysis/idea-analysis.iml index 389f304003d..f55193503f4 100644 --- a/idea/idea-analysis/idea-analysis.iml +++ b/idea/idea-analysis/idea-analysis.iml @@ -33,5 +33,6 @@ + \ No newline at end of file diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt index 75c53c09f61..95738930637 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/AnalyzerFacadeProvider.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.project import org.jetbrains.kotlin.analyzer.AnalyzerFacade +import org.jetbrains.kotlin.analyzer.common.DefaultAnalyzerFacade import org.jetbrains.kotlin.idea.caches.resolve.JsAnalyzerFacade import org.jetbrains.kotlin.js.resolve.JsPlatform import org.jetbrains.kotlin.resolve.TargetPlatform @@ -29,8 +30,9 @@ object AnalyzerFacadeProvider { // otherwise we would be forced to add casts on the call site of setupResolverForProject fun getAnalyzerFacade(targetPlatform: TargetPlatform): AnalyzerFacade { return when (targetPlatform) { - is JvmPlatform -> JvmAnalyzerFacade + JvmPlatform -> JvmAnalyzerFacade JsPlatform -> JsAnalyzerFacade + TargetPlatform.Default -> DefaultAnalyzerFacade else -> throw IllegalArgumentException("Unsupported platform: $targetPlatform") } } diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt index 9ee9b20f981..22216fece81 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/Platform.kt @@ -18,7 +18,9 @@ package org.jetbrains.kotlin.idea.project import com.intellij.openapi.module.Module import com.intellij.openapi.module.ModuleUtilCore +import com.sampullara.cli.Argument import org.jetbrains.kotlin.builtins.KotlinBuiltIns +import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade import org.jetbrains.kotlin.psi.KtElement @@ -30,13 +32,26 @@ val KtElement.platform: TargetPlatform val KtElement.builtIns: KotlinBuiltIns get() = getResolutionFacade().moduleDescriptor.builtIns +private val multiPlatformProjectsArg: String by lazy { + "-" + CommonCompilerArguments::multiPlatform.annotations.filterIsInstance().single().value +} + val Module.languageVersionSettings: LanguageVersionSettings get() { - val versionInfo = KotlinFacetSettingsProvider.getInstance(project).getSettings(this).versionInfo + val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getSettings(this) + val versionInfo = facetSettings.versionInfo val languageVersion = versionInfo.languageLevel ?: LanguageVersion.LATEST val apiVersion = versionInfo.apiLevel ?: languageVersion - return LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion)) + + val extraLanguageFeatures = + if (versionInfo.targetPlatformKind == TargetPlatformKind.Default || + // TODO: this is a dirty hack, parse arguments correctly here + facetSettings.compilerInfo.compilerSettings?.additionalArguments?.contains(multiPlatformProjectsArg) == true) + listOf(LanguageFeature.MultiPlatformProjects) + else emptyList() + + return LanguageVersionSettingsImpl(languageVersion, ApiVersion.createByLanguageVersion(apiVersion), extraLanguageFeatures) } val KtElement.languageVersionSettings: LanguageVersionSettings - get() = ModuleUtilCore.findModuleForPsiElement(this)?.languageVersionSettings ?: LanguageVersionSettingsImpl.DEFAULT \ No newline at end of file + get() = ModuleUtilCore.findModuleForPsiElement(this)?.languageVersionSettings ?: LanguageVersionSettingsImpl.DEFAULT diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java index 70984863632..95a67839ed4 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/project/ProjectStructureUtil.java @@ -44,6 +44,7 @@ public class ProjectStructureUtil { private ProjectStructureUtil() { } + @NotNull /* package */ static TargetPlatform getCachedPlatformForModule(@NotNull final Module module) { CachedValue result = module.getUserData(PLATFORM_FOR_MODULE); if (result == null) { @@ -74,6 +75,9 @@ public class ProjectStructureUtil { if (kind instanceof TargetPlatformKind.JavaScript) { return JsPlatform.INSTANCE; } + if (kind instanceof TargetPlatformKind.Default) { + return TargetPlatform.Default.INSTANCE; + } return null; } diff --git a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt index ca51c0a3756..0c2fd311d3a 100644 --- a/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt +++ b/idea/idea-jps-common/src/org/jetbrains/kotlin/config/KotlinFacetSettings.kt @@ -41,8 +41,10 @@ sealed class TargetPlatformKind( object JavaScript : TargetPlatformKind(NoVersion, "JavaScript") + object Default : TargetPlatformKind(NoVersion, "Default (experimental)") + companion object { - val ALL_PLATFORMS: List> by lazy { Jvm.JVM_PLATFORMS + JavaScript } + val ALL_PLATFORMS: List> by lazy { Jvm.JVM_PLATFORMS + JavaScript + Default } } } diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/FrameworkLibraryValidatorWithDynamicDescription.kt b/idea/src/org/jetbrains/kotlin/idea/facet/FrameworkLibraryValidatorWithDynamicDescription.kt index 18c451d388e..13351ca7bec 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/FrameworkLibraryValidatorWithDynamicDescription.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/FrameworkLibraryValidatorWithDynamicDescription.kt @@ -26,6 +26,7 @@ import com.intellij.openapi.roots.ui.configuration.libraries.AddCustomLibraryDia import com.intellij.openapi.roots.ui.configuration.libraries.CustomLibraryDescription import com.intellij.openapi.roots.ui.configuration.libraries.LibraryPresentationManager import org.jetbrains.kotlin.config.TargetPlatformKind +import org.jetbrains.kotlin.idea.framework.CommonStandardLibraryDescription import org.jetbrains.kotlin.idea.framework.JSLibraryStdDescription import org.jetbrains.kotlin.idea.framework.JavaRuntimeLibraryDescription import javax.swing.JComponent @@ -43,6 +44,7 @@ class FrameworkLibraryValidatorWithDynamicDescription( return when (this) { is TargetPlatformKind.Jvm -> JavaRuntimeLibraryDescription(project) is TargetPlatformKind.JavaScript -> JSLibraryStdDescription(project) + is TargetPlatformKind.Default -> CommonStandardLibraryDescription(project) } } @@ -70,6 +72,9 @@ class FrameworkLibraryValidatorWithDynamicDescription( } if (found) return ValidationResult.OK + // TODO: propose to configure kotlin-stdlib-common once it's available + if (targetPlatform == TargetPlatformKind.Default) return ValidationResult.OK + return ValidationResult( IdeBundle.message("label.missed.libraries.text", libraryCategoryName), LibrariesQuickFix(libraryDescription) diff --git a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt index 4d524838efc..18ea83c8658 100644 --- a/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt +++ b/idea/src/org/jetbrains/kotlin/idea/facet/facetUtils.kt @@ -35,7 +35,10 @@ import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCommonCompilerArgu import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings import org.jetbrains.kotlin.idea.framework.JSLibraryStdPresentationProvider import org.jetbrains.kotlin.idea.framework.JavaRuntimePresentationProvider -import org.jetbrains.kotlin.idea.versions.* +import org.jetbrains.kotlin.idea.versions.MAVEN_COMMON_STDLIB_ID +import org.jetbrains.kotlin.idea.versions.MAVEN_JS_STDLIB_ID +import org.jetbrains.kotlin.idea.versions.MAVEN_STDLIB_ID +import org.jetbrains.kotlin.idea.versions.bundledRuntimeVersion private fun getRuntimeLibraryVersions( module: Module, @@ -45,6 +48,7 @@ private fun getRuntimeLibraryVersions( val presentationProvider = when (targetPlatform) { is TargetPlatformKind.JavaScript -> JSLibraryStdPresentationProvider.getInstance() is TargetPlatformKind.Jvm -> JavaRuntimePresentationProvider.getInstance() + is TargetPlatformKind.Default -> return emptyList() } KotlinVersionInfoProvider.EP_NAME @@ -62,7 +66,7 @@ private fun getRuntimeLibraryVersions( } private fun getDefaultTargetPlatform(module: Module, rootModel: ModuleRootModel?): TargetPlatformKind<*> { - if (getRuntimeLibraryVersions(module, rootModel, TargetPlatformKind.JavaScript).any()) { + if (getRuntimeLibraryVersions(module, rootModel, TargetPlatformKind.JavaScript).isNotEmpty()) { return TargetPlatformKind.JavaScript } @@ -135,6 +139,7 @@ val TargetPlatformKind<*>.mavenLibraryId: String get() = when (this) { is TargetPlatformKind.Jvm -> MAVEN_STDLIB_ID is TargetPlatformKind.JavaScript -> MAVEN_JS_STDLIB_ID + is TargetPlatformKind.Default -> MAVEN_COMMON_STDLIB_ID } fun Module.getOrCreateFacet(modelsProvider: IdeModifiableModelsProvider): KotlinFacet { diff --git a/idea/src/org/jetbrains/kotlin/idea/framework/CommonStandardLibraryDescription.kt b/idea/src/org/jetbrains/kotlin/idea/framework/CommonStandardLibraryDescription.kt new file mode 100644 index 00000000000..018deb4e012 --- /dev/null +++ b/idea/src/org/jetbrains/kotlin/idea/framework/CommonStandardLibraryDescription.kt @@ -0,0 +1,34 @@ +/* + * Copyright 2010-2016 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.framework + +import com.intellij.openapi.project.Project +import com.intellij.openapi.roots.libraries.LibraryKind + +class CommonStandardLibraryDescription(project: Project?) : CustomLibraryDescriptorWithDeferredConfig( + // TODO: KotlinCommonModuleConfigurator + project, "common", LIBRARY_NAME, DIALOG_TITLE, LIBRARY_CAPTION, KOTLIN_COMMON_STDLIB_KIND, SUITABLE_LIBRARY_KINDS +) { + companion object { + val KOTLIN_COMMON_STDLIB_KIND = LibraryKind.create("kotlin-stdlib-common") + val LIBRARY_NAME = "KotlinStdlibCommon" + + val DIALOG_TITLE = "Create Kotlin Common Standard Library" + val LIBRARY_CAPTION = "Kotlin Common Standard Library" + val SUITABLE_LIBRARY_KINDS: Set = setOf(KOTLIN_COMMON_STDLIB_KIND) + } +} diff --git a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt index d3a0e46751c..0da63904cf3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt +++ b/idea/src/org/jetbrains/kotlin/idea/versions/KotlinRuntimeLibraryUtil.kt @@ -289,3 +289,4 @@ fun getKotlinJsRuntimeMarkerClass(project: Project, scope: GlobalSearchScope): V val MAVEN_STDLIB_ID = "kotlin-stdlib" val MAVEN_JS_STDLIB_ID = "kotlin-js-library" +val MAVEN_COMMON_STDLIB_ID = "kotlin-stdlib-common" // TODO: KotlinCommonMavenConfigurator