diff --git a/.idea/inspectionProfiles/idea_default.xml b/.idea/inspectionProfiles/idea_default.xml
index 4b65c8d8754..b6352fcebe9 100644
--- a/.idea/inspectionProfiles/idea_default.xml
+++ b/.idea/inspectionProfiles/idea_default.xml
@@ -115,6 +115,7 @@
+
diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt
index 4e496e83e4b..e1294cb3eaa 100644
--- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt
@@ -48,6 +48,7 @@ import org.jetbrains.kotlin.idea.core.overrideImplement.generateUnsupportedOrSup
import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.setupEditorSelection
import org.jetbrains.kotlin.idea.refactoring.j2k
import org.jetbrains.kotlin.idea.testIntegration.findSuitableFrameworks
+import org.jetbrains.kotlin.idea.util.PopupChooserBuilderWrapper
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
@@ -74,7 +75,7 @@ abstract class KotlinGenerateTestSupportActionBase(
val list = JBList(*frameworks.toTypedArray())
list.cellRenderer = TestFrameworkListCellRenderer()
- PopupChooserBuilder(list)
+ PopupChooserBuilderWrapper(list)
.setFilteringEnabled { (it as TestFramework).name }
.setTitle("Choose Framework")
.setItemChoosenCallback { consumer(list.selectedValue as TestFramework) }
diff --git a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt.181 b/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt.181
deleted file mode 100644
index 4b260c14500..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/actions/generate/KotlinGenerateTestSupportActionBase.kt.181
+++ /dev/null
@@ -1,261 +0,0 @@
-/*
- * Copyright 2010-2015 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.actions.generate
-
-import com.intellij.codeInsight.generation.actions.GenerateActionPopupTemplateInjector
-import com.intellij.codeInsight.hint.HintManager
-import com.intellij.ide.fileTemplates.FileTemplateManager
-import com.intellij.ide.fileTemplates.impl.AllFileTemplatesConfigurable
-import com.intellij.openapi.actionSystem.AnAction
-import com.intellij.openapi.actionSystem.AnActionEvent
-import com.intellij.openapi.actionSystem.CommonDataKeys
-import com.intellij.openapi.actionSystem.DataContext
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.ui.InputValidator
-import com.intellij.openapi.ui.Messages
-import com.intellij.openapi.ui.popup.PopupChooserBuilder
-import com.intellij.openapi.util.io.FileUtil
-import com.intellij.psi.PsiDocumentManager
-import com.intellij.psi.PsiElementFactory
-import com.intellij.psi.PsiFile
-import com.intellij.testIntegration.JavaTestFramework
-import com.intellij.testIntegration.TestFramework
-import com.intellij.testIntegration.TestIntegrationUtils.MethodKind
-import com.intellij.ui.components.JBList
-import com.intellij.util.IncorrectOperationException
-import org.jetbrains.kotlin.asJava.toLightClass
-import org.jetbrains.kotlin.descriptors.FunctionDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
-import org.jetbrains.kotlin.idea.core.insertMember
-import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject.BodyType
-import org.jetbrains.kotlin.idea.core.overrideImplement.generateUnsupportedOrSuperCall
-import org.jetbrains.kotlin.idea.quickfix.createFromUsage.callableBuilder.setupEditorSelection
-import org.jetbrains.kotlin.idea.refactoring.j2k
-import org.jetbrains.kotlin.idea.testIntegration.findSuitableFrameworks
-import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.psiUtil.isIdentifier
-import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
-import org.jetbrains.kotlin.psi.psiUtil.quoteIfNeeded
-import org.jetbrains.kotlin.utils.ifEmpty
-
-abstract class KotlinGenerateTestSupportActionBase(
- private val methodKind : MethodKind
-) : KotlinGenerateActionBase(), GenerateActionPopupTemplateInjector {
- companion object {
- private fun findTargetClass(editor: Editor, file: PsiFile): KtClassOrObject? {
- val elementAtCaret = file.findElementAt(editor.caretModel.offset) ?: return null
- return elementAtCaret.parentsWithSelf.filterIsInstance().firstOrNull { !it.isLocal }
- }
-
- private fun chooseAndPerform(editor: Editor, frameworks: List, consumer: (TestFramework) -> Unit) {
- frameworks.ifEmpty { return }
- frameworks.singleOrNull()?.let { return consumer(it) }
-
- if (ApplicationManager.getApplication().isUnitTestMode) return consumer(frameworks.first())
-
- val list = JBList(*frameworks.toTypedArray())
- list.cellRenderer = TestFrameworkListCellRenderer()
-
- PopupChooserBuilder(list)
- .setFilteringEnabled { (it as TestFramework).name }
- .setTitle("Choose Framework")
- .setItemChoosenCallback { consumer(list.selectedValue as TestFramework) }
- .setMovable(true)
- .createPopup()
- .showInBestPositionFor(editor)
- }
-
- private val BODY_VAR = "\${BODY}"
- private val NAME_VAR = "\${NAME}"
-
- private val NAME_VALIDATOR = object : InputValidator {
- override fun checkInput(inputString: String) = inputString.quoteIfNeeded().isIdentifier()
- override fun canClose(inputString: String) = true
- }
- }
-
- class SetUp : KotlinGenerateTestSupportActionBase(MethodKind.SET_UP) {
- override fun isApplicableTo(framework: TestFramework, targetClass: KtClassOrObject): Boolean {
- return framework.findSetUpMethod(targetClass.toLightClass()!!) == null
- }
- }
-
- class Test : KotlinGenerateTestSupportActionBase(MethodKind.TEST) {
- override fun isApplicableTo(framework: TestFramework, targetClass: KtClassOrObject) = true
- }
-
- class Data : KotlinGenerateTestSupportActionBase(MethodKind.DATA) {
- override fun isApplicableTo(framework: TestFramework, targetClass: KtClassOrObject): Boolean {
- if (framework !is JavaTestFramework) return false
- return framework.findParametersMethod(targetClass.toLightClass()) == null
- }
- }
-
- class TearDown : KotlinGenerateTestSupportActionBase(MethodKind.TEAR_DOWN) {
- override fun isApplicableTo(framework: TestFramework, targetClass: KtClassOrObject): Boolean {
- return framework.findTearDownMethod(targetClass.toLightClass()!!) == null
- }
- }
-
- override fun getTargetClass(editor: Editor, file: PsiFile): KtClassOrObject? {
- return findTargetClass(editor, file)
- }
-
- override fun isValidForClass(targetClass: KtClassOrObject): Boolean {
- return findSuitableFrameworks(targetClass).any { isApplicableTo(it, targetClass) }
- }
-
- protected abstract fun isApplicableTo(framework: TestFramework, targetClass: KtClassOrObject): Boolean
-
- override fun invoke(project: Project, editor: Editor, file: PsiFile) {
- val klass = findTargetClass(editor, file) ?: return
-
- if (testFrameworkToUse != null) {
- val frameworkToUse = findSuitableFrameworks(klass).first { it.name == testFrameworkToUse }
- if (isApplicableTo(frameworkToUse, klass)) {
- doGenerate(editor, file, klass, frameworkToUse)
- }
- }
- else {
- val frameworks = findSuitableFrameworks(klass)
- .filter { methodKind.getFileTemplateDescriptor(it) != null && isApplicableTo(it, klass) }
-
- chooseAndPerform(editor, frameworks) { doGenerate(editor, file, klass, it) }
- }
- }
-
- var testFrameworkToUse: String? = null
-
- private val DUMMY_NAME = "__KOTLIN_RULEZZZ__"
-
- private fun doGenerate(editor: Editor, file: PsiFile, klass: KtClassOrObject, framework: TestFramework) {
- val project = file.project
- val commandName = "Generate test function"
-
- val fileTemplateDescriptor = methodKind.getFileTemplateDescriptor(framework)
- val fileTemplate = FileTemplateManager.getInstance(project).getCodeTemplate(fileTemplateDescriptor.fileName)
- var templateText = fileTemplate.text.replace(BODY_VAR, "")
- var name: String? = null
- if (templateText.contains(NAME_VAR)) {
- name = if (templateText.contains("test$NAME_VAR")) "Name" else "name"
- if (!ApplicationManager.getApplication().isUnitTestMode) {
- name = Messages.showInputDialog("Choose test name: ", commandName, null, name, NAME_VALIDATOR)
- ?: return
- }
-
- templateText = fileTemplate.text.replace(NAME_VAR, DUMMY_NAME)
- }
-
- try {
- var errorHint: String? = null
- project.executeWriteCommand(commandName) {
- PsiDocumentManager.getInstance(project).commitAllDocuments()
-
- val factory = PsiElementFactory.SERVICE.getInstance(project)
- val psiMethod = factory.createMethodFromText(templateText, null)
- psiMethod.throwsList.referenceElements.forEach { it.delete() }
- var function = psiMethod.j2k() as? KtNamedFunction ?: run {
- errorHint = "Couldn't convert Java template to Kotlin"
- return@executeWriteCommand
- }
- name?.let {
- function = substituteNewName(function, it)
- }
- val functionInPlace = insertMember(editor, klass, function)
-
- val functionDescriptor = functionInPlace.unsafeResolveToDescriptor() as FunctionDescriptor
- val overriddenDescriptors = functionDescriptor.overriddenDescriptors
- val bodyText = when (overriddenDescriptors.size) {
- 0 -> generateUnsupportedOrSuperCall(project, functionDescriptor, BodyType.FROM_TEMPLATE)
- 1 -> generateUnsupportedOrSuperCall(project, overriddenDescriptors.single(), BodyType.SUPER)
- else -> generateUnsupportedOrSuperCall(project, overriddenDescriptors.first(), BodyType.QUALIFIED_SUPER)
- }
- functionInPlace.bodyExpression?.delete()
- functionInPlace.add(KtPsiFactory(project).createBlock(bodyText))
-
- if (overriddenDescriptors.isNotEmpty()) {
- functionInPlace.addModifier(KtTokens.OVERRIDE_KEYWORD)
- }
-
- setupEditorSelection(editor, functionInPlace)
- }
- errorHint?.let { HintManager.getInstance().showErrorHint(editor, it) }
- }
- catch (e: IncorrectOperationException) {
- HintManager.getInstance().showErrorHint(editor, "Cannot generate method: " + e.message)
- }
- }
-
- private fun substituteNewName(function: KtNamedFunction, name: String): KtNamedFunction {
- val psiFactory = KtPsiFactory(function)
-
- // First replace all DUMMY_NAME occurrences in names as they need special treatment due to quotation
- var function1 = function
- function1.accept(
- object : KtTreeVisitorVoid() {
- private fun getNewId(currentId: String): String? {
- if (!currentId.contains(DUMMY_NAME)) return null
- return currentId.replace(DUMMY_NAME, name).quoteIfNeeded()
- }
-
- override fun visitNamedDeclaration(declaration: KtNamedDeclaration) {
- val nameIdentifier = declaration.nameIdentifier ?: return
- val newId = getNewId(nameIdentifier.text) ?: return
- declaration.setName(newId)
- }
-
- override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
- val newId = getNewId(expression.text) ?: return
- expression.replace(psiFactory.createSimpleName(newId))
- }
- }
- )
- // Then text-replace remaining occurrences (if any)
- val functionText = function1.text
- if (functionText.contains(DUMMY_NAME)) {
- function1 = psiFactory.createFunction(function1.text.replace(DUMMY_NAME, name))
- }
- return function1
- }
-
- override fun createEditTemplateAction(dataContext: DataContext): AnAction? {
- val project = CommonDataKeys.PROJECT.getData(dataContext) ?: return null
- val editor = CommonDataKeys.EDITOR.getData(dataContext) ?: return null
- val file = CommonDataKeys.PSI_FILE.getData(dataContext) ?: return null
-
- val targetClass = getTargetClass(editor, file) ?: return null
- val frameworks = findSuitableFrameworks(targetClass).ifEmpty { return null }
-
- return object : AnAction("Edit Template") {
- override fun actionPerformed(e: AnActionEvent) {
- chooseAndPerform(editor, frameworks) {
- val descriptor = methodKind.getFileTemplateDescriptor(it)
- if (descriptor == null) {
- HintManager.getInstance().showErrorHint(editor, "No template found for ${it.name}:${templatePresentation.text}")
- return@chooseAndPerform
- }
-
- AllFileTemplatesConfigurable.editCodeTemplate(FileUtil.getNameWithoutExtension(descriptor.fileName), project)
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt
index 9d313534f05..8c86217908d 100644
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt
@@ -45,6 +45,7 @@ import org.jetbrains.kotlin.idea.refactoring.isAbstract
import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
+import org.jetbrains.kotlin.idea.util.PopupChooserBuilderWrapper
import org.jetbrains.kotlin.idea.util.application.executeCommand
import org.jetbrains.kotlin.idea.util.application.runWriteAction
import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
@@ -213,7 +214,7 @@ abstract class ImplementAbstractMemberIntentionBase :
selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
cellRenderer = renderer
}
- val builder = PopupChooserBuilder(list)
+ val builder = PopupChooserBuilderWrapper(list)
renderer.installSpeedSearch(builder)
builder
.setTitle(CodeInsightBundle.message("intention.implement.abstract.method.class.chooser.title"))
diff --git a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt.181 b/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt.181
deleted file mode 100644
index f1f6c059788..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/intentions/ImplementAbstractMemberIntention.kt.181
+++ /dev/null
@@ -1,268 +0,0 @@
-/*
- * Copyright 2010-2016 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.intentions
-
-import com.intellij.codeInsight.CodeInsightBundle
-import com.intellij.codeInsight.FileModificationService
-import com.intellij.codeInsight.generation.OverrideImplementUtil
-import com.intellij.ide.util.PsiClassListCellRenderer
-import com.intellij.ide.util.PsiElementListCellRenderer
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.diagnostic.Logger
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.fileEditor.FileEditorManager
-import com.intellij.openapi.fileEditor.OpenFileDescriptor
-import com.intellij.openapi.ui.popup.PopupChooserBuilder
-import com.intellij.openapi.util.TextRange
-import com.intellij.psi.PsiClass
-import com.intellij.psi.PsiElement
-import com.intellij.ui.components.JBList
-import com.intellij.util.IncorrectOperationException
-import org.jetbrains.kotlin.asJava.classes.KtLightClass
-import org.jetbrains.kotlin.asJava.toLightMethods
-import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
-import org.jetbrains.kotlin.descriptors.ClassDescriptor
-import org.jetbrains.kotlin.descriptors.ClassKind
-import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaClassDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
-import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideImplementMembersHandler
-import org.jetbrains.kotlin.idea.core.overrideImplement.OverrideMemberChooserObject
-import org.jetbrains.kotlin.idea.refactoring.isAbstract
-import org.jetbrains.kotlin.idea.runSynchronouslyWithProgress
-import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
-import org.jetbrains.kotlin.idea.search.declarationsSearch.searchInheritors
-import org.jetbrains.kotlin.idea.util.application.executeCommand
-import org.jetbrains.kotlin.idea.util.application.runWriteAction
-import org.jetbrains.kotlin.load.java.descriptors.JavaClassDescriptor
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.psiUtil.containingClassOrObject
-import org.jetbrains.kotlin.types.TypeSubstitutor
-import org.jetbrains.kotlin.types.substitutions.getTypeSubstitutor
-import org.jetbrains.kotlin.util.findCallableMemberBySignature
-import java.util.*
-import javax.swing.ListSelectionModel
-
-abstract class ImplementAbstractMemberIntentionBase :
- SelfTargetingRangeIntention(KtNamedDeclaration::class.java, "", "Implement abstract member") {
- companion object {
- private val LOG = Logger.getInstance("#${ImplementAbstractMemberIntentionBase::class.java.canonicalName}")
- }
-
- protected fun findExistingImplementation(
- subClass: ClassDescriptor,
- superMember: CallableMemberDescriptor
- ): CallableMemberDescriptor? {
- val superClass = superMember.containingDeclaration as? ClassDescriptor ?: return null
- val substitutor = getTypeSubstitutor(superClass.defaultType, subClass.defaultType) ?: TypeSubstitutor.EMPTY
- val signatureInSubClass = superMember.substitute(substitutor) as? CallableMemberDescriptor ?: return null
- val subMember = subClass.findCallableMemberBySignature(signatureInSubClass)
- return if (subMember?.kind?.isReal == true) subMember else null
- }
-
- protected abstract fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean
-
- private fun findClassesToProcess(member: KtNamedDeclaration): Sequence {
- val baseClass = member.containingClassOrObject as? KtClass ?: return emptySequence()
- val memberDescriptor = member.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return emptySequence()
-
- fun acceptSubClass(subClass: PsiElement): Boolean {
- val classDescriptor = when (subClass) {
- is KtLightClass -> subClass.kotlinOrigin?.resolveToDescriptorIfAny()
- is KtEnumEntry -> subClass.resolveToDescriptorIfAny()
- is PsiClass -> subClass.getJavaClassDescriptor()
- else -> null
- } ?: return false
- return acceptSubClass(classDescriptor, memberDescriptor)
- }
-
- if (baseClass.isEnum()) {
- return baseClass.declarations
- .asSequence()
- .filterIsInstance()
- .filter(::acceptSubClass)
- }
-
- return HierarchySearchRequest(baseClass, baseClass.useScope, false)
- .searchInheritors()
- .asSequence()
- .filter(::acceptSubClass)
- }
-
- protected abstract fun computeText(element: KtNamedDeclaration): String?
-
- override fun applicabilityRange(element: KtNamedDeclaration): TextRange? {
- if (!element.isAbstract()) return null
-
- text = computeText(element) ?: return null
-
- if (!findClassesToProcess(element).any()) return null
-
- return element.nameIdentifier?.textRange
- }
-
- protected abstract val preferConstructorParameters: Boolean
-
- private fun implementInKotlinClass(editor: Editor?, member: KtNamedDeclaration, targetClass: KtClassOrObject) {
- val subClassDescriptor = targetClass.resolveToDescriptorIfAny() ?: return
- val superMemberDescriptor = member.resolveToDescriptorIfAny() as? CallableMemberDescriptor ?: return
- val superClassDescriptor = superMemberDescriptor.containingDeclaration as? ClassDescriptor ?: return
- val substitutor = getTypeSubstitutor(superClassDescriptor.defaultType, subClassDescriptor.defaultType)
- ?: TypeSubstitutor.EMPTY
- val descriptorToImplement = superMemberDescriptor.substitute(substitutor) as CallableMemberDescriptor
- val chooserObject = OverrideMemberChooserObject.create(member.project,
- descriptorToImplement,
- descriptorToImplement,
- OverrideMemberChooserObject.BodyType.FROM_TEMPLATE,
- preferConstructorParameters)
- OverrideImplementMembersHandler.generateMembers(editor, targetClass, listOf(chooserObject), false)
- }
-
- private fun implementInJavaClass(member: KtNamedDeclaration, targetClass: PsiClass) {
- member.toLightMethods().forEach { OverrideImplementUtil.overrideOrImplement(targetClass, it) }
- }
-
- private fun implementInClass(member: KtNamedDeclaration, targetClasses: List) {
- val project = member.project
- project.executeCommand(CodeInsightBundle.message("intention.implement.abstract.method.command.name")) {
- if (!FileModificationService.getInstance().preparePsiElementsForWrite(targetClasses)) return@executeCommand
- runWriteAction {
- for (targetClass in targetClasses) {
- try {
- val descriptor = OpenFileDescriptor(project, targetClass.containingFile.virtualFile)
- val targetEditor = FileEditorManager.getInstance(project).openTextEditor(descriptor, true)!!
- when (targetClass) {
- is KtLightClass -> targetClass.kotlinOrigin?.let { implementInKotlinClass(targetEditor, member, it) }
- is KtEnumEntry -> implementInKotlinClass(targetEditor, member, targetClass)
- is PsiClass -> implementInJavaClass(member, targetClass)
- }
- }
- catch(e: IncorrectOperationException) {
- LOG.error(e)
- }
- }
- }
- }
- }
-
- private class ClassRenderer : PsiElementListCellRenderer() {
- private val psiClassRenderer = PsiClassListCellRenderer()
-
- override fun getComparator(): Comparator {
- val baseComparator = psiClassRenderer.comparator
- return Comparator { o1, o2 ->
- when {
- o1 is KtEnumEntry && o2 is KtEnumEntry -> o1.name!!.compareTo(o2.name!!)
- o1 is KtEnumEntry -> -1
- o2 is KtEnumEntry -> 1
- o1 is PsiClass && o2 is PsiClass -> baseComparator.compare(o1, o2)
- else -> 0
- }
- }
- }
-
- override fun getIconFlags() = 0
-
- override fun getElementText(element: PsiElement?): String? {
- return when (element) {
- is KtEnumEntry -> element.name
- is PsiClass -> psiClassRenderer.getElementText(element)
- else -> null
- }
- }
-
- override fun getContainerText(element: PsiElement?, name: String?): String? {
- return when (element) {
- is KtEnumEntry -> element.containingClassOrObject?.fqName?.asString()
- is PsiClass -> PsiClassListCellRenderer.getContainerTextStatic(element)
- else -> null
- }
- }
- }
-
- override fun applyTo(element: KtNamedDeclaration, editor: Editor?) {
- if (editor == null) throw IllegalArgumentException("This intention requires an editor")
- val project = element.project
-
- val classesToProcess = project.runSynchronouslyWithProgress(
- CodeInsightBundle.message("intention.implement.abstract.method.searching.for.descendants.progress"),
- true
- ) { findClassesToProcess(element).toList() } ?: return
- if (classesToProcess.isEmpty()) return
-
- classesToProcess.singleOrNull()?.let { return implementInClass(element, listOf(it)) }
-
- val renderer = ClassRenderer()
- val sortedClasses = classesToProcess.sortedWith(renderer.comparator)
- if (ApplicationManager.getApplication().isUnitTestMode) return implementInClass(element, sortedClasses)
-
- val list = JBList(sortedClasses).apply {
- selectionMode = ListSelectionModel.MULTIPLE_INTERVAL_SELECTION
- cellRenderer = renderer
- }
- val builder = PopupChooserBuilder(list)
- renderer.installSpeedSearch(builder)
- builder
- .setTitle(CodeInsightBundle.message("intention.implement.abstract.method.class.chooser.title"))
- .setItemChoosenCallback {
- val index = list.selectedIndex
- if (index < 0) return@setItemChoosenCallback
- @Suppress("UNCHECKED_CAST")
- implementInClass(element, list.selectedValues.toList() as List)
- }
- .createPopup()
- .showInBestPositionFor(editor)
- }
-}
-
-class ImplementAbstractMemberIntention : ImplementAbstractMemberIntentionBase() {
- override fun computeText(element: KtNamedDeclaration): String? {
- return when(element) {
- is KtProperty -> "Implement abstract property"
- is KtNamedFunction -> "Implement abstract function"
- else -> null
- }
- }
-
- override fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean {
- return subClassDescriptor.kind != ClassKind.INTERFACE && findExistingImplementation(subClassDescriptor, memberDescriptor) == null
- }
-
- override val preferConstructorParameters: Boolean
- get() = false
-}
-
-class ImplementAbstractMemberAsConstructorParameterIntention : ImplementAbstractMemberIntentionBase() {
- override fun computeText(element: KtNamedDeclaration): String? {
- if (element !is KtProperty) return null
- return "Implement as constructor parameter"
- }
-
- override fun acceptSubClass(subClassDescriptor: ClassDescriptor, memberDescriptor: CallableMemberDescriptor): Boolean {
- val kind = subClassDescriptor.kind
- return (kind == ClassKind.CLASS || kind == ClassKind.ENUM_CLASS)
- && subClassDescriptor !is JavaClassDescriptor
- && findExistingImplementation(subClassDescriptor, memberDescriptor) == null
- }
-
- override val preferConstructorParameters: Boolean
- get() = true
-
- override fun applicabilityRange(element: KtNamedDeclaration): TextRange? {
- if (element !is KtProperty) return null
- return super.applicabilityRange(element)
- }
-}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt
index f8b6fde95df..88381e78f33 100644
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt
+++ b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt
@@ -74,10 +74,7 @@ import org.jetbrains.kotlin.idea.project.languageVersionSettings
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar
import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper
-import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
-import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
-import org.jetbrains.kotlin.idea.util.actualsForExpected
-import org.jetbrains.kotlin.idea.util.liftToExpected
+import org.jetbrains.kotlin.idea.util.*
import org.jetbrains.kotlin.idea.util.string.collapseSpaces
import org.jetbrains.kotlin.j2k.ConverterSettings
import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
@@ -263,7 +260,7 @@ fun getPsiElementPopup(
}
}
- return with(PopupChooserBuilder(list)) {
+ return with(PopupChooserBuilderWrapper(list)) {
title?.let { setTitle(it) }
renderer.installSpeedSearch(this, true)
setItemChoosenCallback {
diff --git a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt.181 b/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt.181
deleted file mode 100644
index 0142d5d84f3..00000000000
--- a/idea/src/org/jetbrains/kotlin/idea/refactoring/kotlinRefactoringUtil.kt.181
+++ /dev/null
@@ -1,1023 +0,0 @@
-/*
- * Copyright 2000-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.refactoring
-
-import com.intellij.codeInsight.daemon.impl.quickfix.CreateFromUsageUtils
-import com.intellij.codeInsight.unwrap.RangeSplitter
-import com.intellij.codeInsight.unwrap.UnwrapHandler
-import com.intellij.ide.IdeBundle
-import com.intellij.ide.util.PsiElementListCellRenderer
-import com.intellij.lang.injection.InjectedLanguageManager
-import com.intellij.lang.java.JavaLanguage
-import com.intellij.openapi.application.ApplicationManager
-import com.intellij.openapi.application.TransactionGuard
-import com.intellij.openapi.command.CommandAdapter
-import com.intellij.openapi.command.CommandEvent
-import com.intellij.openapi.command.CommandProcessor
-import com.intellij.openapi.editor.Editor
-import com.intellij.openapi.editor.colors.EditorColors
-import com.intellij.openapi.editor.colors.EditorColorsManager
-import com.intellij.openapi.editor.markup.HighlighterTargetArea
-import com.intellij.openapi.editor.markup.RangeHighlighter
-import com.intellij.openapi.editor.markup.TextAttributes
-import com.intellij.openapi.options.ConfigurationException
-import com.intellij.openapi.project.Project
-import com.intellij.openapi.roots.JavaProjectRootsUtil
-import com.intellij.openapi.ui.DialogWrapper
-import com.intellij.openapi.ui.Messages
-import com.intellij.openapi.ui.popup.*
-import com.intellij.openapi.util.Pass
-import com.intellij.openapi.util.TextRange
-import com.intellij.openapi.util.text.StringUtil
-import com.intellij.openapi.vfs.LocalFileSystem
-import com.intellij.openapi.vfs.VirtualFile
-import com.intellij.psi.*
-import com.intellij.psi.impl.light.LightElement
-import com.intellij.psi.presentation.java.SymbolPresentationUtil
-import com.intellij.psi.util.PsiTreeUtil
-import com.intellij.refactoring.BaseRefactoringProcessor.ConflictsInTestsException
-import com.intellij.refactoring.changeSignature.ChangeSignatureUtil
-import com.intellij.refactoring.listeners.RefactoringEventData
-import com.intellij.refactoring.listeners.RefactoringEventListener
-import com.intellij.refactoring.ui.ConflictsDialog
-import com.intellij.refactoring.util.ConflictsUtil
-import com.intellij.refactoring.util.RefactoringUIUtil
-import com.intellij.ui.components.JBList
-import com.intellij.usageView.UsageViewTypeLocation
-import com.intellij.util.VisibilityUtil
-import com.intellij.util.containers.MultiMap
-import org.jetbrains.kotlin.asJava.LightClassUtil
-import org.jetbrains.kotlin.asJava.elements.KtLightMethod
-import org.jetbrains.kotlin.asJava.getAccessorLightMethods
-import org.jetbrains.kotlin.asJava.namedUnwrappedElement
-import org.jetbrains.kotlin.asJava.toLightClass
-import org.jetbrains.kotlin.descriptors.*
-import org.jetbrains.kotlin.descriptors.impl.AnonymousFunctionDescriptor
-import org.jetbrains.kotlin.descriptors.impl.LocalVariableDescriptor
-import org.jetbrains.kotlin.diagnostics.Errors
-import org.jetbrains.kotlin.idea.KotlinBundle
-import org.jetbrains.kotlin.idea.KotlinFileType
-import org.jetbrains.kotlin.idea.KotlinLanguage
-import org.jetbrains.kotlin.idea.caches.resolve.analyze
-import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall
-import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
-import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
-import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
-import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
-import org.jetbrains.kotlin.idea.core.*
-import org.jetbrains.kotlin.idea.core.util.showYesNoCancelDialog
-import org.jetbrains.kotlin.idea.j2k.IdeaJavaToKotlinServices
-import org.jetbrains.kotlin.idea.project.languageVersionSettings
-import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinValVar
-import org.jetbrains.kotlin.idea.refactoring.changeSignature.toValVar
-import org.jetbrains.kotlin.idea.refactoring.memberInfo.KtPsiClassWrapper
-import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
-import org.jetbrains.kotlin.idea.util.ProjectRootsUtil
-import org.jetbrains.kotlin.idea.util.actualsForExpected
-import org.jetbrains.kotlin.idea.util.liftToExpected
-import org.jetbrains.kotlin.idea.util.string.collapseSpaces
-import org.jetbrains.kotlin.j2k.ConverterSettings
-import org.jetbrains.kotlin.j2k.JavaToKotlinConverter
-import org.jetbrains.kotlin.lexer.KtTokens
-import org.jetbrains.kotlin.name.FqName
-import org.jetbrains.kotlin.name.FqNameUnsafe
-import org.jetbrains.kotlin.psi.*
-import org.jetbrains.kotlin.psi.codeFragmentUtil.suppressDiagnosticsInDebugMode
-import org.jetbrains.kotlin.psi.psiUtil.*
-import org.jetbrains.kotlin.renderer.DescriptorRenderer
-import org.jetbrains.kotlin.resolve.*
-import org.jetbrains.kotlin.resolve.calls.callUtil.getCallWithAssert
-import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
-import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver
-import org.jetbrains.kotlin.resolve.source.getPsi
-import java.io.File
-import java.lang.annotation.Retention
-import java.util.*
-import javax.swing.Icon
-
-val CHECK_SUPER_METHODS_YES_NO_DIALOG = "CHECK_SUPER_METHODS_YES_NO_DIALOG"
-
-@JvmOverloads
-fun getOrCreateKotlinFile(fileName: String,
- targetDir: PsiDirectory,
- packageName: String? = targetDir.getPackage()?.qualifiedName): KtFile? =
- (targetDir.findFile(fileName) ?: createKotlinFile(fileName, targetDir, packageName)) as? KtFile
-
-fun createKotlinFile(fileName: String,
- targetDir: PsiDirectory,
- packageName: String? = targetDir.getPackage()?.qualifiedName): KtFile {
- targetDir.checkCreateFile(fileName)
- val packageFqName = packageName?.let(::FqName) ?: FqName.ROOT
- val file = PsiFileFactory.getInstance(targetDir.project).createFileFromText(
- fileName, KotlinFileType.INSTANCE, if (!packageFqName.isRoot) "package ${packageFqName.quoteSegmentsIfNeeded()} \n\n" else ""
- )
-
- return targetDir.add(file) as KtFile
-}
-
-fun File.toVirtualFile(): VirtualFile? = LocalFileSystem.getInstance().findFileByIoFile(this)
-
-fun File.toPsiFile(project: Project): PsiFile? = toVirtualFile()?.toPsiFile(project)
-
-fun File.toPsiDirectory(project: Project): PsiDirectory? {
- return toVirtualFile()?.let { vfile -> PsiManager.getInstance(project).findDirectory(vfile) }
-}
-
-fun VirtualFile.toPsiFile(project: Project): PsiFile? = PsiManager.getInstance(project).findFile(this)
-
-fun VirtualFile.toPsiDirectory(project: Project): PsiDirectory? = PsiManager.getInstance(project).findDirectory(this)
-
-fun VirtualFile.toPsiFileOrDirectory(project: Project): PsiFileSystemItem? = if (isDirectory) toPsiDirectory(project) else toPsiFile(project)
-
-fun PsiElement.getUsageContext(): PsiElement {
- return when (this) {
- is KtElement -> PsiTreeUtil.getParentOfType(
- this,
- KtPropertyAccessor::class.java,
- KtProperty::class.java,
- KtNamedFunction::class.java,
- KtConstructor::class.java,
- KtClassOrObject::class.java
- ) ?: containingFile
- else -> ConflictsUtil.getContainer(this)
- }
-}
-
-fun PsiElement.isInJavaSourceRoot(): Boolean =
- !JavaProjectRootsUtil.isOutsideJavaSourceRoot(containingFile)
-
-fun KtFile.createTempCopy(text: String? = null): KtFile {
- val tmpFile = KtPsiFactory(this).createAnalyzableFile(name, text ?: this.text ?: "", this)
- tmpFile.originalFile = this
- tmpFile.suppressDiagnosticsInDebugMode = suppressDiagnosticsInDebugMode
- return tmpFile
-}
-
-fun PsiElement.getAllExtractionContainers(strict: Boolean = true): List {
- val containers = ArrayList()
-
- var objectOrNonInnerNestedClassFound = false
- val parents = if (strict) parents else parentsWithSelf
- for (element in parents) {
- val isValidContainer = when (element) {
- is KtFile -> true
- is KtClassBody -> !objectOrNonInnerNestedClassFound || element.parent is KtObjectDeclaration
- is KtBlockExpression -> !objectOrNonInnerNestedClassFound
- else -> false
- }
- if (!isValidContainer) continue
-
- containers.add(element as KtElement)
-
- if (!objectOrNonInnerNestedClassFound) {
- val bodyParent = (element as? KtClassBody)?.parent
- objectOrNonInnerNestedClassFound =
- (bodyParent is KtObjectDeclaration && !bodyParent.isObjectLiteral())
- || (bodyParent is KtClass && !bodyParent.isInner())
- }
- }
-
- return containers
-}
-
-fun PsiElement.getExtractionContainers(strict: Boolean = true, includeAll: Boolean = false): List {
- fun getEnclosingDeclaration(element: PsiElement, strict: Boolean): PsiElement? {
- return (if (strict) element.parents else element.parentsWithSelf)
- .filter {
- (it is KtDeclarationWithBody && it !is KtFunctionLiteral && !(it is KtNamedFunction && it.name == null))
- || it is KtAnonymousInitializer
- || it is KtClassBody
- || it is KtFile
- }
- .firstOrNull()
- }
-
- if (includeAll) return getAllExtractionContainers(strict)
-
- val enclosingDeclaration = getEnclosingDeclaration(this, strict)?.let {
- if (it is KtDeclarationWithBody || it is KtAnonymousInitializer) getEnclosingDeclaration(it, true) else it
- }
-
- return when (enclosingDeclaration) {
- is KtFile -> Collections.singletonList(enclosingDeclaration)
- is KtClassBody -> getAllExtractionContainers(strict).filterIsInstance()
- else -> {
- val targetContainer = when (enclosingDeclaration) {
- is KtDeclarationWithBody -> enclosingDeclaration.bodyExpression
- is KtAnonymousInitializer -> enclosingDeclaration.body
- else -> null
- }
- if (targetContainer is KtBlockExpression) Collections.singletonList(targetContainer) else Collections.emptyList()
- }
- }
-}
-
-fun Project.checkConflictsInteractively(
- conflicts: MultiMap,
- onShowConflicts: () -> Unit = {},
- onAccept: () -> Unit) {
- if (!conflicts.isEmpty) {
- if (ApplicationManager.getApplication()!!.isUnitTestMode) throw ConflictsInTestsException(conflicts.values())
-
- val dialog = ConflictsDialog(this, conflicts) { onAccept() }
- dialog.show()
- if (!dialog.isOK) {
- if (dialog.isShowConflicts) {
- onShowConflicts()
- }
- return
- }
- }
-
- onAccept()
-}
-
-fun reportDeclarationConflict(
- conflicts: MultiMap,
- declaration: PsiElement,
- message: (renderedDeclaration: String) -> String
-) {
- conflicts.putValue(declaration, message(RefactoringUIUtil.getDescription(declaration, true).capitalize()))
-}
-
-fun getPsiElementPopup(
- editor: Editor,
- elements: List,
- renderer: PsiElementListCellRenderer,
- title: String?,
- highlightSelection: Boolean,
- toPsi: (T) -> E,
- processor: (T) -> Boolean): JBPopup {
- val highlighter = if (highlightSelection) SelectionAwareScopeHighlighter(editor) else null
-
- val list = JBList(elements.map(toPsi))
- list.cellRenderer = renderer
- list.addListSelectionListener {
- highlighter?.dropHighlight()
- val index = list.selectedIndex
- if (index >= 0) {
- highlighter?.highlight(list.model!!.getElementAt(index) as PsiElement)
- }
- }
-
- return with(PopupChooserBuilder(list)) {
- title?.let { setTitle(it) }
- renderer.installSpeedSearch(this, true)
- setItemChoosenCallback {
- val index = list.selectedIndex
- if (index >= 0) {
- processor(elements[index])
- }
- }
- addListener(object : JBPopupAdapter() {
- override fun onClosed(event: LightweightWindowEvent?) {
- highlighter?.dropHighlight()
- }
- })
-
- createPopup()
- }
-}
-
-class SelectionAwareScopeHighlighter(val editor: Editor) {
- private val highlighters = ArrayList()
-
- private fun addHighlighter(r: TextRange, attr: TextAttributes) {
- highlighters.add(
- editor.markupModel.addRangeHighlighter(
- r.startOffset,
- r.endOffset,
- UnwrapHandler.HIGHLIGHTER_LEVEL,
- attr,
- HighlighterTargetArea.EXACT_RANGE
- )
- )
- }
-
- fun highlight(wholeAffected: PsiElement) {
- dropHighlight()
-
- val affectedRange = wholeAffected.textRange ?: return
-
- val attributes = EditorColorsManager.getInstance().globalScheme.getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES)!!
- val selectedRange = with(editor.selectionModel) { TextRange(selectionStart, selectionEnd) }
- for (r in RangeSplitter.split(affectedRange, Collections.singletonList(selectedRange))) {
- addHighlighter(r, attributes)
- }
- }
-
- fun dropHighlight() {
- highlighters.forEach { it.dispose() }
- highlighters.clear()
- }
-}
-
-fun PsiFile.getLineStartOffset(line: Int): Int? {
- val doc = viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(this)
- if (doc != null && line >= 0 && line < doc.lineCount) {
- val startOffset = doc.getLineStartOffset(line)
- val element = findElementAt(startOffset) ?: return startOffset
-
- if (element is PsiWhiteSpace || element is PsiComment) {
- return PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java, PsiComment::class.java)?.startOffset ?: startOffset
- }
- return startOffset
- }
-
- return null
-}
-
-fun PsiFile.getLineEndOffset(line: Int): Int? {
- val document = viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(this)
- return document?.getLineEndOffset(line)
-}
-
-fun PsiElement.getLineNumber(start: Boolean = true): Int {
- val document = containingFile.viewProvider.document ?: PsiDocumentManager.getInstance(project).getDocument(containingFile)
- return document?.getLineNumber(if (start) this.startOffset else this.endOffset) ?: 0
-}
-
-fun PsiElement.getLineCount(): Int {
- val doc = containingFile?.let { file -> PsiDocumentManager.getInstance(project).getDocument(file) }
- if (doc != null) {
- val spaceRange = textRange ?: TextRange.EMPTY_RANGE
-
- if (spaceRange.endOffset <= doc.textLength) {
- val startLine = doc.getLineNumber(spaceRange.startOffset)
- val endLine = doc.getLineNumber(spaceRange.endOffset)
-
- return endLine - startLine
- }
- }
-
- return (text ?: "").count { it == '\n' } + 1
-}
-
-fun PsiElement.isMultiLine(): Boolean = getLineCount() > 1
-
-class SeparateFileWrapper(manager: PsiManager) : LightElement(manager, KotlinLanguage.INSTANCE) {
- override fun toString() = ""
-}
-
-fun chooseContainerElement(
- containers: List,
- editor: Editor,
- title: String,
- highlightSelection: Boolean,
- toPsi: (T) -> PsiElement,
- onSelect: (T) -> Unit) {
- return getPsiElementPopup(
- editor,
- containers,
- object : PsiElementListCellRenderer() {
- private fun PsiElement.renderName(): String {
- if (this is KtPropertyAccessor) {
- return property.renderName() + if (isGetter) ".get" else ".set"
- }
- if (this is KtObjectDeclaration && this.isCompanion()) {
- return "Companion object of ${getStrictParentOfType()?.renderName() ?: ""}"
- }
- return (this as? PsiNamedElement)?.name ?: ""
- }
-
- private fun PsiElement.renderDeclaration(): String? {
- if (this is KtFunctionLiteral || isFunctionalExpression()) return renderText()
-
- val descriptor = when {
- this is KtFile -> name
- this is KtElement -> analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, this]
- this is PsiMember -> getJavaMemberDescriptor()
- else -> null
- } ?: return null
- val name = renderName()
- val params = (descriptor as? FunctionDescriptor)?.valueParameters
- ?.map { DescriptorRenderer.Companion.SHORT_NAMES_IN_TYPES.renderType(it.type) }
- ?.joinToString(", ", "(", ")") ?: ""
- return "$name$params"
- }
-
- private fun PsiElement.renderText(): String {
- if (this is SeparateFileWrapper) return "Extract to separate file"
- return StringUtil.shortenTextWithEllipsis(text!!.collapseSpaces(), 53, 0)
- }
-
- private fun PsiElement.getRepresentativeElement(): PsiElement {
- return when (this) {
- is KtBlockExpression -> (parent as? KtDeclarationWithBody) ?: this
- is KtClassBody -> parent as KtClassOrObject
- else -> this
- }
- }
-
- override fun getElementText(element: PsiElement): String? {
- val representativeElement = element.getRepresentativeElement()
- return representativeElement.renderDeclaration() ?: representativeElement.renderText()
- }
-
- override fun getContainerText(element: PsiElement, name: String?): String? = null
-
- override fun getIconFlags(): Int = 0
-
- override fun getIcon(element: PsiElement): Icon? =
- super.getIcon(element.getRepresentativeElement())
- },
- title,
- highlightSelection,
- toPsi,
- {
- onSelect(it)
- true
- }
- ).showInBestPositionFor(editor)
-}
-
-fun chooseContainerElementIfNecessary(
- containers: List,
- editor: Editor,
- title: String,
- highlightSelection: Boolean,
- toPsi: (T) -> PsiElement,
- onSelect: (T) -> Unit
-) {
- when {
- containers.isEmpty() -> return
- containers.size == 1 || ApplicationManager.getApplication()!!.isUnitTestMode -> onSelect(containers.first())
- else -> chooseContainerElement(containers, editor, title, highlightSelection, toPsi, onSelect)
- }
-}
-
-fun PsiElement.isTrueJavaMethod(): Boolean = this is PsiMethod && this !is KtLightMethod
-
-fun PsiElement.canRefactor(): Boolean {
- if (!this.isValid) return false
-
- return when {
- this is PsiPackage ->
- directories.any { it.canRefactor() }
- this is KtElement ||
- this is PsiMember && language == JavaLanguage.INSTANCE ||
- this is PsiDirectory ->
- ProjectRootsUtil.isInProjectSource(this, includeScriptsOutsideSourceRoots = true)
- else ->
- false
- }
-}
-
-private fun copyModifierListItems(from: PsiModifierList, to: PsiModifierList, withPsiModifiers: Boolean = true) {
- if (withPsiModifiers) {
- for (modifier in PsiModifier.MODIFIERS) {
- if (from.hasExplicitModifier(modifier)) {
- to.setModifierProperty(modifier, true)
- }
- }
- }
- for (annotation in from.annotations) {
- val annotationName = annotation.qualifiedName ?: continue
-
- if (Retention::class.java.name != annotationName) {
- to.addAnnotation(annotationName)
- }
- }
-}
-
-private fun copyTypeParameters(
- from: T,
- to: T,
- inserter: (T, PsiTypeParameterList) -> Unit
-) where T : PsiTypeParameterListOwner, T : PsiNameIdentifierOwner {
- val factory = PsiElementFactory.SERVICE.getInstance((from as PsiElement).project)
- val templateTypeParams = from.typeParameterList?.typeParameters ?: PsiTypeParameter.EMPTY_ARRAY
- if (templateTypeParams.isNotEmpty()) {
- inserter(to, factory.createTypeParameterList())
- val targetTypeParamList = to.typeParameterList
- val newTypeParams = templateTypeParams.map {
- factory.createTypeParameter(it.name, it.extendsList.referencedTypes)
- }
- ChangeSignatureUtil.synchronizeList(
- targetTypeParamList,
- newTypeParams,
- { it!!.typeParameters.toList() },
- BooleanArray(newTypeParams.size)
- )
- }
-}
-
-fun createJavaMethod(function: KtFunction, targetClass: PsiClass): PsiMethod {
- val template = LightClassUtil.getLightClassMethod(function)
- ?: throw AssertionError("Can't generate light method: ${function.getElementTextWithContext()}")
- return createJavaMethod(template, targetClass)
-}
-
-fun createJavaMethod(template: PsiMethod, targetClass: PsiClass): PsiMethod {
- val factory = PsiElementFactory.SERVICE.getInstance(template.project)
- val methodToAdd = if (template.isConstructor) {
- factory.createConstructor(template.name)
- }
- else {
- factory.createMethod(template.name, template.returnType)
- }
- val method = targetClass.add(methodToAdd) as PsiMethod
-
- copyModifierListItems(template.modifierList, method.modifierList)
- if (targetClass.isInterface) {
- method.modifierList.setModifierProperty(PsiModifier.FINAL, false)
- }
-
- copyTypeParameters(template, method) { method, typeParameterList ->
- method.addAfter(typeParameterList, method.modifierList)
- }
-
- val targetParamList = method.parameterList
- val newParams = template.parameterList.parameters.map {
- val param = factory.createParameter(it.name!!, it.type)
- copyModifierListItems(it.modifierList!!, param.modifierList!!)
- param
- }
- ChangeSignatureUtil.synchronizeList(
- targetParamList,
- newParams,
- { it.parameters.toList() },
- BooleanArray(newParams.size)
- )
-
- if (template.modifierList.hasModifierProperty(PsiModifier.ABSTRACT) || targetClass.isInterface) {
- method.body!!.delete()
- }
- else if (!template.isConstructor) {
- CreateFromUsageUtils.setupMethodBody(method)
- }
-
- return method
-}
-
-fun createJavaField(property: KtNamedDeclaration, targetClass: PsiClass): PsiField {
- val accessorLightMethods = property.getAccessorLightMethods()
- val template = accessorLightMethods.getter
- ?: throw AssertionError("Can't generate light method: ${property.getElementTextWithContext()}")
-
- val factory = PsiElementFactory.SERVICE.getInstance(template.project)
- val field = targetClass.add(factory.createField(property.name!!, template.returnType!!)) as PsiField
-
- with(field.modifierList!!) {
- val templateModifiers = template.modifierList
- setModifierProperty(VisibilityUtil.getVisibilityModifier(templateModifiers), true)
- if ((property as KtValVarKeywordOwner).valOrVarKeyword.toValVar() != KotlinValVar.Var || targetClass.isInterface) {
- setModifierProperty(PsiModifier.FINAL, true)
- }
- copyModifierListItems(templateModifiers, this, false)
- }
-
- return field
-}
-
-fun createJavaClass(klass: KtClass, targetClass: PsiClass?, forcePlainClass: Boolean = false): PsiClass {
- val kind = if (forcePlainClass) ClassKind.CLASS else (klass.unsafeResolveToDescriptor() as ClassDescriptor).kind
-
- val factory = PsiElementFactory.SERVICE.getInstance(klass.project)
- val className = klass.name!!
- val javaClassToAdd = when (kind) {
- ClassKind.CLASS -> factory.createClass(className)
- ClassKind.INTERFACE -> factory.createInterface(className)
- ClassKind.ANNOTATION_CLASS -> factory.createAnnotationType(className)
- ClassKind.ENUM_CLASS -> factory.createEnum(className)
- else -> throw AssertionError("Unexpected class kind: ${klass.getElementTextWithContext()}")
- }
- val javaClass = (targetClass?.add(javaClassToAdd) ?: javaClassToAdd) as PsiClass
-
- val template = klass.toLightClass() ?: throw AssertionError("Can't generate light class: ${klass.getElementTextWithContext()}")
-
- copyModifierListItems(template.modifierList!!, javaClass.modifierList!!)
- if (template.isInterface) {
- javaClass.modifierList!!.setModifierProperty(PsiModifier.ABSTRACT, false)
- }
-
- copyTypeParameters(template, javaClass) { klass, typeParameterList ->
- klass.addAfter(typeParameterList, klass.nameIdentifier)
- }
-
- // Turning interface to class
- if (!javaClass.isInterface && template.isInterface) {
- val implementsList = factory.createReferenceListWithRole(
- template.extendsList?.referenceElements ?: PsiJavaCodeReferenceElement.EMPTY_ARRAY,
- PsiReferenceList.Role.IMPLEMENTS_LIST
- )
- implementsList?.let { javaClass.implementsList?.replace(it) }
- }
- else {
- val extendsList = factory.createReferenceListWithRole(
- template.extendsList?.referenceElements ?: PsiJavaCodeReferenceElement.EMPTY_ARRAY,
- PsiReferenceList.Role.EXTENDS_LIST
- )
- extendsList?.let { javaClass.extendsList?.replace(it) }
-
- val implementsList = factory.createReferenceListWithRole(
- template.implementsList?.referenceElements ?: PsiJavaCodeReferenceElement.EMPTY_ARRAY,
- PsiReferenceList.Role.IMPLEMENTS_LIST
- )
- implementsList?.let { javaClass.implementsList?.replace(it) }
- }
-
- for (method in template.methods) {
- val hasParams = method.parameterList.parametersCount > 0
- val needSuperCall = !template.isEnum &&
- (template.superClass?.constructors ?: PsiMethod.EMPTY_ARRAY).all {
- it.parameterList.parametersCount > 0
- }
- if (method.isConstructor && !(hasParams || needSuperCall)) continue
- with(createJavaMethod(method, javaClass)) {
- if (isConstructor && needSuperCall) {
- body!!.add(factory.createStatementFromText("super();", this))
- }
- }
- }
-
- return javaClass
-}
-
-fun PsiElement.j2kText(): String? {
- if (language != JavaLanguage.INSTANCE) return null
-
- val j2kConverter = JavaToKotlinConverter(project,
- ConverterSettings.Companion.defaultSettings,
- IdeaJavaToKotlinServices)
- return j2kConverter.elementsToKotlin(listOf(this)).results.single()?.text ?: return null //TODO: insert imports
-}
-
-fun PsiExpression.j2k(): KtExpression? {
- val text = j2kText() ?: return null
- return KtPsiFactory(project).createExpression(text)
-}
-
-fun PsiMember.j2k(): KtNamedDeclaration? {
- val text = j2kText() ?: return null
- return KtPsiFactory(project).createDeclaration(text)
-}
-
-internal fun broadcastRefactoringExit(project: Project, refactoringId: String) {
- project.messageBus.syncPublisher(KotlinRefactoringEventListener.EVENT_TOPIC).onRefactoringExit(refactoringId)
-}
-
-// IMPORTANT: Target refactoring must support KotlinRefactoringEventListener
-internal abstract class CompositeRefactoringRunner(
- val project: Project,
- val refactoringId: String
-) {
- protected abstract fun runRefactoring()
-
- protected open fun onRefactoringDone() {}
- protected open fun onExit() {}
-
- fun run() {
- val connection = project.messageBus.connect()
- connection.subscribe(
- RefactoringEventListener.REFACTORING_EVENT_TOPIC,
- object : RefactoringEventListener {
- override fun undoRefactoring(refactoringId: String) {
-
- }
-
- override fun refactoringStarted(refactoringId: String, beforeData: RefactoringEventData?) {
-
- }
-
- override fun conflictsDetected(refactoringId: String, conflictsData: RefactoringEventData) {
-
- }
-
- override fun refactoringDone(refactoringId: String, afterData: RefactoringEventData?) {
- if (refactoringId == this@CompositeRefactoringRunner.refactoringId) {
- onRefactoringDone()
- }
- }
- }
- )
- connection.subscribe(
- KotlinRefactoringEventListener.EVENT_TOPIC,
- object : KotlinRefactoringEventListener {
- override fun onRefactoringExit(refactoringId: String) {
- if (refactoringId == this@CompositeRefactoringRunner.refactoringId) {
- try {
- onExit()
- } finally {
- connection.disconnect()
- }
- }
- }
- }
- )
- runRefactoring()
- }
-}
-
-@Throws(ConfigurationException::class) fun KtElement?.validateElement(errorMessage: String) {
- if (this == null) throw ConfigurationException(errorMessage)
-
- try {
- AnalyzingUtils.checkForSyntacticErrors(this)
- }
- catch(e: Exception) {
- throw ConfigurationException(errorMessage)
- }
-}
-
-fun invokeOnceOnCommandFinish(action: () -> Unit) {
- val commandProcessor = CommandProcessor.getInstance()
- val listener = object : CommandAdapter() {
- override fun beforeCommandFinished(event: CommandEvent?) {
- action()
- commandProcessor.removeCommandListener(this)
- }
- }
- commandProcessor.addCommandListener(listener)
-}
-
-fun FqNameUnsafe.hasIdentifiersOnly(): Boolean = pathSegments().all { it.asString().quoteIfNeeded().isIdentifier() }
-
-fun FqName.hasIdentifiersOnly(): Boolean = pathSegments().all { it.asString().quoteIfNeeded().isIdentifier() }
-
-fun PsiNamedElement.isInterfaceClass(): Boolean = when (this) {
- is KtClass -> isInterface()
- is PsiClass -> isInterface
- is KtPsiClassWrapper -> psiClass.isInterface
- else -> false
-}
-
-fun KtNamedDeclaration.isAbstract(): Boolean {
- if (hasModifier(KtTokens.ABSTRACT_KEYWORD)) return true
- if (!(containingClassOrObject?.isInterfaceClass() ?: false)) return false
- return when (this) {
- is KtProperty -> initializer == null && delegate == null && accessors.isEmpty()
- is KtNamedFunction -> !hasBody()
- else -> false
- }
-}
-
-fun KtNamedDeclaration.isConstructorDeclaredProperty() = this is KtParameter && ownerFunction is KtPrimaryConstructor && hasValOrVar()
-
-fun replaceListPsiAndKeepDelimiters(
- originalList: ListType,
- newList: ListType,
- @Suppress("UNCHECKED_CAST") listReplacer: ListType.(ListType) -> ListType = { replace(it) as ListType },
- itemsFun: ListType.() -> List
-): ListType {
- originalList.children.takeWhile { it is PsiErrorElement }.forEach { it.delete() }
-
- val oldParameters = originalList.itemsFun().toMutableList()
- val newParameters = newList.itemsFun()
- val oldCount = oldParameters.size
- val newCount = newParameters.size
-
- val commonCount = Math.min(oldCount, newCount)
- for (i in 0..commonCount - 1) {
- oldParameters[i] = oldParameters[i].replace(newParameters[i]) as KtElement
- }
-
- if (commonCount == 0) return originalList.listReplacer(newList)
-
- val lastOriginalParameter = oldParameters.last()
-
- if (oldCount > commonCount) {
- originalList.deleteChildRange(oldParameters[commonCount - 1].nextSibling, lastOriginalParameter)
- }
- else if (newCount > commonCount) {
- val psiBeforeLastParameter = lastOriginalParameter.prevSibling
- val withMultiline = (psiBeforeLastParameter is PsiWhiteSpace || psiBeforeLastParameter is PsiComment) && psiBeforeLastParameter.textContains('\n')
- val extraSpace = if (withMultiline) KtPsiFactory(originalList).createNewLine() else null
- originalList.addRangeAfter(newParameters[commonCount - 1].nextSibling, newParameters.last(), lastOriginalParameter)
- if (extraSpace != null) {
- val addedItems = originalList.itemsFun().subList(commonCount, newCount)
- for (addedItem in addedItems) {
- val elementBefore = addedItem.prevSibling
- if ((elementBefore !is PsiWhiteSpace && elementBefore !is PsiComment) || !elementBefore.textContains('\n')) {
- addedItem.parent.addBefore(extraSpace, addedItem)
- }
- }
- }
- }
-
- return originalList
-}
-
-fun Pass(body: (T) -> Unit) = object : Pass() {
- override fun pass(t: T) = body(t)
-}
-
-fun KtExpression.removeTemplateEntryBracesIfPossible(): KtExpression {
- val parent = parent as? KtBlockStringTemplateEntry ?: return this
- val newEntry = if (parent.canDropBraces()) parent.dropBraces() else parent
- return newEntry.expression!!
-}
-
-fun dropOverrideKeywordIfNecessary(element: KtNamedDeclaration) {
- val callableDescriptor = element.resolveToDescriptorIfAny() as? CallableDescriptor ?: return
- if (callableDescriptor.overriddenDescriptors.isEmpty()) {
- element.removeModifier(KtTokens.OVERRIDE_KEYWORD)
- }
-}
-
-fun dropOperatorKeywordIfNecessary(element: KtNamedDeclaration) {
- val callableDescriptor = element.resolveToDescriptorIfAny() as? CallableDescriptor ?: return
- val diagnosticHolder = BindingTraceContext()
- OperatorModifierChecker.check(element, callableDescriptor, diagnosticHolder, element.languageVersionSettings)
- if (diagnosticHolder.bindingContext.diagnostics.any { it.factory == Errors.INAPPLICABLE_OPERATOR_MODIFIER }) {
- element.removeModifier(KtTokens.OPERATOR_KEYWORD)
- }
-}
-
-fun getQualifiedTypeArgumentList(initializer: KtExpression): KtTypeArgumentList? {
- val call = initializer.resolveToCall() ?: return null
- val typeArgumentMap = call.typeArguments
- val typeArguments = call.candidateDescriptor.typeParameters.mapNotNull { typeArgumentMap[it] }
- val renderedList = typeArguments.joinToString(prefix = "<", postfix = ">") {
- IdeDescriptorRenderers.SOURCE_CODE_NOT_NULL_TYPE_APPROXIMATION.renderType(it)
- }
- return KtPsiFactory(initializer).createTypeArguments(renderedList)
-}
-
-fun addTypeArgumentsIfNeeded(expression: KtExpression, typeArgumentList: KtTypeArgumentList) {
- val context = expression.analyze(BodyResolveMode.PARTIAL_WITH_DIAGNOSTICS)
- val call = expression.getCallWithAssert(context)
- val callElement = call.callElement as? KtCallExpression ?: return
- if (call.typeArgumentList != null) return
- val callee = call.calleeExpression ?: return
- if (context.diagnostics.forElement(callee).all { it.factory != Errors.TYPE_INFERENCE_NO_INFORMATION_FOR_PARAMETER }) return
-
- callElement.addAfter(typeArgumentList, callElement.calleeExpression)
- ShortenReferences.DEFAULT.process(callElement.typeArgumentList!!)
-}
-
-internal fun DeclarationDescriptor.getThisLabelName(): String {
- if (!name.isSpecial) return name.asString()
- if (this is AnonymousFunctionDescriptor) {
- val function = source.getPsi() as? KtFunction
- val argument = function?.parent as? KtValueArgument
- ?: (function?.parent as? KtLambdaExpression)?.parent as? KtValueArgument
- val callElement = argument?.getStrictParentOfType()
- val callee = callElement?.calleeExpression as? KtSimpleNameExpression
- if (callee != null) return callee.text
- }
- return ""
-}
-
-internal fun DeclarationDescriptor.explicateAsTextForReceiver(): String {
- val labelName = getThisLabelName()
- return if (labelName.isEmpty()) "this" else "this@$labelName"
-}
-
-internal fun ImplicitReceiver.explicateAsText(): String {
- return declarationDescriptor.explicateAsTextForReceiver()
-}
-
-val PsiFile.isInjectedFragment: Boolean
- get() = InjectedLanguageManager.getInstance(project).isInjectedFragment(this)
-
-val PsiElement.isInsideInjectedFragment: Boolean
- get() = containingFile.isInjectedFragment
-
-fun checkSuperMethods(
- declaration: KtDeclaration,
- ignore: Collection?,
- actionString: String
-): List {
- fun getClassDescriptions(overriddenElementsToDescriptor: Map): List {
- return overriddenElementsToDescriptor.entries.map { entry ->
- val (element, descriptor) = entry
- val description = when (element) {
- is KtNamedFunction, is KtProperty, is KtParameter -> formatClassDescriptor(descriptor.containingDeclaration)
- is PsiMethod -> {
- val psiClass = element.containingClass ?: error("Invalid element: ${element.getText()}")
- formatPsiClass(psiClass, true, false)
- }
- else -> error("Unexpected element: ${element.getElementTextWithContext()}")
- }
- " $description\n"
- }
- }
-
- fun askUserForMethodsToSearch(
- declarationDescriptor: CallableDescriptor,
- overriddenElementsToDescriptor: Map
- ): List {
- val superClassDescriptions = getClassDescriptions(overriddenElementsToDescriptor)
-
- val message = KotlinBundle.message(
- "x.overrides.y.in.class.list",
- DescriptorRenderer.COMPACT_WITH_SHORT_TYPES.render(declarationDescriptor),
- "\n${superClassDescriptions.joinToString(separator = "")}",
- actionString
- )
-
- val exitCode = showYesNoCancelDialog(
- CHECK_SUPER_METHODS_YES_NO_DIALOG,
- declaration.project, message, IdeBundle.message("title.warning"), Messages.getQuestionIcon(), Messages.YES)
- return when (exitCode) {
- Messages.YES -> overriddenElementsToDescriptor.keys.toList()
- Messages.NO -> listOf(declaration)
- else -> emptyList()
- }
- }
-
-
- val declarationDescriptor = declaration.unsafeResolveToDescriptor() as CallableDescriptor
-
- if (declarationDescriptor is LocalVariableDescriptor) return listOf(declaration)
-
- val project = declaration.project
- val overriddenElementsToDescriptor = HashMap()
- for (overriddenDescriptor in DescriptorUtils.getAllOverriddenDescriptors(declarationDescriptor)) {
- val overriddenDeclaration = DescriptorToSourceUtilsIde.getAnyDeclaration(project, overriddenDescriptor) ?: continue
- if (overriddenDeclaration is KtNamedFunction || overriddenDeclaration is KtProperty || overriddenDeclaration is PsiMethod || overriddenDeclaration is KtParameter) {
- overriddenElementsToDescriptor[overriddenDeclaration] = overriddenDescriptor
- }
- }
- if (ignore != null) {
- overriddenElementsToDescriptor.keys.removeAll(ignore)
- }
-
- if (overriddenElementsToDescriptor.isEmpty()) return listOf(declaration)
-
- return askUserForMethodsToSearch(declarationDescriptor, overriddenElementsToDescriptor)
-}
-
-fun checkSuperMethodsWithPopup(
- declaration: KtNamedDeclaration,
- deepestSuperMethods: List,
- actionString: String,
- editor: Editor,
- action: (List) -> Unit
-) {
- if (deepestSuperMethods.isEmpty()) return action(listOf(declaration))
-
- val superMethod = deepestSuperMethods.first()
-
- val (superClass, isAbstract) = when (superMethod) {
- is PsiMember -> superMethod.containingClass to superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
- is KtNamedDeclaration -> superMethod.containingClassOrObject to superMethod.isAbstract()
- else -> null
- } ?: return action(listOf(declaration))
- if (superClass == null) return action(listOf(declaration))
-
- if (ApplicationManager.getApplication().isUnitTestMode) return action(deepestSuperMethods)
-
- val kind = when (declaration) {
- is KtNamedFunction -> "function"
- is KtProperty, is KtParameter -> "property"
- else -> return
- }
-
- val unwrappedSupers = deepestSuperMethods.mapNotNull { it.namedUnwrappedElement }
- val hasJavaMethods = unwrappedSupers.any { it is PsiMethod }
- val hasKtMembers = unwrappedSupers.any { it is KtNamedDeclaration }
- val superKind = when {
- hasJavaMethods && hasKtMembers -> "member"
- hasJavaMethods -> "method"
- else -> kind
- }
-
- val renameBase = actionString + " base $superKind" + (if (deepestSuperMethods.size > 1) "s" else "")
- val renameCurrent = actionString + " only current $kind"
- val title = buildString {
- append(declaration.name)
- append(if (isAbstract) " implements " else " overrides ")
- append(ElementDescriptionUtil.getElementDescription(superMethod, UsageViewTypeLocation.INSTANCE))
- append(" of ")
- append(SymbolPresentationUtil.getSymbolPresentableText(superClass))
- }
- val list = JBList(renameBase, renameCurrent)
- JBPopupFactory.getInstance()
- .createListPopupBuilder(list)
- .setTitle(title)
- .setMovable(false)
- .setResizable(false)
- .setRequestFocus(true)
- .setItemChoosenCallback {
- val value = list.selectedValue ?: return@setItemChoosenCallback
- val chosenElements = if (value == renameBase) deepestSuperMethods + declaration else listOf(declaration)
- action(chosenElements)
- }
- .createPopup()
- .showInBestPositionFor(editor)
-}
-
-fun KtNamedDeclaration.isCompanionMemberOf(klass: KtClassOrObject): Boolean {
- val containingObject = containingClassOrObject as? KtObjectDeclaration ?: return false
- return containingObject.isCompanion() && containingObject.containingClassOrObject == klass
-}
-
-internal fun KtDeclaration.withExpectedActuals(): List {
- val expect = liftToExpected() ?: return listOf(this)
- val actuals = expect.actualsForExpected()
- return listOf(expect) + actuals
-}
-
-internal fun KtDeclaration.resolveToExpectedDescriptorIfPossible(): DeclarationDescriptor {
- val descriptor = unsafeResolveToDescriptor()
- return descriptor.liftToExpected() ?: descriptor
-}
-
-fun DialogWrapper.showWithTransaction() {
- TransactionGuard.submitTransaction(disposable, Runnable { show() })
-}
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/util/PopupChooserBuilderWrapper.kt b/idea/src/org/jetbrains/kotlin/idea/util/PopupChooserBuilderWrapper.kt
new file mode 100644
index 00000000000..2e07056337f
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/util/PopupChooserBuilderWrapper.kt
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2010-2019 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.util
+
+import com.intellij.openapi.ui.popup.PopupChooserBuilder
+import javax.swing.JList
+
+// BUNCH: 181
+@Suppress("IncompatibleAPI")
+class PopupChooserBuilderWrapper(list: JList): PopupChooserBuilder(list)
\ No newline at end of file
diff --git a/idea/src/org/jetbrains/kotlin/idea/util/PopupChooserBuilderWrapper.kt.181 b/idea/src/org/jetbrains/kotlin/idea/util/PopupChooserBuilderWrapper.kt.181
new file mode 100644
index 00000000000..5e4cb710a27
--- /dev/null
+++ b/idea/src/org/jetbrains/kotlin/idea/util/PopupChooserBuilderWrapper.kt.181
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2010-2019 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.util
+
+import com.intellij.openapi.ui.popup.PopupChooserBuilder
+import javax.swing.JList
+
+// BUNCH: 181
+@Suppress("IncompatibleAPI")
+class PopupChooserBuilderWrapper(list: JList) : PopupChooserBuilder(list)
\ No newline at end of file