Don't show IR_COMPILED_CLASS error in IJ when it arises in module with backend IR enabled

The problem here is that library resolver uses global project compiler
settings instead of the module ones. That behaviour is caused by more
global problem described in #KT-21246

As a temporary solution we just do not show IR_COMPILED_CLASS error in
IDE if it arises in a module which have -XuseIR or
-Xallow-jvm-ir-dependencies option provided

#KT-36907 fixed
This commit is contained in:
Ilya Kirillov
2020-02-27 17:36:00 +03:00
parent 7a4d414c59
commit 97e320b57f
2 changed files with 33 additions and 0 deletions
@@ -30,6 +30,8 @@ import com.intellij.psi.MultiRangeReference
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiFile
import com.intellij.util.containers.MultiMap
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.diagnostics.Diagnostic
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
@@ -41,10 +43,12 @@ import org.jetbrains.kotlin.idea.fir.firResolveState
import org.jetbrains.kotlin.idea.fir.getOrBuildFirWithDiagnostics
import org.jetbrains.kotlin.idea.quickfix.QuickFixes
import org.jetbrains.kotlin.idea.references.mainReference
import org.jetbrains.kotlin.idea.util.module
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.diagnostics.Diagnostics
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import java.lang.reflect.*
import java.util.*
@@ -236,6 +240,9 @@ private class ElementAnnotator(
val diagnostic = diagnostics.first()
val factory = diagnostic.factory
// hack till the root cause #KT-21246 is fixed
if (isIrCompileClassDiagnosticForModulesWithEnabledIR(diagnostic)) return
assert(diagnostics.all { it.psiElement == element && it.factory == factory })
val ranges = diagnostic.textRanges
@@ -314,6 +321,14 @@ private class ElementAnnotator(
data.processDiagnostics(holder, diagnostics, fixesMap)
}
private fun isIrCompileClassDiagnosticForModulesWithEnabledIR(diagnostic: Diagnostic): Boolean {
if (diagnostic.factory != Errors.IR_COMPILED_CLASS) return false
val module = element.module ?: return false
val moduleFacetSettings = KotlinFacetSettingsProvider.getInstance(element.project)?.getSettings(module) ?: return false
return moduleFacetSettings.isCompilerSettingPresent(K2JVMCompilerArguments::useIR)
|| moduleFacetSettings.isCompilerSettingPresent(K2JVMCompilerArguments::allowJvmIrDependencies)
}
companion object {
val LOG = Logger.getInstance(ElementAnnotator::class.java)
}
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.config
import com.intellij.openapi.components.ServiceManager
import com.intellij.openapi.module.Module
import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.cli.common.arguments.Argument
import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments
import org.jetbrains.kotlin.cli.common.arguments.copyBean
import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments
@@ -18,6 +19,9 @@ import org.jetbrains.kotlin.platform.compat.toIdePlatform
import org.jetbrains.kotlin.platform.isCommon
import org.jetbrains.kotlin.platform.jvm.JvmPlatforms
import org.jetbrains.kotlin.utils.DescriptionAware
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
import kotlin.reflect.KProperty1
import kotlin.reflect.full.findAnnotation
@Deprecated("Use IdePlatformKind instead.", level = DeprecationLevel.ERROR)
sealed class TargetPlatformKind<out Version : TargetPlatformVersion>(
@@ -188,6 +192,20 @@ class KotlinFacetSettings {
updateMergedArguments()
}
/*
This function is needed as some setting values may not be present in compilerArguments
but present in additional arguments instead, so we have to check both cases manually
*/
inline fun <reified A : CommonCompilerArguments> isCompilerSettingPresent(settingReference: KProperty1<A, Boolean>): Boolean {
val isEnabledByCompilerArgument = compilerArguments?.safeAs<A>()?.let(settingReference::get)
if (isEnabledByCompilerArgument == true) return true
val isEnabledByAdditionalSettings = run {
val stringArgumentName = settingReference.findAnnotation<Argument>()?.value ?: return@run null
compilerSettings?.additionalArguments?.contains(stringArgumentName, ignoreCase = true)
}
return isEnabledByAdditionalSettings ?: false
}
var languageLevel: LanguageVersion?
get() = compilerArguments?.languageVersion?.let { LanguageVersion.fromFullVersionString(it) }
set(value) {