diff --git a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt index c9dbfb21593..f969b5de5f0 100644 --- a/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt +++ b/compiler/frontend/src/org/jetbrains/kotlin/resolve/checkers/ExperimentalUsageChecker.kt @@ -66,7 +66,7 @@ class ExperimentalUsageChecker(project: Project) : CallChecker { } companion object { - internal val EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental") + val EXPERIMENTAL_FQ_NAME = FqName("kotlin.Experimental") internal val USE_EXPERIMENTAL_FQ_NAME = FqName("kotlin.UseExperimental") internal val USE_EXPERIMENTAL_ANNOTATION_CLASS = Name.identifier("markerClass") diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt index dcb4061548b..5aaf9bb1304 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRenderer.kt @@ -9,6 +9,7 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor import org.jetbrains.kotlin.descriptors.annotations.AnnotationUseSiteTarget +import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqNameUnsafe import org.jetbrains.kotlin.name.Name @@ -190,6 +191,7 @@ interface DescriptorRendererOptions { var textFormat: RenderingFormat var excludedAnnotationClasses: Set var excludedTypeAnnotationClasses: Set + var annotationFilter: ((AnnotationDescriptor) -> Boolean)? var annotationArgumentsRenderingPolicy: AnnotationArgumentsRenderingPolicy val includeAnnotationArguments: Boolean get() = annotationArgumentsRenderingPolicy.includeAnnotationArguments diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt index 59819dcc657..768012e71a8 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererImpl.kt @@ -396,8 +396,9 @@ internal class DescriptorRendererImpl( val excluded = if (annotated is KotlinType) excludedTypeAnnotationClasses else excludedAnnotationClasses + val annotationFilter = annotationFilter for ((annotation, target) in annotated.annotations.getAllAnnotations()) { - if (annotation.fqName !in excluded) { + if (annotation.fqName !in excluded && (annotationFilter == null || annotationFilter(annotation))) { append(renderAnnotation(annotation, target)).append(" ") } } diff --git a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt index b45fa9fb5e7..5687130839f 100644 --- a/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt +++ b/core/descriptors/src/org/jetbrains/kotlin/renderer/DescriptorRendererOptionsImpl.kt @@ -17,6 +17,8 @@ package org.jetbrains.kotlin.renderer import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor +import org.jetbrains.kotlin.descriptors.annotations.AnnotationWithTarget import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.types.KotlinType import java.lang.IllegalStateException @@ -98,6 +100,8 @@ internal class DescriptorRendererOptionsImpl : DescriptorRendererOptions { override var excludedTypeAnnotationClasses by property(ExcludedTypeAnnotations.internalAnnotationsForResolve) + override var annotationFilter: ((AnnotationDescriptor) -> Boolean)? by property(null) + override var annotationArgumentsRenderingPolicy by property(AnnotationArgumentsRenderingPolicy.NO_ARGUMENTS) override var alwaysRenderModifiers by property(false) diff --git a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt index bbab3f2e44c..de1ae802103 100644 --- a/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt +++ b/idea/idea-core/src/org/jetbrains/kotlin/idea/core/overrideImplement/OverrideMemberChooserObject.kt @@ -38,6 +38,7 @@ import org.jetbrains.kotlin.psi.findDocComment.findDocComment import org.jetbrains.kotlin.psi.psiUtil.hasActualModifier import org.jetbrains.kotlin.psi.psiUtil.hasExpectModifier import org.jetbrains.kotlin.renderer.* +import org.jetbrains.kotlin.resolve.checkers.ExperimentalUsageChecker import org.jetbrains.kotlin.resolve.descriptorUtil.setSingleOverridden interface OverrideMemberChooserObject : ClassMember { @@ -138,13 +139,16 @@ fun OverrideMemberChooserObject.generateMember(targetClass: KtClassOrObject, cop private val OVERRIDE_RENDERER = DescriptorRenderer.withOptions { defaultParameterValueRenderer = null - modifiers = setOf(DescriptorRendererModifier.OVERRIDE) + modifiers = setOf(DescriptorRendererModifier.OVERRIDE, DescriptorRendererModifier.ANNOTATIONS) withDefinedIn = false classifierNamePolicy = ClassifierNamePolicy.SOURCE_CODE_QUALIFIED overrideRenderingPolicy = OverrideRenderingPolicy.RENDER_OVERRIDE unitReturnType = false typeNormalizer = IdeDescriptorRenderers.APPROXIMATE_FLEXIBLE_TYPES renderUnabbreviatedType = false + annotationFilter = { + it.type.constructor.declarationDescriptor?.annotations?.hasAnnotation(ExperimentalUsageChecker.EXPERIMENTAL_FQ_NAME) ?: false + } } private fun PropertyDescriptor.wrap(): PropertyDescriptor { diff --git a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt index aa8cc6e8981..0365928d2c0 100644 --- a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt +++ b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt @@ -28,11 +28,11 @@ import com.intellij.psi.search.ProjectScope import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.LoggedErrorProcessor import org.apache.log4j.Logger -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode +import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.configureFacet import org.jetbrains.kotlin.idea.facet.getOrCreateFacet import org.jetbrains.kotlin.psi.KtFile @@ -186,30 +186,44 @@ fun configureCompilerOptions(fileText: String, project: Project, module: Module) val version = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// LANGUAGE_VERSION: ") val jvmTarget = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// JVM_TARGET: ") val options = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// COMPILER_ARGUMENTS: ") - if (version != null || jvmTarget != null || options != null) { - val accessToken = WriteAction.start() - try { - val modelsProvider = IdeModifiableModelsProviderImpl(project) - val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false) - facet.configureFacet( - version ?: LanguageVersion.LATEST_STABLE.versionString, - LanguageFeature.State.DISABLED, - if (jvmTarget != null) TargetPlatformKind.Jvm(JvmTarget.fromString(jvmTarget)!!) else null, - modelsProvider - ) - if (options != null) { - val compilerSettings = facet.configuration.settings.compilerSettings ?: CompilerSettings().also { - facet.configuration.settings.compilerSettings = it - } - compilerSettings.additionalArguments = options - facet.configuration.settings.updateMergedArguments() + if (version != null || jvmTarget != null || options != null) { + configureLanguageAndApiVersion(project, module, version ?: LanguageVersion.LATEST_STABLE.versionString) + + val facetSettings = KotlinFacet.get(module)!!.configuration.settings + + if (jvmTarget != null) { + (facetSettings.compilerArguments as K2JVMCompilerArguments).jvmTarget = jvmTarget + } + + if (options != null) { + val compilerSettings = facetSettings.compilerSettings ?: CompilerSettings().also { + facetSettings.compilerSettings = it } - modelsProvider.commit() + compilerSettings.additionalArguments = options + facetSettings.updateMergedArguments() } - finally { - accessToken.finish() + } +} + +fun configureLanguageAndApiVersion( + project: Project, + module: Module, + languageVersion: String, + apiVersion: String? = null +) { + val accessToken = WriteAction.start() + try { + val modelsProvider = IdeModifiableModelsProviderImpl(project) + val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false) + facet.configureFacet(languageVersion, LanguageFeature.State.DISABLED, null, modelsProvider) + if (apiVersion != null) { + facet.configuration.settings.apiLevel = LanguageVersion.fromVersionString(apiVersion) } + modelsProvider.commit() + } + finally { + accessToken.finish() } } diff --git a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt.181 b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt.181 index 94e97f66be8..8a2bb5c1b7e 100644 --- a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt.181 +++ b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/KotlinLightCodeInsightFixtureTestCase.kt.181 @@ -28,11 +28,11 @@ import com.intellij.psi.search.ProjectScope import com.intellij.testFramework.LightProjectDescriptor import com.intellij.testFramework.LoggedErrorProcessor import org.apache.log4j.Logger -import org.jetbrains.kotlin.cli.common.arguments.CommonCompilerArguments -import org.jetbrains.kotlin.cli.common.arguments.parseCommandLineArguments +import org.jetbrains.kotlin.cli.common.arguments.K2JVMCompilerArguments import org.jetbrains.kotlin.config.* import org.jetbrains.kotlin.idea.KotlinFileType import org.jetbrains.kotlin.idea.actions.internal.KotlinInternalMode +import org.jetbrains.kotlin.idea.facet.KotlinFacet import org.jetbrains.kotlin.idea.facet.configureFacet import org.jetbrains.kotlin.idea.facet.getOrCreateFacet import org.jetbrains.kotlin.psi.KtFile @@ -185,30 +185,44 @@ fun configureCompilerOptions(fileText: String, project: Project, module: Module) val version = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// LANGUAGE_VERSION: ") val jvmTarget = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// JVM_TARGET: ") val options = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// COMPILER_ARGUMENTS: ") - if (version != null || jvmTarget != null || options != null) { - val accessToken = WriteAction.start() - try { - val modelsProvider = IdeModifiableModelsProviderImpl(project) - val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false) - facet.configureFacet( - version ?: LanguageVersion.LATEST_STABLE.versionString, - LanguageFeature.State.DISABLED, - if (jvmTarget != null) TargetPlatformKind.Jvm(JvmTarget.fromString(jvmTarget)!!) else null, - modelsProvider - ) - if (options != null) { - val compilerSettings = facet.configuration.settings.compilerSettings ?: CompilerSettings().also { - facet.configuration.settings.compilerSettings = it - } - compilerSettings.additionalArguments = options - facet.configuration.settings.updateMergedArguments() - } - modelsProvider.commit() + if (version != null) { + configureLanguageAndApiVersion(project, module, version) + } + + val facetSettings = KotlinFacet.get(module)!!.configuration.settings + + if (jvmTarget != null) { + (facetSettings.compilerArguments as K2JVMCompilerArguments).jvmTarget = jvmTarget + } + + if (options != null) { + val compilerSettings = facetSettings.compilerSettings ?: CompilerSettings().also { + facetSettings.compilerSettings = it } - finally { - accessToken.finish() + compilerSettings.additionalArguments = options + facetSettings.updateMergedArguments() + } +} + +fun configureLanguageAndApiVersion( + project: Project, + module: Module, + languageVersion: String, + apiVersion: String? = null +) { + val accessToken = WriteAction.start() + try { + val modelsProvider = IdeModifiableModelsProviderImpl(project) + val facet = module.getOrCreateFacet(modelsProvider, useProjectSettings = false) + facet.configureFacet(languageVersion, LanguageFeature.State.DISABLED, null, modelsProvider) + if (apiVersion != null) { + facet.configuration.settings.apiLevel = LanguageVersion.fromVersionString(apiVersion) } + modelsProvider.commit() + } + finally { + accessToken.finish() } } diff --git a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/testUtils.kt b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/testUtils.kt index e45837ff465..aceb6a4fba8 100644 --- a/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/testUtils.kt +++ b/idea/idea-test-framework/test/org/jetbrains/kotlin/idea/test/testUtils.kt @@ -37,6 +37,7 @@ import org.jetbrains.kotlin.idea.decompiler.KotlinDecompiledFileViewProvider import org.jetbrains.kotlin.idea.decompiler.KtDecompiledFile import org.jetbrains.kotlin.idea.util.application.runWriteAction import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.InTextDirectivesUtils import java.util.* enum class ModuleKind { @@ -73,6 +74,8 @@ fun Module.configureAs(kind: ModuleKind) { } fun KtFile.dumpTextWithErrors(): String { + val text = text + if (InTextDirectivesUtils.isDirectiveDefined(text, "// DISABLE-ERRORS")) return text val diagnostics = analyzeWithContent().diagnostics val errors = diagnostics.filter { it.severity == Severity.ERROR } if (errors.isEmpty()) return text diff --git a/idea/testData/codeInsight/overrideImplement/copyExperimental.kt b/idea/testData/codeInsight/overrideImplement/copyExperimental.kt new file mode 100644 index 00000000000..c534b841d2a --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/copyExperimental.kt @@ -0,0 +1,12 @@ +// DISABLE-ERRORS + +@Experimental +annotation class FirstExperience + +open class ParentTarget { + @FirstExperience open fun targetFun() {} +} + +class ChildTarget : ParentTarget() { + +} \ No newline at end of file diff --git a/idea/testData/codeInsight/overrideImplement/copyExperimental.kt.after b/idea/testData/codeInsight/overrideImplement/copyExperimental.kt.after new file mode 100644 index 00000000000..2c727206b58 --- /dev/null +++ b/idea/testData/codeInsight/overrideImplement/copyExperimental.kt.after @@ -0,0 +1,15 @@ +// DISABLE-ERRORS + +@Experimental +annotation class FirstExperience + +open class ParentTarget { + @FirstExperience open fun targetFun() {} +} + +class ChildTarget : ParentTarget() { + @FirstExperience + override fun targetFun() { + super.targetFun() + } +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt index 71f36fb8d76..a78f7ed37ef 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/codeInsight/OverrideImplementTest.kt @@ -17,6 +17,7 @@ package org.jetbrains.kotlin.idea.codeInsight import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.idea.test.configureLanguageAndApiVersion class OverrideImplementTest : AbstractOverrideImplementTest() { override fun setUp() { @@ -279,4 +280,9 @@ class OverrideImplementTest : AbstractOverrideImplementTest() { fun testDataClassEquals() { doOverrideFileTest("equals") } + + fun testCopyExperimental() { + configureLanguageAndApiVersion(project, module, "1.3", "1.3") + doOverrideFileTest("targetFun") + } }