From b8f8802cff157c3fa4e091d984eb986a5922b925 Mon Sep 17 00:00:00 2001 From: Dmitry Savvinov Date: Tue, 29 May 2018 16:05:53 +0300 Subject: [PATCH] Parse compiler arguments and configure LV properly in Platform.kt --- .../compiler/IDELanguageSettingsProvider.kt | 13 +- .../jetbrains/kotlin/idea/project/Platform.kt | 120 +++++++++--------- 2 files changed, 64 insertions(+), 69 deletions(-) diff --git a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt index e382cfcd7d6..c8c8f7d354b 100644 --- a/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt +++ b/idea/idea-analysis/src/org/jetbrains/kotlin/idea/compiler/IDELanguageSettingsProvider.kt @@ -38,31 +38,32 @@ import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings import org.jetbrains.kotlin.idea.project.languageVersionSettings import org.jetbrains.kotlin.idea.project.targetPlatform import org.jetbrains.kotlin.script.KotlinScriptDefinition +import org.jetbrains.kotlin.utils.Jsr305State object IDELanguageSettingsProvider : LanguageSettingsProvider { override fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project): LanguageVersionSettings = when (moduleInfo) { is ModuleSourceInfo -> moduleInfo.module.languageVersionSettings - is LibraryInfo -> project.getLanguageVersionSettings(extraAnalysisFlags = getExtraAnalysisFlags(project)) + is LibraryInfo -> project.getLanguageVersionSettings(jsr305State = computeJsr305State(project)) is ScriptModuleInfo -> getVersionLanguageSettingsForScripts(project, moduleInfo.scriptDefinition) is ScriptDependenciesInfo.ForFile -> getVersionLanguageSettingsForScripts(project, moduleInfo.scriptDefinition) is PlatformModuleInfo -> moduleInfo.platformModule.module.languageVersionSettings else -> project.getLanguageVersionSettings() } - private fun getExtraAnalysisFlags(project: Project): Map, Any?> { - val map = mutableMapOf, Any>() + private fun computeJsr305State(project: Project): Jsr305State? { + var result: Jsr305State? = null for (module in ModuleManager.getInstance(project).modules) { val settings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) ?: continue val compilerArguments = settings.mergedCompilerArguments as? K2JVMCompilerArguments ?: continue - val jsr305State = Jsr305Parser(MessageCollector.NONE).parse( + result = Jsr305Parser(MessageCollector.NONE).parse( compilerArguments.jsr305, compilerArguments.supportCompatqualCheckerFrameworkAnnotations ) - map.put(AnalysisFlag.jsr305, jsr305State) + } - return map + return result } override fun getTargetPlatform(moduleInfo: ModuleInfo): TargetPlatformVersion { 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 fa128556bc5..841024dbdf6 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 @@ -28,8 +28,7 @@ import com.intellij.psi.util.CachedValue import com.intellij.psi.util.CachedValueProvider import com.intellij.psi.util.CachedValuesManager import org.jetbrains.kotlin.builtins.KotlinBuiltIns -import org.jetbrains.kotlin.cli.common.arguments.Argument -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments +import org.jetbrains.kotlin.cli.common.arguments.* import org.jetbrains.kotlin.cli.common.messages.MessageCollector import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade @@ -39,6 +38,7 @@ import org.jetbrains.kotlin.idea.compiler.configuration.KotlinCompilerSettings import org.jetbrains.kotlin.idea.facet.getLibraryLanguageLevel import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.resolve.TargetPlatform +import org.jetbrains.kotlin.utils.Jsr305State val KtElement.platform: TargetPlatform get() = TargetPlatformDetector.getPlatform(containingKtFile) @@ -46,22 +46,6 @@ val KtElement.platform: TargetPlatform val KtElement.builtIns: KotlinBuiltIns get() = getResolutionFacade().moduleDescriptor.builtIns -private val multiPlatformProjectsArg: String by lazy { - CommonCompilerArguments::multiPlatform.annotations.filterIsInstance().single().value -} - -private val effectSystemArg: String by lazy { - CommonCompilerArguments::effectSystem.annotations.filterIsInstance().single().value -} - -private val readDeserializedContractsArg: String by lazy { - CommonCompilerArguments::readDeserializedContracts.annotations.filterIsInstance().single().value -} - -private val newInferenceArg: String by lazy { - CommonCompilerArguments::newInference.annotations.filterIsInstance().single().value -} - fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this) val languageLevel = getLibraryLanguageLevel(this, null, facetSettings.targetPlatformKind) @@ -93,7 +77,7 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion { @JvmOverloads fun Project.getLanguageVersionSettings( contextModule: Module? = null, - extraAnalysisFlags: Map, Any?> = emptyMap() + jsr305State: Jsr305State? = null // this is a temporary hack until we'll have a sane way to configure libraries analysis ): LanguageVersionSettings { val arguments = KotlinCommonCompilerArgumentsHolder.getInstance(this).settings val languageVersion = @@ -102,16 +86,24 @@ fun Project.getLanguageVersionSettings( ?: LanguageVersion.LATEST_STABLE val apiVersion = ApiVersion.createByLanguageVersion(LanguageVersion.fromVersionString(arguments.apiVersion) ?: languageVersion) val compilerSettings = KotlinCompilerSettings.getInstance(this).settings - val extraLanguageFeatures = getExtraLanguageFeatures( - null, - CoroutineSupport.byCompilerArguments(KotlinCommonCompilerArgumentsHolder.getInstance(this).settings), - compilerSettings, - null + + val additionalArguments: CommonCompilerArguments = parseArguments( + TargetPlatformKind.DEFAULT_PLATFORM, + compilerSettings.additionalArgumentsAsList ) + + val extraLanguageFeatures = additionalArguments.configureLanguageFeatures(MessageCollector.NONE).apply { + configureCoroutinesSupport(CoroutineSupport.byCompilerArguments(KotlinCommonCompilerArgumentsHolder.getInstance(this@getLanguageVersionSettings).settings)) + } + + val extraAnalysisFlags = additionalArguments.configureAnalysisFlags(MessageCollector.NONE).apply { + if (jsr305State != null) put(AnalysisFlag.jsr305, jsr305State) + } + return LanguageVersionSettingsImpl( languageVersion, apiVersion, arguments.configureAnalysisFlags(MessageCollector.NONE) + extraAnalysisFlags, - extraLanguageFeatures + arguments.configureLanguageFeatures(MessageCollector.NONE) + extraLanguageFeatures ) } @@ -137,26 +129,30 @@ private fun Module.createCachedValueForLanguageVersionSettings(): CachedValue, + additionalArguments: List +): CommonCompilerArguments { + val arguments = when (targetPlatformKind) { + is TargetPlatformKind.Jvm -> K2JVMCompilerArguments() + TargetPlatformKind.JavaScript -> K2JSCompilerArguments() + TargetPlatformKind.Common -> K2MetadataCompilerArguments() + } + + parseCommandLineArguments(additionalArguments, arguments) + + return arguments +} + +fun MutableMap.configureCoroutinesSupport(coroutineSupport: LanguageFeature.State) { + put(LanguageFeature.Coroutines, coroutineSupport) +} + +fun MutableMap.configureMultiplatformSupport( targetPlatformKind: TargetPlatformKind<*>?, - coroutineSupport: LanguageFeature.State, - compilerSettings: CompilerSettings?, module: Module? -): Map { - return mutableMapOf().apply { - put(LanguageFeature.Coroutines, coroutineSupport) - if (targetPlatformKind == TargetPlatformKind.Common || - // TODO: this is a dirty hack, parse arguments correctly here - compilerSettings?.additionalArguments?.contains(multiPlatformProjectsArg) == true || - (module != null && module.implementsCommonModule) - ) { - put(LanguageFeature.MultiPlatformProjects, LanguageFeature.State.ENABLED) - } - - if (compilerSettings?.additionalArguments?.contains(effectSystemArg) == true) { - put(LanguageFeature.UseReturnsEffect, LanguageFeature.State.ENABLED) - put(LanguageFeature.UseCallsInPlaceEffect, LanguageFeature.State.ENABLED) - } - - if (compilerSettings?.additionalArguments?.contains(readDeserializedContractsArg) == true) { - put(LanguageFeature.ReadDeserializedContracts, LanguageFeature.State.ENABLED) - } - - if (compilerSettings?.additionalArguments?.contains(newInferenceArg) == true) { - put(LanguageFeature.NewInference, LanguageFeature.State.ENABLED) - } +) { + if (targetPlatformKind == TargetPlatformKind.Common || module?.implementsCommonModule == true) { + put(LanguageFeature.MultiPlatformProjects, LanguageFeature.State.ENABLED) } } + val KtElement.languageVersionSettings: LanguageVersionSettings get() { if (ServiceManager.getService(project, ProjectFileIndex::class.java) == null) {