Load JSR-305 annotations for libraries if it's enabled for any module
#KT-19303 Fixed
This commit is contained in:
+1
-1
@@ -166,7 +166,7 @@ class K2JVMCompilerArguments : CommonCompilerArguments() {
|
||||
|
||||
override fun configureAnalysisFlags(): MutableMap<AnalysisFlag<*>, Any> {
|
||||
val result = super.configureAnalysisFlags()
|
||||
Jsr305State.values().firstOrNull { it.description == jsr305GlobalReportLevel }?.let {
|
||||
Jsr305State.findByDescription(jsr305GlobalReportLevel)?.let {
|
||||
result.put(AnalysisFlag.loadJsr305Annotations, it)
|
||||
}
|
||||
return result
|
||||
|
||||
@@ -68,5 +68,7 @@ enum class Jsr305State(
|
||||
companion object {
|
||||
@JvmField
|
||||
val DEFAULT: Jsr305State = IGNORE
|
||||
|
||||
fun findByDescription(description: String?) = values().firstOrNull { it.description == description }
|
||||
}
|
||||
}
|
||||
|
||||
+24
-4
@@ -16,19 +16,39 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.compiler
|
||||
|
||||
import com.intellij.openapi.module.ModuleManager
|
||||
import com.intellij.openapi.project.Project
|
||||
import org.jetbrains.kotlin.analyzer.LanguageSettingsProvider
|
||||
import org.jetbrains.kotlin.analyzer.ModuleInfo
|
||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||
import org.jetbrains.kotlin.config.TargetPlatformVersion
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.config.*
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.LibraryInfo
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.ModuleSourceInfo
|
||||
import org.jetbrains.kotlin.idea.project.getLanguageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.languageVersionSettings
|
||||
import org.jetbrains.kotlin.idea.project.targetPlatform
|
||||
|
||||
object IDELanguageSettingsProvider : LanguageSettingsProvider {
|
||||
override fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project): LanguageVersionSettings {
|
||||
return (moduleInfo as? ModuleSourceInfo)?.module?.languageVersionSettings ?: project.getLanguageVersionSettings()
|
||||
override fun getLanguageVersionSettings(moduleInfo: ModuleInfo, project: Project): LanguageVersionSettings =
|
||||
when (moduleInfo) {
|
||||
is ModuleSourceInfo -> moduleInfo.module.languageVersionSettings
|
||||
is LibraryInfo -> project.getLanguageVersionSettings(extraAnalysisFlags = getExtraAnalysisFlags(project))
|
||||
else -> project.getLanguageVersionSettings()
|
||||
}
|
||||
|
||||
private fun getExtraAnalysisFlags(project: Project): Map<AnalysisFlag<*>, Any?> {
|
||||
val map = mutableMapOf<AnalysisFlag<*>, Any>()
|
||||
for (module in ModuleManager.getInstance(project).modules) {
|
||||
val settings = KotlinFacetSettingsProvider.getInstance(project).getSettings(module) ?: continue
|
||||
val compilerArguments = settings.compilerArguments as? K2JVMCompilerArguments ?: continue
|
||||
|
||||
val jsr305state = Jsr305State.findByDescription(compilerArguments.jsr305GlobalReportLevel)
|
||||
if (jsr305state != null && jsr305state != Jsr305State.IGNORE) {
|
||||
map.put(AnalysisFlag.loadJsr305Annotations, jsr305state)
|
||||
break
|
||||
}
|
||||
}
|
||||
return map
|
||||
}
|
||||
|
||||
override fun getTargetPlatform(moduleInfo: ModuleInfo): TargetPlatformVersion {
|
||||
|
||||
@@ -74,7 +74,9 @@ fun Module.getAndCacheLanguageLevelByDependencies(): LanguageVersion {
|
||||
return languageLevel
|
||||
}
|
||||
|
||||
fun Project.getLanguageVersionSettings(contextModule: Module? = null): LanguageVersionSettings {
|
||||
@JvmOverloads
|
||||
fun Project.getLanguageVersionSettings(contextModule: Module? = null,
|
||||
extraAnalysisFlags: Map<AnalysisFlag<*>, Any?> = emptyMap()): LanguageVersionSettings {
|
||||
val arguments = KotlinCommonCompilerArgumentsHolder.getInstance(this).settings
|
||||
val languageVersion =
|
||||
LanguageVersion.fromVersionString(arguments.languageVersion)
|
||||
@@ -88,7 +90,9 @@ fun Project.getLanguageVersionSettings(contextModule: Module? = null): LanguageV
|
||||
compilerSettings,
|
||||
null
|
||||
)
|
||||
return LanguageVersionSettingsImpl(languageVersion, apiVersion, arguments.configureAnalysisFlags(), extraLanguageFeatures)
|
||||
return LanguageVersionSettingsImpl(languageVersion, apiVersion,
|
||||
arguments.configureAnalysisFlags() + extraAnalysisFlags,
|
||||
extraLanguageFeatures)
|
||||
}
|
||||
|
||||
val Module.languageVersionSettings: LanguageVersionSettings
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
package foo;
|
||||
|
||||
import javax.annotation.*;
|
||||
|
||||
@FieldsAreNullable
|
||||
public class A {
|
||||
public String field = null;
|
||||
@Nonnull
|
||||
public String nonNullField = "";
|
||||
|
||||
public String foo(String q, @Nonnull String x, @CheckForNull CharSequence y) {
|
||||
return "";
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public String bar() {
|
||||
return "";
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
package foo;
|
||||
|
||||
import java.lang.annotation.Documented;
|
||||
import java.lang.annotation.ElementType;
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.RetentionPolicy;
|
||||
import java.lang.annotation.Target;
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.CheckForNull;
|
||||
import javax.annotation.meta.TypeQualifierDefault;
|
||||
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Documented
|
||||
@CheckForNull
|
||||
@TypeQualifierDefault({ElementType.FIELD})
|
||||
public @interface FieldsAreNullable {
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
import foo.A
|
||||
|
||||
fun main(a: A) {
|
||||
a.field<error descr="[UNSAFE_CALL] Only safe (?.) or non-null asserted (!!.) calls are allowed on a nullable receiver of type String?">.</error>length
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.findUsages
|
||||
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||
import org.jetbrains.kotlin.idea.stubs.createFacet
|
||||
import org.junit.Test
|
||||
|
||||
class FindUsagesMultiModuleTest : AbstractFindUsagesMultiModuleTest() {
|
||||
|
||||
+1
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||
import org.jetbrains.kotlin.idea.framework.CommonLibraryKind
|
||||
import org.jetbrains.kotlin.idea.stubs.AbstractMultiHighlightingTest
|
||||
import org.jetbrains.kotlin.idea.stubs.createFacet
|
||||
import org.jetbrains.kotlin.test.TestJdkKind
|
||||
|
||||
abstract class AbstractMultiModuleHighlightingTest : AbstractMultiHighlightingTest() {
|
||||
|
||||
@@ -0,0 +1,60 @@
|
||||
/*
|
||||
* 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.openapi.module.Module
|
||||
import com.intellij.openapi.roots.ModifiableRootModel
|
||||
import com.intellij.testFramework.LightProjectDescriptor
|
||||
import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments
|
||||
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime
|
||||
import org.jetbrains.kotlin.config.Jsr305State
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.KotlinFacetSettingsProvider
|
||||
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||
import org.jetbrains.kotlin.idea.stubs.createFacet
|
||||
import org.jetbrains.kotlin.idea.test.KotlinJdkAndLibraryProjectDescriptor
|
||||
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
|
||||
import org.jetbrains.kotlin.test.MockLibraryUtil
|
||||
|
||||
class Jsr305HighlightingTest : KotlinLightCodeInsightFixtureTestCase() {
|
||||
override fun getProjectDescriptor(): LightProjectDescriptor {
|
||||
val foreignAnnotationsJar = MockLibraryUtil.compileJvmLibraryToJar("compiler/testData/foreignAnnotations/annotations", "foreign-annotations")
|
||||
val libraryJar = MockLibraryUtil.compileJvmLibraryToJar("idea/testData/highlighterJsr305/library", "jsr305-library",
|
||||
extraClasspath = listOf(foreignAnnotationsJar.absolutePath))
|
||||
return object : KotlinJdkAndLibraryProjectDescriptor(
|
||||
listOf(
|
||||
ForTestCompileRuntime.runtimeJarForTests(),
|
||||
foreignAnnotationsJar,
|
||||
libraryJar
|
||||
)
|
||||
) {
|
||||
override fun configureModule(module: Module, model: ModifiableRootModel) {
|
||||
super.configureModule(module, model)
|
||||
module.createFacet(TargetPlatformKind.Jvm(JvmTarget.JVM_1_8))
|
||||
val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(module)
|
||||
(facetSettings.compilerArguments as K2JVMCompilerArguments).jsr305GlobalReportLevel = Jsr305State.ENABLE.description
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun testSimple() {
|
||||
myFixture.configureByFile("A.kt")
|
||||
myFixture.checkHighlighting()
|
||||
}
|
||||
|
||||
override fun getTestDataPath() = "idea/testData/highlighterJsr305/project"
|
||||
}
|
||||
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.idea.quickfix
|
||||
|
||||
import org.jetbrains.kotlin.config.JvmTarget
|
||||
import org.jetbrains.kotlin.config.TargetPlatformKind
|
||||
import org.jetbrains.kotlin.idea.stubs.createFacet
|
||||
import org.junit.Test
|
||||
|
||||
class QuickFixMultiModuleTest : AbstractQuickFixMultiModuleTest() {
|
||||
|
||||
@@ -96,22 +96,6 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() {
|
||||
}, this, kind)
|
||||
}
|
||||
|
||||
protected fun Module.createFacet(platformKind: TargetPlatformKind<*>? = null) {
|
||||
val accessToken = WriteAction.start()
|
||||
try {
|
||||
val modelsProvider = IdeModifiableModelsProviderImpl(project)
|
||||
getOrCreateFacet(modelsProvider, true).configuration.settings.initializeIfNeeded(
|
||||
this,
|
||||
modelsProvider.getModifiableRootModel(this),
|
||||
platformKind
|
||||
)
|
||||
modelsProvider.commit()
|
||||
}
|
||||
finally {
|
||||
accessToken.finish()
|
||||
}
|
||||
}
|
||||
|
||||
protected fun Module.enableMultiPlatform() {
|
||||
createFacet()
|
||||
val facetSettings = KotlinFacetSettingsProvider.getInstance(project).getInitializedSettings(this)
|
||||
@@ -132,3 +116,19 @@ abstract class AbstractMultiModuleTest : DaemonAnalyzerTestCase() {
|
||||
Assert.assertTrue(atLeastOneFile)
|
||||
}
|
||||
}
|
||||
|
||||
fun Module.createFacet(platformKind: TargetPlatformKind<*>? = null) {
|
||||
val accessToken = WriteAction.start()
|
||||
try {
|
||||
val modelsProvider = IdeModifiableModelsProviderImpl(project)
|
||||
getOrCreateFacet(modelsProvider, true).configuration.settings.initializeIfNeeded(
|
||||
this,
|
||||
modelsProvider.getModifiableRootModel(this),
|
||||
platformKind
|
||||
)
|
||||
modelsProvider.commit()
|
||||
}
|
||||
finally {
|
||||
accessToken.finish()
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user