From 4285c6045a5acc525c1de10839acb112475f2c81 Mon Sep 17 00:00:00 2001 From: Leonid Startsev Date: Wed, 22 Jan 2020 14:13:36 +0300 Subject: [PATCH] Fix unavailable 'Specify visibility explicitly' quickfix in explicit API mode due to incorrect cast. Add tests for applying this quickfix. #KT-36020 fixed. --- .../idea/quickfix/ChangeVisibilityFix.kt | 9 +++-- .../class.kt | 5 +++ .../class.kt.after | 5 +++ .../companion.kt | 7 ++++ .../companion.kt.after | 7 ++++ .../constructor.kt | 7 ++++ .../constructor.kt.after | 7 ++++ .../method.kt | 6 +++ .../method.kt.after | 6 +++ .../property.kt | 5 +++ .../property.kt.after | 5 +++ .../QuickFixMultiFileTestGenerated.java | 13 +++++++ .../idea/quickfix/QuickFixTestGenerated.java | 38 +++++++++++++++++++ 13 files changed, 116 insertions(+), 4 deletions(-) create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt.after create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt.after create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt.after create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt.after create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt create mode 100644 idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt.after diff --git a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt index f086f7b8704..943e736d3c7 100644 --- a/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt +++ b/idea/src/org/jetbrains/kotlin/idea/quickfix/ChangeVisibilityFix.kt @@ -1,5 +1,5 @@ /* - * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ @@ -14,13 +14,14 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.descriptors.Visibility import org.jetbrains.kotlin.diagnostics.Diagnostic -import org.jetbrains.kotlin.diagnostics.DiagnosticFactory1 +import org.jetbrains.kotlin.diagnostics.DiagnosticFactory0 import org.jetbrains.kotlin.idea.core.canBeInternal import org.jetbrains.kotlin.idea.core.canBePrivate import org.jetbrains.kotlin.idea.core.canBeProtected import org.jetbrains.kotlin.idea.core.setVisibility import org.jetbrains.kotlin.idea.inspections.RemoveRedundantSetterFix import org.jetbrains.kotlin.idea.inspections.isRedundantSetter +import org.jetbrains.kotlin.idea.search.usagesSearch.descriptor import org.jetbrains.kotlin.idea.util.runOnExpectAndAllActuals import org.jetbrains.kotlin.lexer.KtModifierKeywordToken import org.jetbrains.kotlin.lexer.KtTokens @@ -121,8 +122,8 @@ open class ChangeVisibilityFix( object SetExplicitVisibilityFactory : KotlinIntentionActionsFactory() { @Suppress("UNCHECKED_CAST") override fun doCreateActions(diagnostic: Diagnostic): List { - val factory = diagnostic.factory as DiagnosticFactory1<*, DeclarationDescriptor> - val descriptor = factory.cast(diagnostic).a as? DeclarationDescriptorWithVisibility ?: return emptyList() + val factory = diagnostic.factory as DiagnosticFactory0 + val descriptor = factory.cast(diagnostic).psiElement.descriptor as? DeclarationDescriptorWithVisibility ?: return emptyList() val element = diagnostic.psiElement as? KtModifierListOwner ?: return emptyList() return listOf( ChangeToPublicExplicitlyFix( diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt new file mode 100644 index 00000000000..c6f36cfaebd --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt @@ -0,0 +1,5 @@ +// "Make 'Foo1' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +class Foo1() {} + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt.after b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt.after new file mode 100644 index 00000000000..bf1faea51e0 --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt.after @@ -0,0 +1,5 @@ +// "Make 'Foo1' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo1() {} + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt new file mode 100644 index 00000000000..ac2e12ec53c --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt @@ -0,0 +1,7 @@ +// "Make 'Companion' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo1() { + companion object {} +} + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt.after b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt.after new file mode 100644 index 00000000000..cab7d6a20ce --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt.after @@ -0,0 +1,7 @@ +// "Make 'Companion' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo1() { + public companion object {} +} + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt new file mode 100644 index 00000000000..e0a00f7b84a --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt @@ -0,0 +1,7 @@ +// "Make '' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo5 { + constructor() {} +} + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt.after b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt.after new file mode 100644 index 00000000000..2a9aeb31347 --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt.after @@ -0,0 +1,7 @@ +// "Make '' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo5 { + public constructor() {} +} + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt new file mode 100644 index 00000000000..98f967702ea --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt @@ -0,0 +1,6 @@ +// "Make 'method' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo2() { + fun method() {} +} diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt.after b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt.after new file mode 100644 index 00000000000..567100c3439 --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt.after @@ -0,0 +1,6 @@ +// "Make 'method' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo2() { + public fun method() {} +} diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt new file mode 100644 index 00000000000..ed128aa72f9 --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt @@ -0,0 +1,5 @@ +// "Make 'bar' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo(val bar: Int, private var bar2: String, internal var bar3: Long, public var bar4: Int) + diff --git a/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt.after b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt.after new file mode 100644 index 00000000000..a49f08cc5b6 --- /dev/null +++ b/idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt.after @@ -0,0 +1,5 @@ +// "Make 'bar' public explicitly" "true" +// COMPILER_ARGUMENTS: -Xexplicit-api=strict + +public class Foo(public val bar: Int, private var bar2: String, internal var bar3: Long, public var bar4: Int) + diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java index 17d8bd759e9..46f29932626 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixMultiFileTestGenerated.java @@ -4148,6 +4148,19 @@ public class QuickFixMultiFileTestGenerated extends AbstractQuickFixMultiFileTes } } + @TestMetadata("idea/testData/quickfix/specifyVisibilityInExplicitApiMode") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SpecifyVisibilityInExplicitApiMode extends AbstractQuickFixMultiFileTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTestWithExtraFile, this, testDataFilePath); + } + + public void testAllFilesPresentInSpecifyVisibilityInExplicitApiMode() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/specifyVisibilityInExplicitApiMode"), Pattern.compile("^(\\w+)\\.((before\\.Main\\.\\w+)|(test))$"), null, true); + } + } + @TestMetadata("idea/testData/quickfix/superTypeIsExtensionType") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) diff --git a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java index 43bd28cdda4..924c064a7bf 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/quickfix/QuickFixTestGenerated.java @@ -11683,6 +11683,44 @@ public class QuickFixTestGenerated extends AbstractQuickFixTest { } } + @TestMetadata("idea/testData/quickfix/specifyVisibilityInExplicitApiMode") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class SpecifyVisibilityInExplicitApiMode extends AbstractQuickFixTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + public void testAllFilesPresentInSpecifyVisibilityInExplicitApiMode() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/quickfix/specifyVisibilityInExplicitApiMode"), Pattern.compile("^([\\w\\-_]+)\\.kt$"), null, true); + } + + @TestMetadata("class.kt") + public void testClass() throws Exception { + runTest("idea/testData/quickfix/specifyVisibilityInExplicitApiMode/class.kt"); + } + + @TestMetadata("companion.kt") + public void testCompanion() throws Exception { + runTest("idea/testData/quickfix/specifyVisibilityInExplicitApiMode/companion.kt"); + } + + @TestMetadata("constructor.kt") + public void testConstructor() throws Exception { + runTest("idea/testData/quickfix/specifyVisibilityInExplicitApiMode/constructor.kt"); + } + + @TestMetadata("method.kt") + public void testMethod() throws Exception { + runTest("idea/testData/quickfix/specifyVisibilityInExplicitApiMode/method.kt"); + } + + @TestMetadata("property.kt") + public void testProperty() throws Exception { + runTest("idea/testData/quickfix/specifyVisibilityInExplicitApiMode/property.kt"); + } + } + @TestMetadata("idea/testData/quickfix/superTypeIsExtensionType") @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class)