Unused symbol: remove forced "used" from actual declarations
Now we really check whether actual declaration has usages (in expect or actual code) or not Related to KT-17512 Related to KT-15666
This commit is contained in:
@@ -50,7 +50,9 @@ import org.jetbrains.kotlin.idea.imports.importableFqName
|
|||||||
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
|
import org.jetbrains.kotlin.idea.quickfix.RemoveUnusedFunctionParameterFix
|
||||||
import org.jetbrains.kotlin.idea.references.mainReference
|
import org.jetbrains.kotlin.idea.references.mainReference
|
||||||
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
import org.jetbrains.kotlin.idea.references.resolveMainReferenceToDescriptors
|
||||||
|
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReferencesSearchParameters
|
||||||
import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators
|
import org.jetbrains.kotlin.idea.search.isCheapEnoughToSearchConsideringOperators
|
||||||
|
import org.jetbrains.kotlin.idea.search.projectScope
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
import org.jetbrains.kotlin.idea.search.usagesSearch.dataClassComponentFunction
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
|
import org.jetbrains.kotlin.idea.search.usagesSearch.getAccessorNames
|
||||||
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
|
import org.jetbrains.kotlin.idea.search.usagesSearch.getClassNameForCompanionObject
|
||||||
@@ -190,7 +192,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun hasNonTrivialUsages(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor? = null): Boolean {
|
private fun hasNonTrivialUsages(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor? = null): Boolean {
|
||||||
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(declaration.project)
|
val project = declaration.project
|
||||||
|
val psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(project)
|
||||||
|
|
||||||
val useScope = declaration.useScope
|
val useScope = declaration.useScope
|
||||||
val restrictedScope = if (useScope is GlobalSearchScope) {
|
val restrictedScope = if (useScope is GlobalSearchScope) {
|
||||||
@@ -206,14 +209,18 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (zeroOccurrences) {
|
if (zeroOccurrences && !declaration.hasActualModifier()) {
|
||||||
if (declaration is KtObjectDeclaration && declaration.isCompanion()) {
|
if (declaration is KtObjectDeclaration && declaration.isCompanion()) {
|
||||||
// go on: companion object can be used only in containing class
|
// go on: companion object can be used only in containing class
|
||||||
} else {
|
} else {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
KotlinSourceFilterScope.projectSources(useScope, declaration.project)
|
if (declaration.hasActualModifier()) {
|
||||||
|
KotlinSourceFilterScope.projectSources(project.projectScope(), project)
|
||||||
|
} else {
|
||||||
|
KotlinSourceFilterScope.projectSources(useScope, project)
|
||||||
|
}
|
||||||
} else useScope
|
} else useScope
|
||||||
|
|
||||||
return (declaration is KtObjectDeclaration && declaration.isCompanion() &&
|
return (declaration is KtObjectDeclaration && declaration.isCompanion() &&
|
||||||
@@ -221,7 +228,6 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
hasReferences(declaration, descriptor, restrictedScope) ||
|
hasReferences(declaration, descriptor, restrictedScope) ||
|
||||||
hasOverrides(declaration, restrictedScope) ||
|
hasOverrides(declaration, restrictedScope) ||
|
||||||
hasFakeOverrides(declaration, restrictedScope) ||
|
hasFakeOverrides(declaration, restrictedScope) ||
|
||||||
isPlatformImplementation(declaration) ||
|
|
||||||
hasPlatformImplementations(declaration, descriptor)
|
hasPlatformImplementations(declaration, descriptor)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -267,7 +273,8 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
val referenceUsed: Boolean by lazy { !ReferencesSearch.search(declaration, useScope).forEach(::checkReference) }
|
val searchParameters = KotlinReferencesSearchParameters(declaration, useScope)
|
||||||
|
val referenceUsed: Boolean by lazy { !ReferencesSearch.search(searchParameters).forEach(::checkReference) }
|
||||||
|
|
||||||
if (descriptor is FunctionDescriptor &&
|
if (descriptor is FunctionDescriptor &&
|
||||||
DescriptorUtils.getAnnotationByFqName(descriptor.annotations, JvmFileClassUtil.JVM_NAME) != null
|
DescriptorUtils.getAnnotationByFqName(descriptor.annotations, JvmFileClassUtil.JVM_NAME) != null
|
||||||
@@ -278,9 +285,11 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
if (declaration is KtCallableDeclaration && !declaration.hasModifier(KtTokens.INTERNAL_KEYWORD)) {
|
if (declaration is KtCallableDeclaration && !declaration.hasModifier(KtTokens.INTERNAL_KEYWORD)) {
|
||||||
val lightMethods = declaration.toLightMethods()
|
val lightMethods = declaration.toLightMethods()
|
||||||
if (lightMethods.isNotEmpty()) {
|
if (lightMethods.isNotEmpty()) {
|
||||||
return lightMethods.any { method ->
|
val lightMethodsUsed = lightMethods.any { method ->
|
||||||
!MethodReferencesSearch.search(method).forEach(::checkReference)
|
!MethodReferencesSearch.search(method).forEach(::checkReference)
|
||||||
}
|
}
|
||||||
|
if (lightMethodsUsed) return true
|
||||||
|
if (!declaration.hasActualModifier()) return false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,9 +328,6 @@ class UnusedSymbolInspection : AbstractKotlinInspection() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun isPlatformImplementation(declaration: KtNamedDeclaration) =
|
|
||||||
declaration.hasActualModifier()
|
|
||||||
|
|
||||||
private fun hasPlatformImplementations(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor?): Boolean {
|
private fun hasPlatformImplementations(declaration: KtNamedDeclaration, descriptor: DeclarationDescriptor?): Boolean {
|
||||||
if (!declaration.hasExpectModifier()) return false
|
if (!declaration.hasExpectModifier()) return false
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
// No "unused symbol" should be reported here
|
// No "unused symbol" should be reported here
|
||||||
|
|
||||||
expect class My
|
expect class My
|
||||||
|
|
||||||
|
// But this should be reported
|
||||||
actual class My
|
actual class My
|
||||||
|
|
||||||
// But this should be reported
|
// And this too
|
||||||
expect val bar: String
|
expect val bar: String
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,14 @@
|
|||||||
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
||||||
<description>Class 'Some' is never used</description>
|
<description>Class 'Some' is never used</description>
|
||||||
</problem>
|
</problem>
|
||||||
|
<problem>
|
||||||
|
<file>headerImpl.kt</file>
|
||||||
|
<line>5</line>
|
||||||
|
<module>light_idea_test_case</module>
|
||||||
|
<entry_point TYPE="file" FQNAME="temp:///src/headerImpl.kt" />
|
||||||
|
<problem_class severity="WARNING" attribute_key="NOT_USED_ELEMENT_ATTRIBUTES">Unused symbol</problem_class>
|
||||||
|
<description>Class 'My' is never used</description>
|
||||||
|
</problem>
|
||||||
<problem>
|
<problem>
|
||||||
<file>headerImpl.kt</file>
|
<file>headerImpl.kt</file>
|
||||||
<line>8</line>
|
<line>8</line>
|
||||||
|
|||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
expect class My constructor() {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
My().foo()
|
||||||
|
}
|
||||||
+7
@@ -0,0 +1,7 @@
|
|||||||
|
expect class My constructor() {
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun test() {
|
||||||
|
My().foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
// "Safe delete 'foo'" "false"
|
||||||
|
// TOOL: org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
|
||||||
|
// ACTION: Convert member to extension
|
||||||
|
// ACTION: Move to companion object
|
||||||
|
|
||||||
|
actual class My {
|
||||||
|
actual fun <caret>foo() {}
|
||||||
|
}
|
||||||
+8
@@ -0,0 +1,8 @@
|
|||||||
|
// "Safe delete 'foo'" "false"
|
||||||
|
// TOOL: org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
|
||||||
|
// ACTION: Convert member to extension
|
||||||
|
// ACTION: Move to companion object
|
||||||
|
|
||||||
|
actual class My {
|
||||||
|
actual fun foo() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
expect class My constructor() {
|
||||||
|
// TODO: also should be deleted (KT-15666)
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
expect class My constructor() {
|
||||||
|
// TODO: also should be deleted (KT-15666)
|
||||||
|
fun foo()
|
||||||
|
}
|
||||||
@@ -0,0 +1,6 @@
|
|||||||
|
// "Safe delete 'foo'" "true"
|
||||||
|
// TOOL: org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
|
||||||
|
|
||||||
|
actual class My {
|
||||||
|
actual fun <caret>foo() {}
|
||||||
|
}
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
// "Safe delete 'foo'" "true"
|
||||||
|
// TOOL: org.jetbrains.kotlin.idea.inspections.UnusedSymbolInspection
|
||||||
|
|
||||||
|
actual class My {
|
||||||
|
}
|
||||||
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
|||||||
import org.jetbrains.kotlin.test.KotlinTestUtils
|
import org.jetbrains.kotlin.test.KotlinTestUtils
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
||||||
abstract class AbstractQuickFixMultiModuleTest : AbstractMultiModuleTest() {
|
abstract class AbstractQuickFixMultiModuleTest : AbstractMultiModuleTest(), QuickFixTest {
|
||||||
|
|
||||||
override fun getTestDataPath() = PluginTestCaseBase.getTestDataPathBase() + "/multiModuleQuickFix/"
|
override fun getTestDataPath() = PluginTestCaseBase.getTestDataPathBase() + "/multiModuleQuickFix/"
|
||||||
|
|
||||||
@@ -34,10 +34,12 @@ abstract class AbstractQuickFixMultiModuleTest : AbstractMultiModuleTest() {
|
|||||||
|
|
||||||
private fun doQuickFixTest() {
|
private fun doQuickFixTest() {
|
||||||
val actionFile = project.findFileWithCaret()
|
val actionFile = project.findFileWithCaret()
|
||||||
configureByExistingFile(actionFile.virtualFile!!)
|
val virtualFile = actionFile.virtualFile!!
|
||||||
|
configureByExistingFile(virtualFile)
|
||||||
val actionFileText = actionFile.text
|
val actionFileText = actionFile.text
|
||||||
val actionFileName = actionFile.name
|
val actionFileName = actionFile.name
|
||||||
|
val inspections = parseInspectionsToEnable(virtualFile.path, actionFileText).toTypedArray()
|
||||||
|
enableInspectionTools(*inspections)
|
||||||
|
|
||||||
CommandProcessor.getInstance().executeCommand(project, {
|
CommandProcessor.getInstance().executeCommand(project, {
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -18,19 +18,18 @@ package org.jetbrains.kotlin.idea.quickfix
|
|||||||
|
|
||||||
import com.intellij.codeInsight.daemon.quickFix.ActionHint
|
import com.intellij.codeInsight.daemon.quickFix.ActionHint
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.codeInspection.InspectionProfileEntry
|
|
||||||
import com.intellij.codeInspection.LocalInspectionTool
|
|
||||||
import com.intellij.codeInspection.SuppressableProblemGroup
|
import com.intellij.codeInspection.SuppressableProblemGroup
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
import com.intellij.openapi.vfs.CharsetToolkit
|
import com.intellij.openapi.vfs.CharsetToolkit
|
||||||
import com.intellij.rt.execution.junit.FileComparisonFailure
|
import com.intellij.rt.execution.junit.FileComparisonFailure
|
||||||
import com.intellij.testFramework.*
|
import com.intellij.testFramework.LightPlatformTestCase
|
||||||
|
import com.intellij.testFramework.LightProjectDescriptor
|
||||||
|
import com.intellij.testFramework.UsefulTestCase
|
||||||
import com.intellij.util.ui.UIUtil
|
import com.intellij.util.ui.UIUtil
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||||
import org.jetbrains.kotlin.idea.quickfix.utils.findInspectionFile
|
|
||||||
import org.jetbrains.kotlin.idea.test.*
|
import org.jetbrains.kotlin.idea.test.*
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
@@ -38,13 +37,13 @@ import org.junit.Assert
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase() {
|
abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase(), QuickFixTest {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
protected fun doTest(beforeFileName: String) {
|
protected fun doTest(beforeFileName: String) {
|
||||||
val beforeFileText = FileUtil.loadFile(File(beforeFileName))
|
val beforeFileText = FileUtil.loadFile(File(beforeFileName))
|
||||||
configureCompilerOptions(beforeFileText, project, module)
|
configureCompilerOptions(beforeFileText, project, module)
|
||||||
|
|
||||||
val inspections = parceInspectionsToEnable(beforeFileName, beforeFileText).toTypedArray()
|
val inspections = parseInspectionsToEnable(beforeFileName, beforeFileText).toTypedArray()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
myFixture.enableInspections(*inspections)
|
myFixture.enableInspections(*inspections)
|
||||||
@@ -171,31 +170,6 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parceInspectionsToEnable(beforeFileName: String, beforeFileText: String): List<InspectionProfileEntry> {
|
|
||||||
val toolsStrings = InTextDirectivesUtils.findListWithPrefixes(beforeFileText, "TOOL:")
|
|
||||||
if (toolsStrings.isNotEmpty()) {
|
|
||||||
val inspections = toolsStrings.map { toolFqName ->
|
|
||||||
try {
|
|
||||||
val aClass = Class.forName(toolFqName)
|
|
||||||
return@map aClass.newInstance() as LocalInspectionTool
|
|
||||||
}
|
|
||||||
catch (e: Exception) {
|
|
||||||
throw IllegalArgumentException("Failed to create inspection for key '$toolFqName'", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inspections
|
|
||||||
}
|
|
||||||
|
|
||||||
val inspectionFile = findInspectionFile(File(beforeFileName).parentFile)
|
|
||||||
if (inspectionFile != null) {
|
|
||||||
val className = FileUtil.loadFile(inspectionFile).trim { it <= ' ' }
|
|
||||||
val inspectionClass = Class.forName(className) as Class<InspectionProfileEntry>
|
|
||||||
return InspectionTestUtil.instantiateTools(listOf<Class<out InspectionProfileEntry>>(inspectionClass))
|
|
||||||
}
|
|
||||||
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ClassNotFoundException::class)
|
@Throws(ClassNotFoundException::class)
|
||||||
private fun checkForUnexpectedActions() {
|
private fun checkForUnexpectedActions() {
|
||||||
val text = myFixture.editor.document.text
|
val text = myFixture.editor.document.text
|
||||||
|
|||||||
@@ -18,8 +18,6 @@ package org.jetbrains.kotlin.idea.quickfix
|
|||||||
|
|
||||||
import com.intellij.codeInsight.daemon.quickFix.ActionHint
|
import com.intellij.codeInsight.daemon.quickFix.ActionHint
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import com.intellij.codeInspection.InspectionProfileEntry
|
|
||||||
import com.intellij.codeInspection.LocalInspectionTool
|
|
||||||
import com.intellij.codeInspection.SuppressableProblemGroup
|
import com.intellij.codeInspection.SuppressableProblemGroup
|
||||||
import com.intellij.openapi.command.CommandProcessor
|
import com.intellij.openapi.command.CommandProcessor
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
@@ -30,7 +28,6 @@ import com.intellij.testFramework.*
|
|||||||
import com.intellij.util.ui.UIUtil
|
import com.intellij.util.ui.UIUtil
|
||||||
import junit.framework.TestCase
|
import junit.framework.TestCase
|
||||||
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
import org.jetbrains.kotlin.idea.facet.KotlinFacet
|
||||||
import org.jetbrains.kotlin.idea.quickfix.utils.findInspectionFile
|
|
||||||
import org.jetbrains.kotlin.idea.test.*
|
import org.jetbrains.kotlin.idea.test.*
|
||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
@@ -38,13 +35,13 @@ import org.junit.Assert
|
|||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
|
|
||||||
abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase() {
|
abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase(), QuickFixTest {
|
||||||
@Throws(Exception::class)
|
@Throws(Exception::class)
|
||||||
protected fun doTest(beforeFileName: String) {
|
protected fun doTest(beforeFileName: String) {
|
||||||
val beforeFileText = FileUtil.loadFile(File(beforeFileName))
|
val beforeFileText = FileUtil.loadFile(File(beforeFileName))
|
||||||
configureCompilerOptions(beforeFileText, project, module)
|
configureCompilerOptions(beforeFileText, project, module)
|
||||||
|
|
||||||
val inspections = parceInspectionsToEnable(beforeFileName, beforeFileText).toTypedArray()
|
val inspections = parseInspectionsToEnable(beforeFileName, beforeFileText).toTypedArray()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
myFixture.enableInspections(*inspections)
|
myFixture.enableInspections(*inspections)
|
||||||
@@ -156,31 +153,6 @@ abstract class AbstractQuickFixTest : KotlinLightCodeInsightFixtureTestCase() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun parceInspectionsToEnable(beforeFileName: String, beforeFileText: String): List<InspectionProfileEntry> {
|
|
||||||
val toolsStrings = InTextDirectivesUtils.findListWithPrefixes(beforeFileText, "TOOL:")
|
|
||||||
if (toolsStrings.isNotEmpty()) {
|
|
||||||
val inspections = toolsStrings.map { toolFqName ->
|
|
||||||
try {
|
|
||||||
val aClass = Class.forName(toolFqName)
|
|
||||||
return@map aClass.newInstance() as LocalInspectionTool
|
|
||||||
}
|
|
||||||
catch (e: Exception) {
|
|
||||||
throw IllegalArgumentException("Failed to create inspection for key '$toolFqName'", e)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return inspections
|
|
||||||
}
|
|
||||||
|
|
||||||
val inspectionFile = findInspectionFile(File(beforeFileName).parentFile)
|
|
||||||
if (inspectionFile != null) {
|
|
||||||
val className = FileUtil.loadFile(inspectionFile).trim { it <= ' ' }
|
|
||||||
val inspectionClass = Class.forName(className) as Class<InspectionProfileEntry>
|
|
||||||
return InspectionTestUtil.instantiateTools(listOf<Class<out InspectionProfileEntry>>(inspectionClass))
|
|
||||||
}
|
|
||||||
|
|
||||||
return emptyList()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ClassNotFoundException::class)
|
@Throws(ClassNotFoundException::class)
|
||||||
private fun checkForUnexpectedActions() {
|
private fun checkForUnexpectedActions() {
|
||||||
val text = myFixture.editor.document.text
|
val text = myFixture.editor.document.text
|
||||||
|
|||||||
+10
@@ -334,6 +334,16 @@ public class QuickFixMultiModuleTestGenerated extends AbstractQuickFixMultiModul
|
|||||||
runTest("idea/testData/multiModuleQuickFix/property/");
|
runTest("idea/testData/multiModuleQuickFix/property/");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeDeleteForbiddenFromActual")
|
||||||
|
public void testSafeDeleteForbiddenFromActual() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/safeDeleteForbiddenFromActual/");
|
||||||
|
}
|
||||||
|
|
||||||
|
@TestMetadata("safeDeleteFromActual")
|
||||||
|
public void testSafeDeleteFromActual() throws Exception {
|
||||||
|
runTest("idea/testData/multiModuleQuickFix/safeDeleteFromActual/");
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("sealed")
|
@TestMetadata("sealed")
|
||||||
public void testSealed() throws Exception {
|
public void testSealed() throws Exception {
|
||||||
runTest("idea/testData/multiModuleQuickFix/sealed/");
|
runTest("idea/testData/multiModuleQuickFix/sealed/");
|
||||||
|
|||||||
@@ -0,0 +1,39 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
|
import com.intellij.codeInspection.InspectionProfileEntry
|
||||||
|
import com.intellij.codeInspection.LocalInspectionTool
|
||||||
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.testFramework.InspectionTestUtil
|
||||||
|
import org.jetbrains.kotlin.idea.quickfix.utils.findInspectionFile
|
||||||
|
import org.jetbrains.kotlin.test.InTextDirectivesUtils
|
||||||
|
import java.io.File
|
||||||
|
|
||||||
|
interface QuickFixTest {
|
||||||
|
fun parseInspectionsToEnable(beforeFileName: String, beforeFileText: String): List<InspectionProfileEntry> {
|
||||||
|
val toolsStrings = InTextDirectivesUtils.findListWithPrefixes(beforeFileText, "TOOL:")
|
||||||
|
if (toolsStrings.isNotEmpty()) {
|
||||||
|
return toolsStrings.map { toolFqName ->
|
||||||
|
try {
|
||||||
|
val aClass = Class.forName(toolFqName)
|
||||||
|
return@map aClass.newInstance() as LocalInspectionTool
|
||||||
|
} catch (e: Exception) {
|
||||||
|
throw IllegalArgumentException("Failed to create inspection for key '$toolFqName'", e)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val inspectionFile = findInspectionFile(File(beforeFileName).parentFile)
|
||||||
|
if (inspectionFile != null) {
|
||||||
|
val className = FileUtil.loadFile(inspectionFile).trim { it <= ' ' }
|
||||||
|
val inspectionClass = Class.forName(className) as Class<InspectionProfileEntry>
|
||||||
|
return InspectionTestUtil.instantiateTools(listOf<Class<out InspectionProfileEntry>>(inspectionClass))
|
||||||
|
}
|
||||||
|
|
||||||
|
return emptyList()
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user