Fix 'Redundant qualifier name' warnings & refactoring in idea
This commit is contained in:
@@ -41,7 +41,7 @@ class KotlinGenerateEqualsWizard(
|
|||||||
needEquals: Boolean,
|
needEquals: Boolean,
|
||||||
needHashCode: Boolean
|
needHashCode: Boolean
|
||||||
) : AbstractGenerateEqualsWizard<KtClass, KtNamedDeclaration, KotlinMemberInfo>(
|
) : AbstractGenerateEqualsWizard<KtClass, KtNamedDeclaration, KotlinMemberInfo>(
|
||||||
project, KotlinGenerateEqualsWizard.BuilderImpl(klass, properties, needEquals, needHashCode)
|
project, BuilderImpl(klass, properties, needEquals, needHashCode)
|
||||||
) {
|
) {
|
||||||
private object MemberInfoModelImpl : AbstractMemberInfoModel<KtNamedDeclaration, KotlinMemberInfo>()
|
private object MemberInfoModelImpl : AbstractMemberInfoModel<KtNamedDeclaration, KotlinMemberInfo>()
|
||||||
|
|
||||||
@@ -60,13 +60,13 @@ class KotlinGenerateEqualsWizard(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
equalsPanel = if (needEquals) {
|
equalsPanel = if (needEquals) {
|
||||||
KotlinMemberSelectionPanel("Choose p&roperties to be included in equals()", memberInfos, null).apply {
|
KotlinMemberSelectionPanel("Choose properties to be included in equals()", memberInfos, null).apply {
|
||||||
table.memberInfoModel = MemberInfoModelImpl
|
table.memberInfoModel = MemberInfoModelImpl
|
||||||
}
|
}
|
||||||
} else null
|
} else null
|
||||||
|
|
||||||
hashCodePanel = if (needHashCode) {
|
hashCodePanel = if (needHashCode) {
|
||||||
KotlinMemberSelectionPanel("Choose p&roperties to be included in hashCode()", memberInfos, null).apply {
|
KotlinMemberSelectionPanel("Choose properties to be included in hashCode()", memberInfos, null).apply {
|
||||||
table.memberInfoModel = MemberInfoModelImpl
|
table.memberInfoModel = MemberInfoModelImpl
|
||||||
}
|
}
|
||||||
} else null
|
} else null
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ class KotlinReferenceTransferableData(
|
|||||||
return i
|
return i
|
||||||
}
|
}
|
||||||
|
|
||||||
public override fun clone() = KotlinReferenceTransferableData(Array(data.size, { data[it].clone() }))
|
public override fun clone() = KotlinReferenceTransferableData(Array(data.size) { data[it].clone() })
|
||||||
}
|
}
|
||||||
|
|
||||||
class KotlinReferenceData(
|
class KotlinReferenceData(
|
||||||
@@ -64,7 +64,7 @@ class KotlinReferenceData(
|
|||||||
var endOffset: Int,
|
var endOffset: Int,
|
||||||
val fqName: String,
|
val fqName: String,
|
||||||
val isQualifiable: Boolean,
|
val isQualifiable: Boolean,
|
||||||
val kind: KotlinReferenceData.Kind
|
val kind: Kind
|
||||||
) : Cloneable, Serializable {
|
) : Cloneable, Serializable {
|
||||||
|
|
||||||
enum class Kind {
|
enum class Kind {
|
||||||
@@ -87,8 +87,7 @@ class KotlinReferenceData(
|
|||||||
public override fun clone(): KotlinReferenceData {
|
public override fun clone(): KotlinReferenceData {
|
||||||
try {
|
try {
|
||||||
return super.clone() as KotlinReferenceData
|
return super.clone() as KotlinReferenceData
|
||||||
}
|
} catch (e: CloneNotSupportedException) {
|
||||||
catch (e: CloneNotSupportedException) {
|
|
||||||
throw RuntimeException()
|
throw RuntimeException()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -97,14 +96,14 @@ class KotlinReferenceData(
|
|||||||
val dataFlavor: DataFlavor? by lazy {
|
val dataFlavor: DataFlavor? by lazy {
|
||||||
try {
|
try {
|
||||||
val dataClass = KotlinReferenceData::class.java
|
val dataClass = KotlinReferenceData::class.java
|
||||||
DataFlavor(DataFlavor.javaJVMLocalObjectMimeType + ";class=" + dataClass.name,
|
DataFlavor(
|
||||||
|
DataFlavor.javaJVMLocalObjectMimeType + ";class=" + dataClass.name,
|
||||||
"KotlinReferenceData",
|
"KotlinReferenceData",
|
||||||
dataClass.classLoader)
|
dataClass.classLoader
|
||||||
}
|
)
|
||||||
catch (e: NoClassDefFoundError) {
|
} catch (e: NoClassDefFoundError) {
|
||||||
null
|
null
|
||||||
}
|
} catch (e: IllegalArgumentException) {
|
||||||
catch (e: IllegalArgumentException) {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.psi.*
|
|||||||
|
|
||||||
class KotlinSpellcheckingStrategy : SpellcheckingStrategy() {
|
class KotlinSpellcheckingStrategy : SpellcheckingStrategy() {
|
||||||
private val plainTextTokenizer = TokenizerBase<KtLiteralStringTemplateEntry>(PlainTextSplitter.getInstance())
|
private val plainTextTokenizer = TokenizerBase<KtLiteralStringTemplateEntry>(PlainTextSplitter.getInstance())
|
||||||
private val emptyTokenizer = SpellcheckingStrategy.EMPTY_TOKENIZER
|
private val emptyTokenizer = EMPTY_TOKENIZER
|
||||||
|
|
||||||
override fun getTokenizer(element: PsiElement?): Tokenizer<out PsiElement?> {
|
override fun getTokenizer(element: PsiElement?): Tokenizer<out PsiElement?> {
|
||||||
return when (element) {
|
return when (element) {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ class KotlinMigrationProjectComponent(val project: Project) {
|
|||||||
init {
|
init {
|
||||||
val connection = project.messageBus.connect()
|
val connection = project.messageBus.connect()
|
||||||
connection.subscribe(ProjectDataImportListener.TOPIC, ProjectDataImportListener {
|
connection.subscribe(ProjectDataImportListener.TOPIC, ProjectDataImportListener {
|
||||||
KotlinMigrationProjectComponent.getInstanceIfNotDisposed(project)?.onImportFinished()
|
getInstanceIfNotDisposed(project)?.onImportFinished()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,8 +165,7 @@ class KotlinMigrationProjectComponent(val project: Project) {
|
|||||||
|
|
||||||
val changedFiles = ChangeListManager.getInstance(project).affectedPaths
|
val changedFiles = ChangeListManager.getInstance(project).affectedPaths
|
||||||
for (changedFile in changedFiles) {
|
for (changedFile in changedFiles) {
|
||||||
val extension = changedFile.extension
|
when (changedFile.extension) {
|
||||||
when (extension) {
|
|
||||||
"gradle" -> return true
|
"gradle" -> return true
|
||||||
"properties" -> return true
|
"properties" -> return true
|
||||||
"kts" -> return true
|
"kts" -> return true
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.idea.editor
|
package org.jetbrains.kotlin.idea.editor
|
||||||
|
|
||||||
import com.intellij.codeInsight.CodeInsightSettings
|
import com.intellij.codeInsight.CodeInsightSettings
|
||||||
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate
|
|
||||||
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate.Result
|
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegate.Result
|
||||||
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter
|
import com.intellij.codeInsight.editorActions.enter.EnterHandlerDelegateAdapter
|
||||||
import com.intellij.injected.editor.EditorWindow
|
import com.intellij.injected.editor.EditorWindow
|
||||||
@@ -55,7 +54,7 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
|||||||
override fun preprocessEnter(
|
override fun preprocessEnter(
|
||||||
file: PsiFile, editor: Editor, caretOffset: Ref<Int>, caretAdvance: Ref<Int>, dataContext: DataContext,
|
file: PsiFile, editor: Editor, caretOffset: Ref<Int>, caretAdvance: Ref<Int>, dataContext: DataContext,
|
||||||
originalHandler: EditorActionHandler?
|
originalHandler: EditorActionHandler?
|
||||||
): EnterHandlerDelegate.Result {
|
): Result {
|
||||||
val offset = caretOffset.get().toInt()
|
val offset = caretOffset.get().toInt()
|
||||||
if (editor !is EditorWindow) {
|
if (editor !is EditorWindow) {
|
||||||
return preprocessEnter(file, editor, offset, originalHandler, dataContext)
|
return preprocessEnter(file, editor, offset, originalHandler, dataContext)
|
||||||
@@ -194,7 +193,7 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
|||||||
|
|
||||||
val marginCharToInsert = if (marginChar != null &&
|
val marginCharToInsert = if (marginChar != null &&
|
||||||
!prefixStripped.startsWith(marginChar) &&
|
!prefixStripped.startsWith(marginChar) &&
|
||||||
!nonBlankNotFirstLines.isEmpty() &&
|
nonBlankNotFirstLines.isNotEmpty() &&
|
||||||
nonBlankNotFirstLines.none { it.trimStart().startsWith(marginChar) }
|
nonBlankNotFirstLines.none { it.trimStart().startsWith(marginChar) }
|
||||||
) {
|
) {
|
||||||
|
|
||||||
@@ -242,11 +241,11 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
val DEFAULT_TRIM_MARGIN_CHAR = '|'
|
const val DEFAULT_TRIM_MARGIN_CHAR = '|'
|
||||||
val TRIM_INDENT_CALL = "trimIndent"
|
const val TRIM_INDENT_CALL = "trimIndent"
|
||||||
val TRIM_MARGIN_CALL = "trimMargin"
|
const val TRIM_MARGIN_CALL = "trimMargin"
|
||||||
|
|
||||||
val MULTILINE_QUOTE = "\"\"\""
|
const val MULTILINE_QUOTE = "\"\"\""
|
||||||
|
|
||||||
class MultilineSettings(project: Project) {
|
class MultilineSettings(project: Project) {
|
||||||
private val kotlinIndentOptions =
|
private val kotlinIndentOptions =
|
||||||
@@ -286,7 +285,7 @@ class KotlinMultilineStringEnterHandler : EnterHandlerDelegateAdapter() {
|
|||||||
else -> return null
|
else -> return null
|
||||||
}
|
}
|
||||||
|
|
||||||
return element.parents.firstIsInstanceOrNull<KtStringTemplateExpression>()
|
return element.parents.firstIsInstanceOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun inMultilineString(element: PsiElement?, offset: Int) =
|
fun inMultilineString(element: PsiElement?, offset: Int) =
|
||||||
|
|||||||
+2
-2
@@ -54,9 +54,9 @@ class KotlinCodeBlockSelectioner : ExtendWordSelectionHandlerBase() {
|
|||||||
val start = findBlockContentStart(block)
|
val start = findBlockContentStart(block)
|
||||||
val end = findBlockContentEnd(block)
|
val end = findBlockContentEnd(block)
|
||||||
if (end > start) {
|
if (end > start) {
|
||||||
result.addAll(ExtendWordSelectionHandlerBase.expandToWholeLine(editorText, TextRange(start, end)))
|
result.addAll(expandToWholeLine(editorText, TextRange(start, end)))
|
||||||
}
|
}
|
||||||
result.addAll(ExtendWordSelectionHandlerBase.expandToWholeLine(editorText, block.textRange!!))
|
result.addAll(expandToWholeLine(editorText, block.textRange!!))
|
||||||
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -26,6 +26,6 @@ class KotlinDocCommentSelectioner : ExtendWordSelectionHandlerBase() {
|
|||||||
override fun canSelect(e: PsiElement) = e is KDoc
|
override fun canSelect(e: PsiElement) = e is KDoc
|
||||||
|
|
||||||
override fun select(e: PsiElement, editorText: CharSequence, cursorOffset: Int, editor: Editor): List<TextRange>? {
|
override fun select(e: PsiElement, editorText: CharSequence, cursorOffset: Int, editor: Editor): List<TextRange>? {
|
||||||
return ExtendWordSelectionHandlerBase.expandToWholeLine(editorText, e.textRange)
|
return expandToWholeLine(editorText, e.textRange)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-10
@@ -18,8 +18,8 @@ import kotlin.reflect.KProperty
|
|||||||
class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvider() {
|
class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvider() {
|
||||||
override fun getLanguage() = KotlinLanguage.INSTANCE
|
override fun getLanguage() = KotlinLanguage.INSTANCE
|
||||||
|
|
||||||
override fun getCodeSample(settingsType: LanguageCodeStyleSettingsProvider.SettingsType): String = when (settingsType) {
|
override fun getCodeSample(settingsType: SettingsType): String = when (settingsType) {
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.WRAPPING_AND_BRACES_SETTINGS ->
|
SettingsType.WRAPPING_AND_BRACES_SETTINGS ->
|
||||||
"""
|
"""
|
||||||
@Deprecated("Foo") public class ThisIsASampleClass : Comparable<*>, Appendable {
|
@Deprecated("Foo") public class ThisIsASampleClass : Comparable<*>, Appendable {
|
||||||
val test =
|
val test =
|
||||||
@@ -71,7 +71,7 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
fun veryLongExpressionBodyMethod() = "abc"
|
fun veryLongExpressionBodyMethod() = "abc"
|
||||||
""".trimIndent()
|
""".trimIndent()
|
||||||
|
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.BLANK_LINES_SETTINGS ->
|
SettingsType.BLANK_LINES_SETTINGS ->
|
||||||
"""
|
"""
|
||||||
class Foo {
|
class Foo {
|
||||||
private var field1: Int = 1
|
private var field1: Int = 1
|
||||||
@@ -169,13 +169,13 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
|
|
||||||
override fun getLanguageName(): String = KotlinLanguage.NAME
|
override fun getLanguageName(): String = KotlinLanguage.NAME
|
||||||
|
|
||||||
override fun customizeSettings(consumer: CodeStyleSettingsCustomizable, settingsType: LanguageCodeStyleSettingsProvider.SettingsType) {
|
override fun customizeSettings(consumer: CodeStyleSettingsCustomizable, settingsType: SettingsType) {
|
||||||
fun showCustomOption(field: KProperty<*>, title: String, groupName: String? = null, vararg options: Any) {
|
fun showCustomOption(field: KProperty<*>, title: String, groupName: String? = null, vararg options: Any) {
|
||||||
consumer.showCustomOption(KotlinCodeStyleSettings::class.java, field.name, title, groupName, *options)
|
consumer.showCustomOption(KotlinCodeStyleSettings::class.java, field.name, title, groupName, *options)
|
||||||
}
|
}
|
||||||
|
|
||||||
when (settingsType) {
|
when (settingsType) {
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.SPACING_SETTINGS -> {
|
SettingsType.SPACING_SETTINGS -> {
|
||||||
consumer.showStandardOptions(
|
consumer.showStandardOptions(
|
||||||
"SPACE_AROUND_ASSIGNMENT_OPERATORS",
|
"SPACE_AROUND_ASSIGNMENT_OPERATORS",
|
||||||
"SPACE_AROUND_LOGICAL_OPERATORS",
|
"SPACE_AROUND_LOGICAL_OPERATORS",
|
||||||
@@ -190,7 +190,7 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
"SPACE_BEFORE_WHILE_PARENTHESES",
|
"SPACE_BEFORE_WHILE_PARENTHESES",
|
||||||
"SPACE_BEFORE_FOR_PARENTHESES",
|
"SPACE_BEFORE_FOR_PARENTHESES",
|
||||||
"SPACE_BEFORE_CATCH_PARENTHESES"
|
"SPACE_BEFORE_CATCH_PARENTHESES"
|
||||||
);
|
)
|
||||||
|
|
||||||
showCustomOption(
|
showCustomOption(
|
||||||
KotlinCodeStyleSettings::SPACE_AROUND_RANGE,
|
KotlinCodeStyleSettings::SPACE_AROUND_RANGE,
|
||||||
@@ -252,7 +252,7 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
CodeStyleSettingsCustomizable.SPACES_BEFORE_PARENTHESES
|
CodeStyleSettingsCustomizable.SPACES_BEFORE_PARENTHESES
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.WRAPPING_AND_BRACES_SETTINGS -> {
|
SettingsType.WRAPPING_AND_BRACES_SETTINGS -> {
|
||||||
consumer.showStandardOptions(
|
consumer.showStandardOptions(
|
||||||
// "ALIGN_MULTILINE_CHAINED_METHODS",
|
// "ALIGN_MULTILINE_CHAINED_METHODS",
|
||||||
"RIGHT_MARGIN",
|
"RIGHT_MARGIN",
|
||||||
@@ -364,7 +364,7 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
CodeStyleSettingsCustomizable.WRAPPING_IF_STATEMENT
|
CodeStyleSettingsCustomizable.WRAPPING_IF_STATEMENT
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.BLANK_LINES_SETTINGS -> {
|
SettingsType.BLANK_LINES_SETTINGS -> {
|
||||||
consumer.showStandardOptions(
|
consumer.showStandardOptions(
|
||||||
"KEEP_BLANK_LINES_IN_CODE",
|
"KEEP_BLANK_LINES_IN_CODE",
|
||||||
"KEEP_BLANK_LINES_IN_DECLARATIONS",
|
"KEEP_BLANK_LINES_IN_DECLARATIONS",
|
||||||
@@ -377,8 +377,8 @@ class KotlinLanguageCodeStyleSettingsProvider : LanguageCodeStyleSettingsProvide
|
|||||||
CodeStyleSettingsCustomizable.BLANK_LINES
|
CodeStyleSettingsCustomizable.BLANK_LINES
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
LanguageCodeStyleSettingsProvider.SettingsType.COMMENTER_SETTINGS -> {
|
SettingsType.COMMENTER_SETTINGS -> {
|
||||||
consumer.showAllStandardOptions();
|
consumer.showAllStandardOptions()
|
||||||
}
|
}
|
||||||
else -> consumer.showStandardOptions()
|
else -> consumer.showStandardOptions()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,8 +16,8 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.idea.goto
|
package org.jetbrains.kotlin.idea.goto
|
||||||
|
|
||||||
|
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
||||||
import com.intellij.ide.util.PlatformModuleRendererFactory
|
import com.intellij.ide.util.PlatformModuleRendererFactory
|
||||||
import com.intellij.ide.util.PsiElementListCellRenderer
|
|
||||||
import com.intellij.ide.util.gotoByName.GotoFileCellRenderer
|
import com.intellij.ide.util.gotoByName.GotoFileCellRenderer
|
||||||
import com.intellij.navigation.NavigationItem
|
import com.intellij.navigation.NavigationItem
|
||||||
import com.intellij.openapi.util.Iconable
|
import com.intellij.openapi.util.Iconable
|
||||||
@@ -30,7 +30,6 @@ import com.intellij.ui.ColoredListCellRenderer
|
|||||||
import com.intellij.ui.JBColor
|
import com.intellij.ui.JBColor
|
||||||
import com.intellij.ui.SimpleTextAttributes
|
import com.intellij.ui.SimpleTextAttributes
|
||||||
import com.intellij.util.ui.FilePathSplittingPolicy
|
import com.intellij.util.ui.FilePathSplittingPolicy
|
||||||
import com.intellij.ide.util.DefaultPsiElementCellRenderer
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.psi.KtNamedFunction
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
@@ -58,8 +57,8 @@ internal class KotlinSearchEverywherePsiRenderer(private val myList: JList<*>) :
|
|||||||
layout = object : BorderLayout() {
|
layout = object : BorderLayout() {
|
||||||
override fun layoutContainer(target: Container) {
|
override fun layoutContainer(target: Container) {
|
||||||
super.layoutContainer(target)
|
super.layoutContainer(target)
|
||||||
val right = getLayoutComponent(BorderLayout.EAST)
|
val right = getLayoutComponent(EAST)
|
||||||
val left = getLayoutComponent(BorderLayout.WEST)
|
val left = getLayoutComponent(WEST)
|
||||||
|
|
||||||
//IDEA-140824
|
//IDEA-140824
|
||||||
if (right != null && left != null && left.bounds.x + left.bounds.width > right.bounds.x) {
|
if (right != null && left != null && left.bounds.x + left.bounds.width > right.bounds.x) {
|
||||||
|
|||||||
+4
-4
@@ -49,11 +49,11 @@ class KotlinOverrideHierarchyBrowser(
|
|||||||
|
|
||||||
BaseOnThisMethodAction().registerCustomShortcutSet(actionManager.getAction(IdeActions.ACTION_METHOD_HIERARCHY).shortcutSet, tree)
|
BaseOnThisMethodAction().registerCustomShortcutSet(actionManager.getAction(IdeActions.ACTION_METHOD_HIERARCHY).shortcutSet, tree)
|
||||||
|
|
||||||
trees.put(MethodHierarchyBrowserBase.METHOD_TYPE, tree)
|
trees[METHOD_TYPE] = tree
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createLegendPanel(): JPanel? =
|
override fun createLegendPanel(): JPanel? =
|
||||||
MethodHierarchyBrowserBase.createStandardLegendPanel(
|
createStandardLegendPanel(
|
||||||
KotlinBundle.message("hierarchy.legend.member.is.defined.in.class"),
|
KotlinBundle.message("hierarchy.legend.member.is.defined.in.class"),
|
||||||
KotlinBundle.message("hierarchy.legend.member.defined.in.superclass"),
|
KotlinBundle.message("hierarchy.legend.member.defined.in.superclass"),
|
||||||
KotlinBundle.message("hierarchy.legend.member.should.be.defined")
|
KotlinBundle.message("hierarchy.legend.member.should.be.defined")
|
||||||
@@ -65,9 +65,9 @@ class KotlinOverrideHierarchyBrowser(
|
|||||||
psiElement.isOverrideHierarchyElement()
|
psiElement.isOverrideHierarchyElement()
|
||||||
|
|
||||||
override fun createHierarchyTreeStructure(typeName: String, psiElement: PsiElement): HierarchyTreeStructure? =
|
override fun createHierarchyTreeStructure(typeName: String, psiElement: PsiElement): HierarchyTreeStructure? =
|
||||||
if (typeName == MethodHierarchyBrowserBase.METHOD_TYPE) KotlinOverrideTreeStructure(myProject, psiElement as KtCallableDeclaration) else null
|
if (typeName == METHOD_TYPE) KotlinOverrideTreeStructure(myProject, psiElement as KtCallableDeclaration) else null
|
||||||
|
|
||||||
override fun getComparator() = JavaHierarchyUtil.getComparator(myProject)!!
|
override fun getComparator() = JavaHierarchyUtil.getComparator(myProject)
|
||||||
|
|
||||||
override fun getContentDisplayName(typeName: String, element: PsiElement): String? {
|
override fun getContentDisplayName(typeName: String, element: PsiElement): String? {
|
||||||
val targetElement = element.unwrapped
|
val targetElement = element.unwrapped
|
||||||
|
|||||||
+5
-4
@@ -28,8 +28,8 @@ import com.intellij.psi.PsiMember
|
|||||||
import com.intellij.ui.LayeredIcon
|
import com.intellij.ui.LayeredIcon
|
||||||
import com.intellij.ui.RowIcon
|
import com.intellij.ui.RowIcon
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor
|
||||||
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaMemberDescriptor
|
||||||
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
import org.jetbrains.kotlin.psi.KtNamedDeclaration
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
import org.jetbrains.kotlin.psi.psiUtil.createSmartPointer
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
@@ -79,7 +79,8 @@ class KotlinOverrideHierarchyNodeDescriptor (
|
|||||||
}
|
}
|
||||||
|
|
||||||
val isAbstractClass = classDescriptor.modality == Modality.ABSTRACT
|
val isAbstractClass = classDescriptor.modality == Modality.ABSTRACT
|
||||||
val hasBaseImplementation = DescriptorUtils.getAllOverriddenDeclarations(callableDescriptor).any { it.modality != Modality.ABSTRACT }
|
val hasBaseImplementation =
|
||||||
|
DescriptorUtils.getAllOverriddenDeclarations(callableDescriptor).any { it.modality != Modality.ABSTRACT }
|
||||||
return if (isAbstractClass || hasBaseImplementation) AllIcons.Hierarchy.MethodNotDefined else AllIcons.Hierarchy.ShouldDefineMethod
|
return if (isAbstractClass || hasBaseImplementation) AllIcons.Hierarchy.MethodNotDefined else AllIcons.Hierarchy.ShouldDefineMethod
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -115,7 +116,7 @@ class KotlinOverrideHierarchyNodeDescriptor (
|
|||||||
if (myIsBase) {
|
if (myIsBase) {
|
||||||
val icon = LayeredIcon(2)
|
val icon = LayeredIcon(2)
|
||||||
icon.setIcon(newIcon, 0)
|
icon.setIcon(newIcon, 0)
|
||||||
icon.setIcon(AllIcons.Hierarchy.Base, 1, -AllIcons.Hierarchy.Base.iconWidth / 2, 0)
|
icon.setIcon(AllIcons.Actions.Forward, 1, -AllIcons.Actions.Forward.iconWidth / 2, 0)
|
||||||
newIcon = icon
|
newIcon = icon
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +146,7 @@ class KotlinOverrideHierarchyNodeDescriptor (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
is PackageFragmentDescriptor -> {
|
is PackageFragmentDescriptor -> {
|
||||||
addText(" (${parentDescriptor.fqName.asString()})", HierarchyNodeDescriptor.getPackageNameAttributes())
|
addText(" (${parentDescriptor.fqName.asString()})", getPackageNameAttributes())
|
||||||
return@forEach
|
return@forEach
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ class KotlinRunLineMarkerContributor : RunLineMarkerContributor() {
|
|||||||
val platform = function.containingKtFile.module?.platform ?: return null
|
val platform = function.containingKtFile.module?.platform ?: return null
|
||||||
if (!platform.kind.tooling.acceptsAsEntryPoint(function)) return null
|
if (!platform.kind.tooling.acceptsAsEntryPoint(function)) return null
|
||||||
|
|
||||||
return RunLineMarkerContributor.Info(AllIcons.RunConfigurations.TestState.Run, null, ExecutorAction.getActions(0))
|
return Info(AllIcons.RunConfigurations.TestState.Run, null, ExecutorAction.getActions(0))
|
||||||
}
|
}
|
||||||
|
|
||||||
return null
|
return null
|
||||||
|
|||||||
+3
-4
@@ -40,8 +40,7 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
|||||||
fun getTestStateIcon(url: String, project: Project): Icon? {
|
fun getTestStateIcon(url: String, project: Project): Icon? {
|
||||||
val defaultIcon = AllIcons.RunConfigurations.TestState.Run
|
val defaultIcon = AllIcons.RunConfigurations.TestState.Run
|
||||||
val state = TestStateStorage.getInstance(project).getState(url) ?: return defaultIcon
|
val state = TestStateStorage.getInstance(project).getState(url) ?: return defaultIcon
|
||||||
val magnitude = TestIconMapper.getMagnitude(state.magnitude)
|
return when (TestIconMapper.getMagnitude(state.magnitude)) {
|
||||||
return when (magnitude) {
|
|
||||||
TestStateInfo.Magnitude.ERROR_INDEX,
|
TestStateInfo.Magnitude.ERROR_INDEX,
|
||||||
TestStateInfo.Magnitude.FAILED_INDEX -> AllIcons.RunConfigurations.TestState.Red2
|
TestStateInfo.Magnitude.FAILED_INDEX -> AllIcons.RunConfigurations.TestState.Red2
|
||||||
TestStateInfo.Magnitude.PASSED_INDEX,
|
TestStateInfo.Magnitude.PASSED_INDEX,
|
||||||
@@ -51,7 +50,7 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getInfo(element: PsiElement): RunLineMarkerContributor.Info? {
|
override fun getInfo(element: PsiElement): Info? {
|
||||||
val declaration = element.getStrictParentOfType<KtNamedDeclaration>() ?: return null
|
val declaration = element.getStrictParentOfType<KtNamedDeclaration>() ?: return null
|
||||||
if (declaration.nameIdentifier != element) return null
|
if (declaration.nameIdentifier != element) return null
|
||||||
|
|
||||||
@@ -64,6 +63,6 @@ class KotlinTestRunLineMarkerContributor : RunLineMarkerContributor() {
|
|||||||
|
|
||||||
val targetPlatform = declaration.module?.platform ?: return null
|
val targetPlatform = declaration.module?.platform ?: return null
|
||||||
val icon = targetPlatform.kind.tooling.getTestIcon(declaration, descriptor) ?: return null
|
val icon = targetPlatform.kind.tooling.getTestIcon(declaration, descriptor) ?: return null
|
||||||
return RunLineMarkerContributor.Info(icon, { "Run Test" }, ExecutorAction.getActions())
|
return Info(icon, { "Run Test" }, ExecutorAction.getActions())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+13
-10
@@ -26,15 +26,18 @@ class RecursivePropertyAccessorInspection : AbstractKotlinInspection() {
|
|||||||
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
override fun buildVisitor(holder: ProblemsHolder, isOnTheFly: Boolean, session: LocalInspectionToolSession): PsiElementVisitor {
|
||||||
return simpleNameExpressionVisitor { expression ->
|
return simpleNameExpressionVisitor { expression ->
|
||||||
if (isRecursivePropertyAccess(expression)) {
|
if (isRecursivePropertyAccess(expression)) {
|
||||||
holder.registerProblem(expression,
|
holder.registerProblem(
|
||||||
|
expression,
|
||||||
"Recursive property accessor",
|
"Recursive property accessor",
|
||||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
|
||||||
ReplaceWithFieldFix())
|
ReplaceWithFieldFix()
|
||||||
}
|
)
|
||||||
else if (isRecursiveSyntheticPropertyAccess(expression)) {
|
} else if (isRecursiveSyntheticPropertyAccess(expression)) {
|
||||||
holder.registerProblem(expression,
|
holder.registerProblem(
|
||||||
|
expression,
|
||||||
"Recursive synthetic property accessor",
|
"Recursive synthetic property accessor",
|
||||||
ProblemHighlightType.GENERIC_ERROR_OR_WARNING)
|
ProblemHighlightType.GENERIC_ERROR_OR_WARNING
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -64,8 +67,7 @@ class RecursivePropertyAccessorInspection : AbstractKotlinInspection() {
|
|||||||
return KtTokens.AUGMENTED_ASSIGNMENTS.contains(binaryExpr?.operationToken)
|
return KtTokens.AUGMENTED_ASSIGNMENTS.contains(binaryExpr?.operationToken)
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
} else /* isSetter */ {
|
||||||
else /* isSetter */ {
|
|
||||||
if (binaryExpr.isAssignmentTo(expression)) {
|
if (binaryExpr.isAssignmentTo(expression)) {
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
@@ -84,7 +86,7 @@ class RecursivePropertyAccessorInspection : AbstractKotlinInspection() {
|
|||||||
if (element.parent is KtCallableReferenceExpression) return false
|
if (element.parent is KtCallableReferenceExpression) return false
|
||||||
val bindingContext = element.analyze()
|
val bindingContext = element.analyze()
|
||||||
val target = bindingContext[REFERENCE_TARGET, element]
|
val target = bindingContext[REFERENCE_TARGET, element]
|
||||||
if (target != bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, propertyAccessor.property]) return false
|
if (target != bindingContext[DECLARATION_TO_DESCRIPTOR, propertyAccessor.property]) return false
|
||||||
(element.parent as? KtQualifiedExpression)?.let {
|
(element.parent as? KtQualifiedExpression)?.let {
|
||||||
if (it.receiverExpression.text != KtTokens.THIS_KEYWORD.value && !it.hasObjectReceiver(bindingContext)) return false
|
if (it.receiverExpression.text != KtTokens.THIS_KEYWORD.value && !it.hasObjectReceiver(bindingContext)) return false
|
||||||
}
|
}
|
||||||
@@ -104,7 +106,8 @@ class RecursivePropertyAccessorInspection : AbstractKotlinInspection() {
|
|||||||
val syntheticDescriptor = bindingContext[REFERENCE_TARGET, element] as? SyntheticJavaPropertyDescriptor ?: return false
|
val syntheticDescriptor = bindingContext[REFERENCE_TARGET, element] as? SyntheticJavaPropertyDescriptor ?: return false
|
||||||
val namedFunctionDescriptor = bindingContext[DECLARATION_TO_DESCRIPTOR, namedFunction]
|
val namedFunctionDescriptor = bindingContext[DECLARATION_TO_DESCRIPTOR, namedFunction]
|
||||||
if (namedFunctionDescriptor != syntheticDescriptor.getMethod &&
|
if (namedFunctionDescriptor != syntheticDescriptor.getMethod &&
|
||||||
namedFunctionDescriptor != syntheticDescriptor.setMethod) return false
|
namedFunctionDescriptor != syntheticDescriptor.setMethod
|
||||||
|
) return false
|
||||||
return isSameAccessor(element, isGetter)
|
return isSameAccessor(element, isGetter)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -88,7 +88,7 @@ class ReformatInspection : LocalInspectionTool() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun isEmptyLineReformat(whitespace: PsiWhiteSpace, change: FormattingChange): Boolean {
|
private fun isEmptyLineReformat(whitespace: PsiWhiteSpace, change: FormattingChange): Boolean {
|
||||||
if (change !is FormattingChange.ReplaceWhiteSpace) return false
|
if (change !is ReplaceWhiteSpace) return false
|
||||||
|
|
||||||
val beforeText = whitespace.text
|
val beforeText = whitespace.text
|
||||||
val afterText = change.whiteSpace
|
val afterText = change.whiteSpace
|
||||||
|
|||||||
+1
-1
@@ -55,7 +55,7 @@ class FoldInitializerAndIfToElvisIntention :
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun applyTo(element: KtIfExpression, editor: Editor?) {
|
override fun applyTo(element: KtIfExpression, editor: Editor?) {
|
||||||
val newElvis = FoldInitializerAndIfToElvisIntention.applyTo(element)
|
val newElvis = applyTo(element)
|
||||||
editor?.caretModel?.moveToOffset(newElvis.right!!.textOffset)
|
editor?.caretModel?.moveToOffset(newElvis.right!!.textOffset)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -29,16 +29,16 @@ import org.jetbrains.kotlin.kdoc.lexer.KDocTokens
|
|||||||
import org.jetbrains.kotlin.psi.KtFile
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class KDocTypedHandler : TypedHandlerDelegate() {
|
class KDocTypedHandler : TypedHandlerDelegate() {
|
||||||
override fun beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): TypedHandlerDelegate.Result {
|
override fun beforeCharTyped(c: Char, project: Project, editor: Editor, file: PsiFile, fileType: FileType): Result {
|
||||||
if (overwriteClosingBracket(c, editor, file)) {
|
if (overwriteClosingBracket(c, editor, file)) {
|
||||||
EditorModificationUtil.moveCaretRelatively(editor, 1)
|
EditorModificationUtil.moveCaretRelatively(editor, 1)
|
||||||
return TypedHandlerDelegate.Result.STOP
|
return Result.STOP
|
||||||
}
|
}
|
||||||
return TypedHandlerDelegate.Result.CONTINUE
|
return Result.CONTINUE
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun charTyped(c: Char, project: Project, editor: Editor, file: PsiFile): TypedHandlerDelegate.Result =
|
override fun charTyped(c: Char, project: Project, editor: Editor, file: PsiFile): Result =
|
||||||
if (handleBracketTyped(c, project, editor, file)) TypedHandlerDelegate.Result.STOP else TypedHandlerDelegate.Result.CONTINUE
|
if (handleBracketTyped(c, project, editor, file)) Result.STOP else Result.CONTINUE
|
||||||
|
|
||||||
private fun overwriteClosingBracket(c: Char, editor: Editor, file: PsiFile): Boolean {
|
private fun overwriteClosingBracket(c: Char, editor: Editor, file: PsiFile): Boolean {
|
||||||
if (c != ']' && c != ')') return false
|
if (c != ']' && c != ')') return false
|
||||||
|
|||||||
@@ -18,11 +18,11 @@ interface Template<in TOuter> {
|
|||||||
* A placeholder that is inserted inside [TOuter]
|
* A placeholder that is inserted inside [TOuter]
|
||||||
*/
|
*/
|
||||||
open class Placeholder<TOuter> {
|
open class Placeholder<TOuter> {
|
||||||
private var contentStack = mutableListOf<(TOuter.(Placeholder<TOuter>.Exec) -> Unit)>()
|
private var contentStack = mutableListOf<(TOuter.(Exec) -> Unit)>()
|
||||||
|
|
||||||
var meta: String = ""
|
var meta: String = ""
|
||||||
|
|
||||||
operator fun invoke(meta: String = "", content: TOuter.(Placeholder<TOuter>.Exec) -> Unit) {
|
operator fun invoke(meta: String = "", content: TOuter.(Exec) -> Unit) {
|
||||||
this.contentStack.add(content)
|
this.contentStack.add(content)
|
||||||
this.meta = meta
|
this.meta = meta
|
||||||
}
|
}
|
||||||
@@ -48,10 +48,10 @@ open class Placeholder<TOuter> {
|
|||||||
/**
|
/**
|
||||||
* Placeholder that can appear multiple times
|
* Placeholder that can appear multiple times
|
||||||
*/
|
*/
|
||||||
open class PlaceholderList<TOuter, TInner>() {
|
open class PlaceholderList<TOuter, TInner> {
|
||||||
private var items = ArrayList<PlaceholderItem<TInner>>()
|
private var items = ArrayList<PlaceholderItem<TInner>>()
|
||||||
operator fun invoke(meta: String = "", content: TInner.(Placeholder<TInner>.Exec) -> Unit = {}) {
|
operator fun invoke(meta: String = "", content: TInner.(Placeholder<TInner>.Exec) -> Unit = {}) {
|
||||||
val placeholder = PlaceholderItem<TInner>(items.size, items)
|
val placeholder = PlaceholderItem(items.size, items)
|
||||||
placeholder(meta, content)
|
placeholder(meta, content)
|
||||||
items.add(placeholder)
|
items.add(placeholder)
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ class PlaceholderItem<TOuter>(val index: Int, val collection: List<PlaceholderIt
|
|||||||
/**
|
/**
|
||||||
* Inserts every element of placeholder list
|
* Inserts every element of placeholder list
|
||||||
*/
|
*/
|
||||||
fun <TOuter, TInner> TOuter.each(items: PlaceholderList<TOuter, TInner>, itemTemplate: TOuter.(PlaceholderItem<TInner>) -> Unit): Unit {
|
fun <TOuter, TInner> TOuter.each(items: PlaceholderList<TOuter, TInner>, itemTemplate: TOuter.(PlaceholderItem<TInner>) -> Unit) {
|
||||||
items.apply(this, itemTemplate)
|
items.apply(this, itemTemplate)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -268,7 +268,7 @@ abstract class KotlinParameterInfoWithCallHandlerBase<TArgumentList : KtElement,
|
|||||||
|
|
||||||
|
|
||||||
val color = if (isResolvedToDescriptor(call, itemToShow, bindingContext))
|
val color = if (isResolvedToDescriptor(call, itemToShow, bindingContext))
|
||||||
KotlinParameterInfoWithCallHandlerBase.GREEN_BACKGROUND
|
GREEN_BACKGROUND
|
||||||
else
|
else
|
||||||
context.defaultParameterColor
|
context.defaultParameterColor
|
||||||
|
|
||||||
|
|||||||
+2
-3
@@ -118,7 +118,7 @@ enum class HintType(val desc: String, defaultEnabled: Boolean) {
|
|||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
fun resolve(elem: PsiElement): HintType? {
|
fun resolve(elem: PsiElement): HintType? {
|
||||||
val applicableTypes = HintType.values().filter { it.isApplicable(elem) }
|
val applicableTypes = values().filter { it.isApplicable(elem) }
|
||||||
return applicableTypes.firstOrNull()
|
return applicableTypes.firstOrNull()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,8 +153,7 @@ class KotlinInlayParameterHintsProvider : InlayParameterHintsProvider {
|
|||||||
)
|
)
|
||||||
|
|
||||||
override fun getHintInfo(element: PsiElement): HintInfo? {
|
override fun getHintInfo(element: PsiElement): HintInfo? {
|
||||||
val hintType = HintType.resolve(element) ?: return null
|
return when (val hintType = HintType.resolve(element) ?: return null) {
|
||||||
return when (hintType) {
|
|
||||||
HintType.PARAMETER_HINT -> {
|
HintType.PARAMETER_HINT -> {
|
||||||
val parent = (element as? KtValueArgumentList)?.parent
|
val parent = (element as? KtValueArgumentList)?.parent
|
||||||
(parent as? KtCallElement)?.let { getMethodInfo(it) }
|
(parent as? KtCallElement)?.let { getMethodInfo(it) }
|
||||||
|
|||||||
@@ -31,12 +31,12 @@ import org.jetbrains.kotlin.descriptors.*
|
|||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.core.TemplateKind
|
import org.jetbrains.kotlin.idea.core.TemplateKind
|
||||||
import org.jetbrains.kotlin.idea.core.getFunctionBodyTextFromTemplate
|
import org.jetbrains.kotlin.idea.core.getFunctionBodyTextFromTemplate
|
||||||
import org.jetbrains.kotlin.idea.core.implicitModality
|
import org.jetbrains.kotlin.idea.core.implicitModality
|
||||||
import org.jetbrains.kotlin.idea.imports.importableFqName
|
import org.jetbrains.kotlin.idea.imports.importableFqName
|
||||||
|
import org.jetbrains.kotlin.idea.util.IdeDescriptorRenderers
|
||||||
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
import org.jetbrains.kotlin.idea.util.application.executeWriteCommand
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -48,7 +48,7 @@ import org.jetbrains.kotlin.types.typeUtil.supertypes
|
|||||||
|
|
||||||
class AddFunctionToSupertypeFix private constructor(
|
class AddFunctionToSupertypeFix private constructor(
|
||||||
element: KtNamedFunction,
|
element: KtNamedFunction,
|
||||||
private val functions: List<AddFunctionToSupertypeFix.FunctionData>
|
private val functions: List<FunctionData>
|
||||||
) : KotlinQuickFixAction<KtNamedFunction>(element), LowPriorityAction {
|
) : KotlinQuickFixAction<KtNamedFunction>(element), LowPriorityAction {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
|
|||||||
@@ -33,7 +33,6 @@ import org.jetbrains.kotlin.idea.inspections.KotlinUniversalQuickFix
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
import org.jetbrains.kotlin.idea.refactoring.canRefactor
|
||||||
import org.jetbrains.kotlin.idea.util.runOnExpectAndAllActuals
|
import org.jetbrains.kotlin.idea.util.runOnExpectAndAllActuals
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
import org.jetbrains.kotlin.psi.psiUtil.containingClass
|
||||||
@@ -49,7 +48,7 @@ open class AddModifierFix(
|
|||||||
) : KotlinCrossLanguageQuickFixAction<KtModifierListOwner>(element), KotlinUniversalQuickFix {
|
) : KotlinCrossLanguageQuickFixAction<KtModifierListOwner>(element), KotlinUniversalQuickFix {
|
||||||
override fun getText(): String {
|
override fun getText(): String {
|
||||||
val element = element ?: return ""
|
val element = element ?: return ""
|
||||||
if (modifier in modalityModifiers || modifier in KtTokens.VISIBILITY_MODIFIERS || modifier == KtTokens.CONST_KEYWORD) {
|
if (modifier in modalityModifiers || modifier in VISIBILITY_MODIFIERS || modifier == CONST_KEYWORD) {
|
||||||
return "Make ${getElementName(element)} ${modifier.value}"
|
return "Make ${getElementName(element)} ${modifier.value}"
|
||||||
}
|
}
|
||||||
return "Add '${modifier.value}' modifier"
|
return "Add '${modifier.value}' modifier"
|
||||||
@@ -60,10 +59,10 @@ open class AddModifierFix(
|
|||||||
private fun invokeOnElement(element: KtModifierListOwner?) {
|
private fun invokeOnElement(element: KtModifierListOwner?) {
|
||||||
element?.addModifier(modifier)
|
element?.addModifier(modifier)
|
||||||
|
|
||||||
if (modifier == KtTokens.ABSTRACT_KEYWORD && (element is KtProperty || element is KtNamedFunction)) {
|
if (modifier == ABSTRACT_KEYWORD && (element is KtProperty || element is KtNamedFunction)) {
|
||||||
element.containingClass()?.run {
|
element.containingClass()?.run {
|
||||||
if (!hasModifier(KtTokens.ABSTRACT_KEYWORD) && !hasModifier(KtTokens.SEALED_KEYWORD)) {
|
if (!hasModifier(ABSTRACT_KEYWORD) && !hasModifier(SEALED_KEYWORD)) {
|
||||||
addModifier(KtTokens.ABSTRACT_KEYWORD)
|
addModifier(ABSTRACT_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -85,7 +84,7 @@ open class AddModifierFix(
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
private fun KtModifierKeywordToken.isMultiplatformPersistent(): Boolean =
|
private fun KtModifierKeywordToken.isMultiplatformPersistent(): Boolean =
|
||||||
this in KtTokens.MODALITY_MODIFIERS || this == KtTokens.INLINE_KEYWORD
|
this in MODALITY_MODIFIERS || this == INLINE_KEYWORD
|
||||||
|
|
||||||
private val modalityModifiers = setOf(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD)
|
private val modalityModifiers = setOf(ABSTRACT_KEYWORD, OPEN_KEYWORD, FINAL_KEYWORD)
|
||||||
|
|
||||||
@@ -133,7 +132,7 @@ open class AddModifierFix(
|
|||||||
}
|
}
|
||||||
if (modifier == ABSTRACT_KEYWORD
|
if (modifier == ABSTRACT_KEYWORD
|
||||||
&& modifierListOwner is KtClass
|
&& modifierListOwner is KtClass
|
||||||
&& modifierListOwner.hasModifier(KtTokens.INLINE_KEYWORD)
|
&& modifierListOwner.hasModifier(INLINE_KEYWORD)
|
||||||
) return null
|
) return null
|
||||||
}
|
}
|
||||||
INNER_KEYWORD -> {
|
INNER_KEYWORD -> {
|
||||||
@@ -158,7 +157,7 @@ open class AddModifierFix(
|
|||||||
val typeReference = diagnostic.psiElement as KtTypeReference
|
val typeReference = diagnostic.psiElement as KtTypeReference
|
||||||
val declaration = typeReference.classForRefactor() ?: return null
|
val declaration = typeReference.classForRefactor() ?: return null
|
||||||
if (declaration.isEnum() || declaration.isData()) return null
|
if (declaration.isEnum() || declaration.isData()) return null
|
||||||
return AddModifierFix(declaration, KtTokens.OPEN_KEYWORD)
|
return AddModifierFix(declaration, OPEN_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -173,7 +172,7 @@ open class AddModifierFix(
|
|||||||
if (TypeUtils.isNullableType(type)) return null
|
if (TypeUtils.isNullableType(type)) return null
|
||||||
if (KotlinBuiltIns.isPrimitiveType(type)) return null
|
if (KotlinBuiltIns.isPrimitiveType(type)) return null
|
||||||
|
|
||||||
return AddModifierFix(property, KtTokens.LATEINIT_KEYWORD)
|
return AddModifierFix(property, LATEINIT_KEYWORD)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
changeFunctionLiteralReturnTypeFix = if (element is KtFunctionLiteral) {
|
changeFunctionLiteralReturnTypeFix = if (element is KtFunctionLiteral) {
|
||||||
val functionLiteralExpression = PsiTreeUtil.getParentOfType(element, KtLambdaExpression::class.java) ?: error("FunctionLiteral outside any FunctionLiteralExpression: " + element.getElementTextWithContext())
|
val functionLiteralExpression = PsiTreeUtil.getParentOfType(element, KtLambdaExpression::class.java)
|
||||||
|
?: error("FunctionLiteral outside any FunctionLiteralExpression: " + element.getElementTextWithContext())
|
||||||
ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression, type)
|
ChangeFunctionLiteralReturnTypeFix(functionLiteralExpression, type)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,8 +80,7 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
return "property $fullName"
|
return "property $fullName"
|
||||||
}
|
}
|
||||||
return "function $fullName"
|
return "function $fullName"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,14 +146,12 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
|
|
||||||
if (changeFunctionLiteralReturnTypeFix != null) {
|
if (changeFunctionLiteralReturnTypeFix != null) {
|
||||||
changeFunctionLiteralReturnTypeFix.invoke(project, editor!!, file)
|
changeFunctionLiteralReturnTypeFix.invoke(project, editor!!, file)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!(isUnitType && element is KtFunction && element.hasBlockBody())) {
|
if (!(isUnitType && element is KtFunction && element.hasBlockBody())) {
|
||||||
var newTypeRef = KtPsiFactory(project).createType(typeSourceCode)
|
var newTypeRef = KtPsiFactory(project).createType(typeSourceCode)
|
||||||
newTypeRef = element.setTypeReference(newTypeRef)!!
|
newTypeRef = element.setTypeReference(newTypeRef)!!
|
||||||
ShortenReferences.DEFAULT.process(newTypeRef)
|
ShortenReferences.DEFAULT.process(newTypeRef)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
element.typeReference = null
|
element.typeReference = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -169,7 +166,7 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.candidateDescriptor) as? KtCallableDeclaration
|
DescriptorToSourceUtils.descriptorToDeclaration(resolvedCall.candidateDescriptor) as? KtCallableDeclaration
|
||||||
?: return null
|
?: return null
|
||||||
val expectedType = context[BindingContext.TYPE, entry.typeReference!!] ?: return null
|
val expectedType = context[BindingContext.TYPE, entry.typeReference!!] ?: return null
|
||||||
return ChangeCallableReturnTypeFix.ForCalled(componentFunction, expectedType)
|
return ForCalled(componentFunction, expectedType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -181,17 +178,18 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
val resolvedCall = context[BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, expression] ?: return null
|
val resolvedCall = context[BindingContext.LOOP_RANGE_HAS_NEXT_RESOLVED_CALL, expression] ?: return null
|
||||||
val hasNextDescriptor = resolvedCall.candidateDescriptor
|
val hasNextDescriptor = resolvedCall.candidateDescriptor
|
||||||
val hasNextFunction = DescriptorToSourceUtils.descriptorToDeclaration(hasNextDescriptor) as KtFunction? ?: return null
|
val hasNextFunction = DescriptorToSourceUtils.descriptorToDeclaration(hasNextDescriptor) as KtFunction? ?: return null
|
||||||
return ChangeCallableReturnTypeFix.ForCalled(hasNextFunction, hasNextDescriptor.builtIns.booleanType)
|
return ForCalled(hasNextFunction, hasNextDescriptor.builtIns.booleanType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object CompareToTypeMismatchFactory : KotlinSingleIntentionActionFactory() {
|
object CompareToTypeMismatchFactory : KotlinSingleIntentionActionFactory() {
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val expression = QuickFixUtil.getParentElementOfType(diagnostic, KtBinaryExpression::class.java) ?: error("COMPARE_TO_TYPE_MISMATCH reported on element that is not within any expression")
|
val expression = QuickFixUtil.getParentElementOfType(diagnostic, KtBinaryExpression::class.java)
|
||||||
|
?: error("COMPARE_TO_TYPE_MISMATCH reported on element that is not within any expression")
|
||||||
val resolvedCall = expression.resolveToCall() ?: return null
|
val resolvedCall = expression.resolveToCall() ?: return null
|
||||||
val compareToDescriptor = resolvedCall.candidateDescriptor
|
val compareToDescriptor = resolvedCall.candidateDescriptor
|
||||||
val compareTo = DescriptorToSourceUtils.descriptorToDeclaration(compareToDescriptor) as? KtFunction ?: return null
|
val compareTo = DescriptorToSourceUtils.descriptorToDeclaration(compareToDescriptor) as? KtFunction ?: return null
|
||||||
return ChangeCallableReturnTypeFix.ForCalled(compareTo, compareToDescriptor.builtIns.intType)
|
return ForCalled(compareTo, compareToDescriptor.builtIns.intType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,7 +203,7 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
|
|
||||||
val matchingReturnType = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(descriptor)
|
val matchingReturnType = QuickFixUtil.findLowerBoundOfOverriddenCallablesReturnTypes(descriptor)
|
||||||
if (matchingReturnType != null) {
|
if (matchingReturnType != null) {
|
||||||
actions.add(ChangeCallableReturnTypeFix.OnType(function, matchingReturnType))
|
actions.add(OnType(function, matchingReturnType))
|
||||||
}
|
}
|
||||||
|
|
||||||
val functionType = descriptor.returnType ?: return actions
|
val functionType = descriptor.returnType ?: return actions
|
||||||
@@ -221,7 +219,7 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
if (overriddenMismatchingFunctions.size == 1) {
|
if (overriddenMismatchingFunctions.size == 1) {
|
||||||
val overriddenFunction = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingFunctions[0])
|
val overriddenFunction = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingFunctions[0])
|
||||||
if (overriddenFunction is KtFunction) {
|
if (overriddenFunction is KtFunction) {
|
||||||
actions.add(ChangeCallableReturnTypeFix.ForOverridden(overriddenFunction, functionType))
|
actions.add(ForOverridden(overriddenFunction, functionType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,14 +230,14 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
object ChangingReturnTypeToUnitFactory : KotlinSingleIntentionActionFactory() {
|
object ChangingReturnTypeToUnitFactory : KotlinSingleIntentionActionFactory() {
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val function = QuickFixUtil.getParentElementOfType(diagnostic, KtFunction::class.java) ?: return null
|
val function = QuickFixUtil.getParentElementOfType(diagnostic, KtFunction::class.java) ?: return null
|
||||||
return ChangeCallableReturnTypeFix.ForEnclosing(function, function.builtIns.unitType)
|
return ForEnclosing(function, function.builtIns.unitType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
object ChangingReturnTypeToNothingFactory : KotlinSingleIntentionActionFactory() {
|
object ChangingReturnTypeToNothingFactory : KotlinSingleIntentionActionFactory() {
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val function = QuickFixUtil.getParentElementOfType(diagnostic, KtFunction::class.java) ?: return null
|
val function = QuickFixUtil.getParentElementOfType(diagnostic, KtFunction::class.java) ?: return null
|
||||||
return ChangeCallableReturnTypeFix.ForEnclosing(function, function.builtIns.nothingType)
|
return ForEnclosing(function, function.builtIns.nothingType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -247,7 +245,8 @@ abstract class ChangeCallableReturnTypeFix(
|
|||||||
fun getDestructuringDeclarationEntryThatTypeMismatchComponentFunction(diagnostic: Diagnostic): KtDestructuringDeclarationEntry {
|
fun getDestructuringDeclarationEntryThatTypeMismatchComponentFunction(diagnostic: Diagnostic): KtDestructuringDeclarationEntry {
|
||||||
val componentName = COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.cast(diagnostic).a
|
val componentName = COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH.cast(diagnostic).a
|
||||||
val componentIndex = DataClassDescriptorResolver.getComponentIndex(componentName.asString())
|
val componentIndex = DataClassDescriptorResolver.getComponentIndex(componentName.asString())
|
||||||
val multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, KtDestructuringDeclaration::class.java) ?: error("COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH reported on expression that is not within any multi declaration")
|
val multiDeclaration = QuickFixUtil.getParentElementOfType(diagnostic, KtDestructuringDeclaration::class.java)
|
||||||
|
?: error("COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH reported on expression that is not within any multi declaration")
|
||||||
return multiDeclaration.entries[componentIndex - 1]
|
return multiDeclaration.entries[componentIndex - 1]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,8 +51,7 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
|||||||
val container = element.unsafeResolveToDescriptor().containingDeclaration as? ClassDescriptor
|
val container = element.unsafeResolveToDescriptor().containingDeclaration as? ClassDescriptor
|
||||||
val containerName = container?.name?.takeUnless { it.isSpecial }?.asString()
|
val containerName = container?.name?.takeUnless { it.isSpecial }?.asString()
|
||||||
if (containerName != null) "'$containerName.$name'" else "'$name'"
|
if (containerName != null) "'$containerName.$name'" else "'$name'"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,8 +62,7 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
|||||||
val variablePresentation = variablePresentation()
|
val variablePresentation = variablePresentation()
|
||||||
return if (variablePresentation != null) {
|
return if (variablePresentation != null) {
|
||||||
"Change type of $variablePresentation to '$typePresentation'"
|
"Change type of $variablePresentation to '$typePresentation'"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
"Change type to '$typePresentation'"
|
"Change type to '$typePresentation'"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -80,11 +78,9 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getFamilyName()
|
override fun getFamilyName() = KotlinBundle.message("change.type.family")
|
||||||
= KotlinBundle.message("change.type.family")
|
|
||||||
|
|
||||||
override fun isAvailable(project: Project, editor: Editor?, file: KtFile)
|
override fun isAvailable(project: Project, editor: Editor?, file: KtFile) = !typeContainsError
|
||||||
= !typeContainsError
|
|
||||||
|
|
||||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||||
val element = element ?: return
|
val element = element ?: return
|
||||||
@@ -141,25 +137,29 @@ open class ChangeVariableTypeFix(element: KtVariableDeclaration, type: KotlinTyp
|
|||||||
if (overriddenPropertyType != null) {
|
if (overriddenPropertyType != null) {
|
||||||
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(propertyType, overriddenPropertyType)) {
|
if (!KotlinTypeChecker.DEFAULT.isSubtypeOf(propertyType, overriddenPropertyType)) {
|
||||||
overriddenMismatchingProperties.add(overriddenProperty)
|
overriddenMismatchingProperties.add(overriddenProperty)
|
||||||
}
|
} else if (overriddenProperty.isVar && !KotlinTypeChecker.DEFAULT.equalTypes(
|
||||||
else if (overriddenProperty.isVar && !KotlinTypeChecker.DEFAULT.equalTypes(overriddenPropertyType, propertyType)) {
|
overriddenPropertyType,
|
||||||
|
propertyType
|
||||||
|
)
|
||||||
|
) {
|
||||||
canChangeOverriddenPropertyType = false
|
canChangeOverriddenPropertyType = false
|
||||||
}
|
}
|
||||||
if (overriddenProperty.isVar && lowerBoundOfOverriddenPropertiesTypes != null &&
|
if (overriddenProperty.isVar && lowerBoundOfOverriddenPropertiesTypes != null &&
|
||||||
!KotlinTypeChecker.DEFAULT.equalTypes(lowerBoundOfOverriddenPropertiesTypes, overriddenPropertyType)) {
|
!KotlinTypeChecker.DEFAULT.equalTypes(lowerBoundOfOverriddenPropertiesTypes, overriddenPropertyType)
|
||||||
|
) {
|
||||||
lowerBoundOfOverriddenPropertiesTypes = null
|
lowerBoundOfOverriddenPropertiesTypes = null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (lowerBoundOfOverriddenPropertiesTypes != null) {
|
if (lowerBoundOfOverriddenPropertiesTypes != null) {
|
||||||
actions.add(ChangeVariableTypeFix.OnType(property, lowerBoundOfOverriddenPropertiesTypes))
|
actions.add(OnType(property, lowerBoundOfOverriddenPropertiesTypes))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (overriddenMismatchingProperties.size == 1 && canChangeOverriddenPropertyType) {
|
if (overriddenMismatchingProperties.size == 1 && canChangeOverriddenPropertyType) {
|
||||||
val overriddenProperty = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingProperties.single())
|
val overriddenProperty = DescriptorToSourceUtils.descriptorToDeclaration(overriddenMismatchingProperties.single())
|
||||||
if (overriddenProperty is KtProperty) {
|
if (overriddenProperty is KtProperty) {
|
||||||
actions.add(ChangeVariableTypeFix.ForOverridden(overriddenProperty, propertyType))
|
actions.add(ForOverridden(overriddenProperty, propertyType))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,9 +17,12 @@
|
|||||||
package org.jetbrains.kotlin.idea.quickfix
|
package org.jetbrains.kotlin.idea.quickfix
|
||||||
|
|
||||||
import com.intellij.codeInsight.intention.IntentionAction
|
import com.intellij.codeInsight.intention.IntentionAction
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithVisibility
|
||||||
|
import org.jetbrains.kotlin.descriptors.DescriptorWithRelation
|
||||||
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility
|
||||||
import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness.LESS
|
import org.jetbrains.kotlin.descriptors.EffectiveVisibility.Permissiveness.LESS
|
||||||
import org.jetbrains.kotlin.descriptors.Visibilities.*
|
import org.jetbrains.kotlin.descriptors.Visibilities.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||||
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
import org.jetbrains.kotlin.diagnostics.DiagnosticFactory3
|
||||||
import org.jetbrains.kotlin.idea.core.toDescriptor
|
import org.jetbrains.kotlin.idea.core.toDescriptor
|
||||||
@@ -67,15 +70,19 @@ object ChangeVisibilityOnExposureFactory : KotlinIntentionActionsFactory() {
|
|||||||
val protectedAllowed = exposedDeclaration.parent == userDeclaration?.parent
|
val protectedAllowed = exposedDeclaration.parent == userDeclaration?.parent
|
||||||
if (userDeclaration != null) {
|
if (userDeclaration != null) {
|
||||||
val userDescriptor = userDeclaration.toDescriptor() as? DeclarationDescriptorWithVisibility
|
val userDescriptor = userDeclaration.toDescriptor() as? DeclarationDescriptorWithVisibility
|
||||||
if (userDescriptor != null && Visibilities.isVisibleIgnoringReceiver(exposedDescriptor, userDescriptor)) {
|
if (userDescriptor != null && isVisibleIgnoringReceiver(exposedDescriptor, userDescriptor)) {
|
||||||
addFixToTargetVisibility(userDeclaration, userDescriptor,
|
addFixToTargetVisibility(
|
||||||
|
userDeclaration, userDescriptor,
|
||||||
targetUserVisibility, PRIVATE,
|
targetUserVisibility, PRIVATE,
|
||||||
protectedAllowed, result)
|
protectedAllowed, result
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
addFixToTargetVisibility(exposedDeclaration, exposedDescriptor,
|
addFixToTargetVisibility(
|
||||||
|
exposedDeclaration, exposedDescriptor,
|
||||||
targetExposedVisibility, PUBLIC,
|
targetExposedVisibility, PUBLIC,
|
||||||
protectedAllowed, result)
|
protectedAllowed, result
|
||||||
|
)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -96,13 +96,12 @@ sealed class CreateLabelFix(
|
|||||||
|
|
||||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||||
val labelReferenceExpression = diagnostic.psiElement as? KtLabelReferenceExpression ?: return null
|
val labelReferenceExpression = diagnostic.psiElement as? KtLabelReferenceExpression ?: return null
|
||||||
val parentExpression = (labelReferenceExpression.parent as? KtContainerNode)?.parent
|
return when ((labelReferenceExpression.parent as? KtContainerNode)?.parent) {
|
||||||
return when (parentExpression) {
|
|
||||||
is KtBreakExpression, is KtContinueExpression -> {
|
is KtBreakExpression, is KtContinueExpression -> {
|
||||||
if (labelReferenceExpression.getContainingLoops().any()) CreateLabelFix.ForLoop(labelReferenceExpression) else null
|
if (labelReferenceExpression.getContainingLoops().any()) ForLoop(labelReferenceExpression) else null
|
||||||
}
|
}
|
||||||
is KtReturnExpression -> {
|
is KtReturnExpression -> {
|
||||||
if (labelReferenceExpression.getContainingLambdas().any()) CreateLabelFix.ForLambda(labelReferenceExpression) else null
|
if (labelReferenceExpression.getContainingLambdas().any()) ForLambda(labelReferenceExpression) else null
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -168,7 +168,7 @@ class QuickFixFactoryForTypeMismatchError : KotlinIntentionActionsFactory() {
|
|||||||
actions.add(CastExpressionFix(diagnosticElement.getTopMostQualifiedForSelectorIfAny(), expectedType))
|
actions.add(CastExpressionFix(diagnosticElement.getTopMostQualifiedForSelectorIfAny(), expectedType))
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!expectedType.isMarkedNullable && org.jetbrains.kotlin.types.TypeUtils.isNullableType(expressionType)) {
|
if (!expectedType.isMarkedNullable && TypeUtils.isNullableType(expressionType)) {
|
||||||
val nullableExpected = expectedType.makeNullable()
|
val nullableExpected = expectedType.makeNullable()
|
||||||
if (expressionType.isSubtypeOf(nullableExpected)) {
|
if (expressionType.isSubtypeOf(nullableExpected)) {
|
||||||
actions.add(AddExclExclCallFix(diagnosticElement.getTopMostQualifiedForSelectorIfAny()))
|
actions.add(AddExclExclCallFix(diagnosticElement.getTopMostQualifiedForSelectorIfAny()))
|
||||||
|
|||||||
@@ -21,7 +21,10 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticFactory
|
|||||||
import org.jetbrains.kotlin.diagnostics.Errors.*
|
import org.jetbrains.kotlin.diagnostics.Errors.*
|
||||||
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementAsConstructorParameter
|
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementAsConstructorParameter
|
||||||
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
|
import org.jetbrains.kotlin.idea.core.overrideImplement.ImplementMembersHandler
|
||||||
import org.jetbrains.kotlin.idea.inspections.*
|
import org.jetbrains.kotlin.idea.inspections.AddModifierFixFactory
|
||||||
|
import org.jetbrains.kotlin.idea.inspections.InfixCallFixActionFactory
|
||||||
|
import org.jetbrains.kotlin.idea.inspections.PlatformUnresolvedProvider
|
||||||
|
import org.jetbrains.kotlin.idea.inspections.RemoveAnnotationFix
|
||||||
import org.jetbrains.kotlin.idea.intentions.AbstractAddAccessorsIntention
|
import org.jetbrains.kotlin.idea.intentions.AbstractAddAccessorsIntention
|
||||||
import org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction
|
import org.jetbrains.kotlin.idea.intentions.AddValVarToConstructorParameterAction
|
||||||
import org.jetbrains.kotlin.idea.intentions.ConvertPropertyInitializerToGetterIntention
|
import org.jetbrains.kotlin.idea.intentions.ConvertPropertyInitializerToGetterIntention
|
||||||
@@ -46,7 +49,6 @@ import org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageFix
|
|||||||
import org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageInWholeProjectFix
|
import org.jetbrains.kotlin.idea.quickfix.replaceWith.DeprecatedSymbolUsageInWholeProjectFix
|
||||||
import org.jetbrains.kotlin.idea.quickfix.replaceWith.ReplaceProtectedToPublishedApiCallFix
|
import org.jetbrains.kotlin.idea.quickfix.replaceWith.ReplaceProtectedToPublishedApiCallFix
|
||||||
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
import org.jetbrains.kotlin.js.resolve.diagnostics.ErrorsJs
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.psi.KtClass
|
import org.jetbrains.kotlin.psi.KtClass
|
||||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||||
@@ -455,10 +457,10 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
|
|
||||||
NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.registerFactory(ConstFixFactory)
|
NON_CONST_VAL_USED_IN_CONSTANT_EXPRESSION.registerFactory(ConstFixFactory)
|
||||||
|
|
||||||
OPERATOR_MODIFIER_REQUIRED.registerFactory(AddModifierFixFactory(KtTokens.OPERATOR_KEYWORD))
|
OPERATOR_MODIFIER_REQUIRED.registerFactory(AddModifierFixFactory(OPERATOR_KEYWORD))
|
||||||
OPERATOR_MODIFIER_REQUIRED.registerFactory(ImportForMissingOperatorFactory)
|
OPERATOR_MODIFIER_REQUIRED.registerFactory(ImportForMissingOperatorFactory)
|
||||||
|
|
||||||
INFIX_MODIFIER_REQUIRED.registerFactory(AddModifierFixFactory(KtTokens.INFIX_KEYWORD))
|
INFIX_MODIFIER_REQUIRED.registerFactory(AddModifierFixFactory(INFIX_KEYWORD))
|
||||||
INFIX_MODIFIER_REQUIRED.registerFactory(InfixCallFixActionFactory)
|
INFIX_MODIFIER_REQUIRED.registerFactory(InfixCallFixActionFactory)
|
||||||
|
|
||||||
UNDERSCORE_IS_RESERVED.registerFactory(RenameUnderscoreFix)
|
UNDERSCORE_IS_RESERVED.registerFactory(RenameUnderscoreFix)
|
||||||
@@ -530,7 +532,7 @@ class QuickFixRegistrar : QuickFixContributor {
|
|||||||
NO_ACTUAL_FOR_EXPECT.registerFactory(CreateActualFix)
|
NO_ACTUAL_FOR_EXPECT.registerFactory(CreateActualFix)
|
||||||
NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS.registerFactory(AddActualFix)
|
NO_ACTUAL_CLASS_MEMBER_FOR_EXPECTED_CLASS.registerFactory(AddActualFix)
|
||||||
|
|
||||||
ACTUAL_MISSING.registerFactory(AddModifierFix.createFactory(KtTokens.ACTUAL_KEYWORD))
|
ACTUAL_MISSING.registerFactory(AddModifierFix.createFactory(ACTUAL_KEYWORD))
|
||||||
|
|
||||||
CAST_NEVER_SUCCEEDS.registerFactory(ReplacePrimitiveCastWithNumberConversionFix)
|
CAST_NEVER_SUCCEEDS.registerFactory(ReplacePrimitiveCastWithNumberConversionFix)
|
||||||
|
|
||||||
|
|||||||
@@ -26,8 +26,10 @@ import org.jetbrains.kotlin.psi.KtProperty
|
|||||||
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||||
|
|
||||||
class RemoveNullableFix(element: KtNullableType,
|
class RemoveNullableFix(
|
||||||
private val typeOfError: RemoveNullableFix.NullableKind) : KotlinQuickFixAction<KtNullableType>(element) {
|
element: KtNullableType,
|
||||||
|
private val typeOfError: NullableKind
|
||||||
|
) : KotlinQuickFixAction<KtNullableType>(element) {
|
||||||
enum class NullableKind(val message: String) {
|
enum class NullableKind(val message: String) {
|
||||||
REDUNDANT("Remove redundant '?'"),
|
REDUNDANT("Remove redundant '?'"),
|
||||||
SUPERTYPE("Remove '?'"),
|
SUPERTYPE("Remove '?'"),
|
||||||
|
|||||||
+1
-1
@@ -244,7 +244,7 @@ sealed class CreateCallableFromCallActionFactory<E : KtExpression>(
|
|||||||
receiverType: TypeInfo,
|
receiverType: TypeInfo,
|
||||||
possibleContainers: List<KtElement>
|
possibleContainers: List<KtElement>
|
||||||
) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let {
|
) = super.doCreateCallableInfo(expression, analysisResult, name, receiverType, possibleContainers)?.let {
|
||||||
ByImplicitExtensionReceiver.getCallableWithReceiverInsideExtension(
|
getCallableWithReceiverInsideExtension(
|
||||||
it,
|
it,
|
||||||
expression,
|
expression,
|
||||||
analysisResult.bindingContext,
|
analysisResult.bindingContext,
|
||||||
|
|||||||
+3
-3
@@ -70,7 +70,7 @@ val ClassKind.actionPriority: IntentionActionPriority
|
|||||||
get() = if (this == ANNOTATION_CLASS) IntentionActionPriority.LOW else IntentionActionPriority.NORMAL
|
get() = if (this == ANNOTATION_CLASS) IntentionActionPriority.LOW else IntentionActionPriority.NORMAL
|
||||||
|
|
||||||
data class ClassInfo(
|
data class ClassInfo(
|
||||||
val kind: ClassKind = ClassKind.DEFAULT,
|
val kind: ClassKind = DEFAULT,
|
||||||
val name: String,
|
val name: String,
|
||||||
private val targetParents: List<PsiElement>,
|
private val targetParents: List<PsiElement>,
|
||||||
val expectedTypeInfo: TypeInfo,
|
val expectedTypeInfo: TypeInfo,
|
||||||
@@ -81,7 +81,7 @@ data class ClassInfo(
|
|||||||
) {
|
) {
|
||||||
val applicableParents by lazy {
|
val applicableParents by lazy {
|
||||||
targetParents.filter {
|
targetParents.filter {
|
||||||
if (kind == ClassKind.OBJECT && it is KtClass && (it.isInner() || it.isLocal)) return@filter false
|
if (kind == OBJECT && it is KtClass && (it.isInner() || it.isLocal)) return@filter false
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -124,7 +124,7 @@ open class CreateClassFromUsageFix<E : KtElement> protected constructor(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (classInfo.kind != ClassKind.ENUM_ENTRY && parents.find { it is PsiPackage } == null) {
|
if (classInfo.kind != ENUM_ENTRY && parents.find { it is PsiPackage } == null) {
|
||||||
parents += SeparateFileWrapper(PsiManager.getInstance(project))
|
parents += SeparateFileWrapper(PsiManager.getInstance(project))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.idea.quickfix.crossLanguage
|
|||||||
import com.intellij.codeInsight.daemon.QuickFixBundle
|
import com.intellij.codeInsight.daemon.QuickFixBundle
|
||||||
import com.intellij.lang.jvm.actions.ChangeParametersRequest
|
import com.intellij.lang.jvm.actions.ChangeParametersRequest
|
||||||
import com.intellij.lang.jvm.actions.ExpectedParameter
|
import com.intellij.lang.jvm.actions.ExpectedParameter
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.editor.Editor
|
import com.intellij.openapi.editor.Editor
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.text.StringUtil
|
import com.intellij.openapi.util.text.StringUtil
|
||||||
@@ -26,7 +25,10 @@ import org.jetbrains.kotlin.load.java.NOT_NULL_ANNOTATIONS
|
|||||||
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
|
import org.jetbrains.kotlin.load.java.NULLABLE_ANNOTATIONS
|
||||||
import org.jetbrains.kotlin.name.FqName
|
import org.jetbrains.kotlin.name.FqName
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||||
|
import org.jetbrains.kotlin.psi.KtParameterList
|
||||||
|
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||||
import org.jetbrains.kotlin.types.ErrorUtils
|
import org.jetbrains.kotlin.types.ErrorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|||||||
@@ -35,7 +35,10 @@ import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
|||||||
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
import org.jetbrains.kotlin.idea.codeInsight.DescriptorToSourceUtilsIde
|
||||||
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
|
import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations
|
||||||
import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
|
import org.jetbrains.kotlin.idea.core.getDirectlyOverriddenDeclarations
|
||||||
import org.jetbrains.kotlin.idea.util.*
|
import org.jetbrains.kotlin.idea.util.actualsForExpected
|
||||||
|
import org.jetbrains.kotlin.idea.util.getResolutionScope
|
||||||
|
import org.jetbrains.kotlin.idea.util.isExpectDeclaration
|
||||||
|
import org.jetbrains.kotlin.idea.util.liftToExpected
|
||||||
import org.jetbrains.kotlin.psi.KtBlockExpression
|
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||||
import org.jetbrains.kotlin.psi.KtDeclaration
|
import org.jetbrains.kotlin.psi.KtDeclaration
|
||||||
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
import org.jetbrains.kotlin.psi.KtDeclarationWithBody
|
||||||
@@ -50,13 +53,14 @@ import java.util.*
|
|||||||
abstract class CallableRefactoring<out T : CallableDescriptor>(
|
abstract class CallableRefactoring<out T : CallableDescriptor>(
|
||||||
val project: Project,
|
val project: Project,
|
||||||
callableDescriptor: T,
|
callableDescriptor: T,
|
||||||
val commandName: String) {
|
val commandName: String
|
||||||
|
) {
|
||||||
private val LOG = Logger.getInstance(CallableRefactoring::class.java)
|
private val LOG = Logger.getInstance(CallableRefactoring::class.java)
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
val callableDescriptor = callableDescriptor.liftToExpected() as? T ?: callableDescriptor
|
val callableDescriptor = callableDescriptor.liftToExpected() as? T ?: callableDescriptor
|
||||||
|
|
||||||
private val kind = (callableDescriptor as? CallableMemberDescriptor)?.kind ?: CallableMemberDescriptor.Kind.DECLARATION
|
private val kind = (callableDescriptor as? CallableMemberDescriptor)?.kind ?: DECLARATION
|
||||||
|
|
||||||
protected open fun forcePerformForSelectedFunctionOnly(): Boolean {
|
protected open fun forcePerformForSelectedFunctionOnly(): Boolean {
|
||||||
return false
|
return false
|
||||||
@@ -76,16 +80,20 @@ abstract class CallableRefactoring<out T: CallableDescriptor>(
|
|||||||
}.map { it.liftToExpected() as? CallableDescriptor ?: it }
|
}.map { it.liftToExpected() as? CallableDescriptor ?: it }
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun showSuperFunctionWarningDialog(superCallables: Collection<CallableDescriptor>,
|
private fun showSuperFunctionWarningDialog(
|
||||||
|
superCallables: Collection<CallableDescriptor>,
|
||||||
callableFromEditor: CallableDescriptor,
|
callableFromEditor: CallableDescriptor,
|
||||||
options: List<String>): Int {
|
options: List<String>
|
||||||
|
): Int {
|
||||||
val superString = superCallables.joinToString(prefix = "\n ", separator = ",\n ", postfix = ".\n\n") {
|
val superString = superCallables.joinToString(prefix = "\n ", separator = ",\n ", postfix = ".\n\n") {
|
||||||
it.containingDeclaration.name.asString()
|
it.containingDeclaration.name.asString()
|
||||||
}
|
}
|
||||||
val message = KotlinBundle.message("x.overrides.y.in.class.list",
|
val message = KotlinBundle.message(
|
||||||
|
"x.overrides.y.in.class.list",
|
||||||
DescriptorRenderer.COMPACT.render(callableFromEditor),
|
DescriptorRenderer.COMPACT.render(callableFromEditor),
|
||||||
superString,
|
superString,
|
||||||
"refactor")
|
"refactor"
|
||||||
|
)
|
||||||
val title = IdeBundle.message("title.warning")!!
|
val title = IdeBundle.message("title.warning")!!
|
||||||
val icon = Messages.getQuestionIcon()
|
val icon = Messages.getQuestionIcon()
|
||||||
return Messages.showDialog(message, title, options.toTypedArray(), 0, icon)
|
return Messages.showDialog(message, title, options.toTypedArray(), 0, icon)
|
||||||
@@ -101,8 +109,7 @@ abstract class CallableRefactoring<out T: CallableDescriptor>(
|
|||||||
val message = RefactoringBundle.message("refactoring.cannot.be.performed") + "\n" +
|
val message = RefactoringBundle.message("refactoring.cannot.be.performed") + "\n" +
|
||||||
IdeBundle.message("error.message.cannot.modify.file.0", unmodifiableFile)
|
IdeBundle.message("error.message.cannot.modify.file.0", unmodifiableFile)
|
||||||
Messages.showErrorDialog(project, message, CommonBundle.getErrorTitle()!!)
|
Messages.showErrorDialog(project, message, CommonBundle.getErrorTitle()!!)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
LOG.error("Could not find file for Psi element: " + element.text)
|
LOG.error("Could not find file for Psi element: " + element.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -127,14 +134,13 @@ abstract class CallableRefactoring<out T: CallableDescriptor>(
|
|||||||
fun buildDialogOptions(isSingleFunctionSelected: Boolean): List<String> {
|
fun buildDialogOptions(isSingleFunctionSelected: Boolean): List<String> {
|
||||||
return if (isSingleFunctionSelected) {
|
return if (isSingleFunctionSelected) {
|
||||||
arrayListOf(Messages.YES_BUTTON, Messages.NO_BUTTON, Messages.CANCEL_BUTTON)
|
arrayListOf(Messages.YES_BUTTON, Messages.NO_BUTTON, Messages.CANCEL_BUTTON)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
arrayListOf(Messages.OK_BUTTON, Messages.CANCEL_BUTTON)
|
arrayListOf(Messages.OK_BUTTON, Messages.CANCEL_BUTTON)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kind == SYNTHESIZED) {
|
if (kind == SYNTHESIZED) {
|
||||||
LOG.error("Change signature refactoring should not be called for synthesized member " + callableDescriptor)
|
LOG.error("Change signature refactoring should not be called for synthesized member $callableDescriptor")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,8 +189,7 @@ fun getAffectedCallables(project: Project, descriptorsForChange: Collection<Call
|
|||||||
return baseCallables + baseCallables.flatMapTo(HashSet<PsiElement>()) { callable ->
|
return baseCallables + baseCallables.flatMapTo(HashSet<PsiElement>()) { callable ->
|
||||||
if (callable is KtDeclaration && callable.isExpectDeclaration()) {
|
if (callable is KtDeclaration && callable.isExpectDeclaration()) {
|
||||||
callable.actualsForExpected()
|
callable.actualsForExpected()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
callable.toLightMethods().flatMap { psiMethod ->
|
callable.toLightMethods().flatMap { psiMethod ->
|
||||||
val overrides = OverridingMethodsSearch.search(psiMethod).findAll()
|
val overrides = OverridingMethodsSearch.search(psiMethod).findAll()
|
||||||
overrides.map { method -> method.namedUnwrappedElement ?: method }
|
overrides.map { method -> method.namedUnwrappedElement ?: method }
|
||||||
@@ -200,10 +205,8 @@ fun DeclarationDescriptor.getContainingScope(): LexicalScope? {
|
|||||||
val lastStatement = block.statements.last()
|
val lastStatement = block.statements.last()
|
||||||
val bindingContext = lastStatement.analyze()
|
val bindingContext = lastStatement.analyze()
|
||||||
lastStatement.getResolutionScope(bindingContext, lastStatement.getResolutionFacade())
|
lastStatement.getResolutionScope(bindingContext, lastStatement.getResolutionFacade())
|
||||||
}
|
} else {
|
||||||
else {
|
when (val containingDescriptor = containingDeclaration ?: return null) {
|
||||||
val containingDescriptor = containingDeclaration ?: return null
|
|
||||||
when (containingDescriptor) {
|
|
||||||
is ClassDescriptorWithResolutionScopes -> containingDescriptor.scopeForInitializerResolution
|
is ClassDescriptorWithResolutionScopes -> containingDescriptor.scopeForInitializerResolution
|
||||||
is PackageFragmentDescriptor -> LexicalScope.Base(containingDescriptor.getMemberScope().memberScopeAsImportingScope(), this)
|
is PackageFragmentDescriptor -> LexicalScope.Base(containingDescriptor.getMemberScope().memberScopeAsImportingScope(), this)
|
||||||
else -> null
|
else -> null
|
||||||
|
|||||||
+29
-22
@@ -36,7 +36,6 @@ import org.jetbrains.kotlin.descriptors.Visibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.Visibility
|
import org.jetbrains.kotlin.descriptors.Visibility
|
||||||
import org.jetbrains.kotlin.idea.KotlinLanguage
|
import org.jetbrains.kotlin.idea.KotlinLanguage
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaOrKotlinMemberDescriptor
|
import org.jetbrains.kotlin.idea.caches.resolve.util.getJavaOrKotlinMemberDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.util.javaResolutionFacade
|
|
||||||
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
import org.jetbrains.kotlin.idea.project.TargetPlatformDetector
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor.Kind
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinMethodDescriptor.Kind
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinCallableDefinitionUsage
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.usages.KotlinCallableDefinitionUsage
|
||||||
@@ -72,7 +71,11 @@ open class KotlinChangeInfo(
|
|||||||
val defaultValues: Set<KtExpression>
|
val defaultValues: Set<KtExpression>
|
||||||
) {
|
) {
|
||||||
fun constrainBy(other: JvmOverloadSignature): JvmOverloadSignature {
|
fun constrainBy(other: JvmOverloadSignature): JvmOverloadSignature {
|
||||||
return JvmOverloadSignature(method, mandatoryParams.intersect(other.mandatoryParams), defaultValues.intersect(other.defaultValues))
|
return JvmOverloadSignature(
|
||||||
|
method,
|
||||||
|
mandatoryParams.intersect(other.mandatoryParams),
|
||||||
|
defaultValues.intersect(other.defaultValues)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -142,11 +145,11 @@ open class KotlinChangeInfo(
|
|||||||
newParameters[index] = parameterInfo
|
newParameters[index] = parameterInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
@JvmOverloads fun addParameter(parameterInfo: KotlinParameterInfo, atIndex: Int = -1) {
|
@JvmOverloads
|
||||||
|
fun addParameter(parameterInfo: KotlinParameterInfo, atIndex: Int = -1) {
|
||||||
if (atIndex >= 0) {
|
if (atIndex >= 0) {
|
||||||
newParameters.add(atIndex, parameterInfo)
|
newParameters.add(atIndex, parameterInfo)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
newParameters.add(parameterInfo)
|
newParameters.add(parameterInfo)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -230,7 +233,7 @@ open class KotlinChangeInfo(
|
|||||||
private fun renderReturnTypeIfNeeded(): String? {
|
private fun renderReturnTypeIfNeeded(): String? {
|
||||||
val typeInfo = newReturnTypeInfo
|
val typeInfo = newReturnTypeInfo
|
||||||
if (kind != Kind.FUNCTION) return null
|
if (kind != Kind.FUNCTION) return null
|
||||||
if (typeInfo.type?.isUnit() ?: false) return null
|
if (typeInfo.type?.isUnit() == true) return null
|
||||||
return typeInfo.render()
|
return typeInfo.render()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -244,8 +247,7 @@ open class KotlinChangeInfo(
|
|||||||
if (isCustomizedVisibility) {
|
if (isCustomizedVisibility) {
|
||||||
buffer.append(' ').append(newVisibility).append(" constructor ")
|
buffer.append(' ').append(newVisibility).append(" constructor ")
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (!DescriptorUtils.isLocal(inheritedCallable.originalCallableDescriptor) && isCustomizedVisibility) {
|
if (!DescriptorUtils.isLocal(inheritedCallable.originalCallableDescriptor) && isCustomizedVisibility) {
|
||||||
buffer.append(newVisibility).append(' ')
|
buffer.append(newVisibility).append(' ')
|
||||||
}
|
}
|
||||||
@@ -257,8 +259,7 @@ open class KotlinChangeInfo(
|
|||||||
val typeInfo = it.currentTypeInfo
|
val typeInfo = it.currentTypeInfo
|
||||||
if (typeInfo.type != null && typeInfo.type.isNonExtensionFunctionType) {
|
if (typeInfo.type != null && typeInfo.type.isNonExtensionFunctionType) {
|
||||||
buffer.append("(${typeInfo.render()})")
|
buffer.append("(${typeInfo.render()})")
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
buffer.append(typeInfo.render())
|
buffer.append(typeInfo.render())
|
||||||
}
|
}
|
||||||
buffer.append('.')
|
buffer.append('.')
|
||||||
@@ -332,8 +333,8 @@ open class KotlinChangeInfo(
|
|||||||
|
|
||||||
val mandatoryParams = parameters.toMutableList()
|
val mandatoryParams = parameters.toMutableList()
|
||||||
val defaultValues = ArrayList<KtExpression>()
|
val defaultValues = ArrayList<KtExpression>()
|
||||||
return psiMethods.map {
|
return psiMethods.map { method ->
|
||||||
JvmOverloadSignature(it, mandatoryParams.asSequence().map(getPsi).toSet(), defaultValues.toSet()).apply {
|
JvmOverloadSignature(method, mandatoryParams.asSequence().map(getPsi).toSet(), defaultValues.toSet()).apply {
|
||||||
val param = mandatoryParams.removeLast { getDefaultValue(it) != null } ?: return@apply
|
val param = mandatoryParams.removeLast { getDefaultValue(it) != null } ?: return@apply
|
||||||
defaultValues.add(getDefaultValue(param)!!)
|
defaultValues.add(getDefaultValue(param)!!)
|
||||||
}
|
}
|
||||||
@@ -358,7 +359,8 @@ open class KotlinChangeInfo(
|
|||||||
fun matchOriginalAndCurrentMethods(currentPsiMethods: List<PsiMethod>): Map<PsiMethod, PsiMethod> {
|
fun matchOriginalAndCurrentMethods(currentPsiMethods: List<PsiMethod>): Map<PsiMethod, PsiMethod> {
|
||||||
if (!(isPrimaryMethodUpdated
|
if (!(isPrimaryMethodUpdated
|
||||||
&& originalBaseFunctionDescriptor is FunctionDescriptor
|
&& originalBaseFunctionDescriptor is FunctionDescriptor
|
||||||
&& originalBaseFunctionDescriptor.findJvmOverloadsAnnotation() != null)) {
|
&& originalBaseFunctionDescriptor.findJvmOverloadsAnnotation() != null)
|
||||||
|
) {
|
||||||
return (originalPsiMethods.zip(currentPsiMethods)).toMap()
|
return (originalPsiMethods.zip(currentPsiMethods)).toMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -384,7 +386,8 @@ open class KotlinChangeInfo(
|
|||||||
* So we resort to this hack and pass around "default" type (void) and visibility (package-local)
|
* So we resort to this hack and pass around "default" type (void) and visibility (package-local)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
fun createJavaChangeInfo(originalPsiMethod: PsiMethod,
|
fun createJavaChangeInfo(
|
||||||
|
originalPsiMethod: PsiMethod,
|
||||||
currentPsiMethod: PsiMethod,
|
currentPsiMethod: PsiMethod,
|
||||||
newName: String,
|
newName: String,
|
||||||
newReturnType: PsiType?,
|
newReturnType: PsiType?,
|
||||||
@@ -427,7 +430,8 @@ open class KotlinChangeInfo(
|
|||||||
var defaultValuesRemained = defaultValuesToRetain
|
var defaultValuesRemained = defaultValuesToRetain
|
||||||
for (param in newParameterList) {
|
for (param in newParameterList) {
|
||||||
if (param.isNewParameter || param.defaultValueForParameter == null || defaultValuesRemained-- > 0) continue
|
if (param.isNewParameter || param.defaultValueForParameter == null || defaultValuesRemained-- > 0) continue
|
||||||
newParameterList.asSequence().withIndex().filter { it.value.oldIndex >= param.oldIndex }.toList().forEach { oldIndices[it.index]-- }
|
newParameterList.asSequence().withIndex().filter { it.value.oldIndex >= param.oldIndex }.toList()
|
||||||
|
.forEach { oldIndices[it.index]-- }
|
||||||
}
|
}
|
||||||
|
|
||||||
defaultValuesRemained = defaultValuesToRetain
|
defaultValuesRemained = defaultValuesToRetain
|
||||||
@@ -476,8 +480,7 @@ open class KotlinChangeInfo(
|
|||||||
val newIndex = if (receiverParameterInfo != null) 1 else 0
|
val newIndex = if (receiverParameterInfo != null) 1 else 0
|
||||||
val setterParameter = currentPsiMethod.parameterList.parameters[newIndex]
|
val setterParameter = currentPsiMethod.parameterList.parameters[newIndex]
|
||||||
newJavaParameters.add(ParameterInfoImpl(oldIndex, setterParameter.name, setterParameter.type))
|
newJavaParameters.add(ParameterInfoImpl(oldIndex, setterParameter.name, setterParameter.type))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
newJavaParameters.add(ParameterInfoImpl(oldIndex, "receiver", PsiType.VOID))
|
newJavaParameters.add(ParameterInfoImpl(oldIndex, "receiver", PsiType.VOID))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -548,7 +551,7 @@ fun ChangeInfo.toJetChangeInfo(
|
|||||||
info is KotlinAwareJavaParameterInfoImpl -> info.kotlinDefaultValue
|
info is KotlinAwareJavaParameterInfoImpl -> info.kotlinDefaultValue
|
||||||
language.`is`(JavaLanguage.INSTANCE) && !defaultValueText.isNullOrEmpty() -> {
|
language.`is`(JavaLanguage.INSTANCE) && !defaultValueText.isNullOrEmpty() -> {
|
||||||
PsiElementFactory.SERVICE.getInstance(method.project)
|
PsiElementFactory.SERVICE.getInstance(method.project)
|
||||||
.createExpressionFromText(defaultValueText!!, null)
|
.createExpressionFromText(defaultValueText, null)
|
||||||
.j2k()
|
.j2k()
|
||||||
}
|
}
|
||||||
else -> null
|
else -> null
|
||||||
@@ -557,21 +560,25 @@ fun ChangeInfo.toJetChangeInfo(
|
|||||||
val parameterType = if (oldIndex >= 0) originalParameterDescriptors[oldIndex].type else currentType
|
val parameterType = if (oldIndex >= 0) originalParameterDescriptors[oldIndex].type else currentType
|
||||||
val originalKtParameter = originalParameterDescriptors.getOrNull(oldIndex)?.source?.getPsi() as? KtParameter
|
val originalKtParameter = originalParameterDescriptors.getOrNull(oldIndex)?.source?.getPsi() as? KtParameter
|
||||||
val valOrVar = originalKtParameter?.valOrVarKeyword?.toValVar() ?: KotlinValVar.None
|
val valOrVar = originalKtParameter?.valOrVarKeyword?.toValVar() ?: KotlinValVar.None
|
||||||
KotlinParameterInfo(callableDescriptor = functionDescriptor,
|
KotlinParameterInfo(
|
||||||
|
callableDescriptor = functionDescriptor,
|
||||||
originalIndex = oldIndex,
|
originalIndex = oldIndex,
|
||||||
name = info.name,
|
name = info.name,
|
||||||
originalTypeInfo = KotlinTypeInfo(false, parameterType),
|
originalTypeInfo = KotlinTypeInfo(false, parameterType),
|
||||||
defaultValueForCall = defaultValueExpr,
|
defaultValueForCall = defaultValueExpr,
|
||||||
valOrVar = valOrVar).apply {
|
valOrVar = valOrVar
|
||||||
|
).apply {
|
||||||
currentTypeInfo = KotlinTypeInfo(false, currentType)
|
currentTypeInfo = KotlinTypeInfo(false, currentType)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return KotlinChangeInfo(originalChangeSignatureDescriptor,
|
return KotlinChangeInfo(
|
||||||
|
originalChangeSignatureDescriptor,
|
||||||
newName,
|
newName,
|
||||||
KotlinTypeInfo(true, functionDescriptor.returnType),
|
KotlinTypeInfo(true, functionDescriptor.returnType),
|
||||||
functionDescriptor.visibility,
|
functionDescriptor.visibility,
|
||||||
newParameters,
|
newParameters,
|
||||||
null,
|
null,
|
||||||
method)
|
method
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-4
@@ -20,7 +20,6 @@ import com.intellij.openapi.application.ApplicationManager
|
|||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.Ref
|
import com.intellij.openapi.util.Ref
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
import com.intellij.refactoring.BaseRefactoringProcessor
|
|
||||||
import com.intellij.refactoring.RefactoringBundle
|
import com.intellij.refactoring.RefactoringBundle
|
||||||
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase
|
import com.intellij.refactoring.changeSignature.ChangeSignatureProcessorBase
|
||||||
import com.intellij.refactoring.changeSignature.ChangeSignatureUsageProcessor
|
import com.intellij.refactoring.changeSignature.ChangeSignatureUsageProcessor
|
||||||
@@ -92,7 +91,7 @@ class KotlinChangeSignatureProcessor(
|
|||||||
RenameUtil.removeConflictUsages(usagesSet)
|
RenameUtil.removeConflictUsages(usagesSet)
|
||||||
if (!conflictDescriptions.isEmpty) {
|
if (!conflictDescriptions.isEmpty) {
|
||||||
if (ApplicationManager.getApplication().isUnitTestMode) {
|
if (ApplicationManager.getApplication().isUnitTestMode) {
|
||||||
throw BaseRefactoringProcessor.ConflictsInTestsException(conflictDescriptions.values())
|
throw ConflictsInTestsException(conflictDescriptions.values())
|
||||||
}
|
}
|
||||||
|
|
||||||
val dialog = prepareConflictsDialog(conflictDescriptions, usages)
|
val dialog = prepareConflictsDialog(conflictDescriptions, usages)
|
||||||
@@ -127,8 +126,7 @@ class KotlinChangeSignatureProcessor(
|
|||||||
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
override fun performRefactoring(usages: Array<out UsageInfo>) {
|
||||||
try {
|
try {
|
||||||
super.performRefactoring(usages)
|
super.performRefactoring(usages)
|
||||||
}
|
} finally {
|
||||||
finally {
|
|
||||||
changeInfo.invalidate()
|
changeInfo.invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+58
-42
@@ -76,15 +76,20 @@ class KotlinChangeSignatureDialog(
|
|||||||
KotlinMethodDescriptor,
|
KotlinMethodDescriptor,
|
||||||
ParameterTableModelItemBase<KotlinParameterInfo>,
|
ParameterTableModelItemBase<KotlinParameterInfo>,
|
||||||
KotlinCallableParameterTableModel>(project, methodDescriptor, false, context) {
|
KotlinCallableParameterTableModel>(project, methodDescriptor, false, context) {
|
||||||
override fun getFileType() = KotlinFileType.INSTANCE
|
override fun getFileType(): KotlinFileType = KotlinFileType.INSTANCE
|
||||||
|
|
||||||
override fun createParametersInfoModel(descriptor: KotlinMethodDescriptor) = createParametersInfoModel(descriptor, myDefaultValueContext)
|
override fun createParametersInfoModel(descriptor: KotlinMethodDescriptor) =
|
||||||
|
createParametersInfoModel(descriptor, myDefaultValueContext)
|
||||||
|
|
||||||
override fun createReturnTypeCodeFragment() = createReturnTypeCodeFragment(myProject, myMethod)
|
override fun createReturnTypeCodeFragment() = createReturnTypeCodeFragment(myProject, myMethod)
|
||||||
|
|
||||||
private val parametersTableModel: KotlinCallableParameterTableModel get() = super.myParametersTableModel
|
private val parametersTableModel: KotlinCallableParameterTableModel get() = super.myParametersTableModel
|
||||||
|
|
||||||
override fun getRowPresentation(item: ParameterTableModelItemBase<KotlinParameterInfo>, selected: Boolean, focused: Boolean): JComponent? {
|
override fun getRowPresentation(
|
||||||
|
item: ParameterTableModelItemBase<KotlinParameterInfo>,
|
||||||
|
selected: Boolean,
|
||||||
|
focused: Boolean
|
||||||
|
): JComponent? {
|
||||||
val panel = JPanel(BorderLayout())
|
val panel = JPanel(BorderLayout())
|
||||||
|
|
||||||
val valOrVar = if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) {
|
val valOrVar = if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) {
|
||||||
@@ -93,8 +98,7 @@ class KotlinChangeSignatureDialog(
|
|||||||
KotlinValVar.Val -> "val "
|
KotlinValVar.Val -> "val "
|
||||||
KotlinValVar.Var -> "var "
|
KotlinValVar.Var -> "var "
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
""
|
""
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -118,8 +122,7 @@ class KotlinChangeSignatureDialog(
|
|||||||
if (selected && focused) {
|
if (selected && focused) {
|
||||||
panel.background = UIUtil.getTableSelectionBackground()
|
panel.background = UIUtil.getTableSelectionBackground()
|
||||||
field.setAsRendererWithSelection(UIUtil.getTableSelectionBackground(), UIUtil.getTableSelectionForeground())
|
field.setAsRendererWithSelection(UIUtil.getTableSelectionBackground(), UIUtil.getTableSelectionForeground())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
panel.background = UIUtil.getTableBackground()
|
panel.background = UIUtil.getTableBackground()
|
||||||
if (selected && !focused) {
|
if (selected && !focused) {
|
||||||
panel.border = DottedBorder(UIUtil.getTableForeground())
|
panel.border = DottedBorder(UIUtil.getTableForeground())
|
||||||
@@ -147,8 +150,8 @@ class KotlinChangeSignatureDialog(
|
|||||||
override fun isListTableViewSupported() = true
|
override fun isListTableViewSupported() = true
|
||||||
|
|
||||||
override fun isEmptyRow(row: ParameterTableModelItemBase<KotlinParameterInfo>): Boolean {
|
override fun isEmptyRow(row: ParameterTableModelItemBase<KotlinParameterInfo>): Boolean {
|
||||||
if (!row.parameter.name.isEmpty()) return false
|
if (row.parameter.name.isNotEmpty()) return false
|
||||||
if (!row.parameter.typeText.isEmpty()) return false
|
if (row.parameter.typeText.isNotEmpty()) return false
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -185,18 +188,15 @@ class KotlinChangeSignatureDialog(
|
|||||||
val document = PsiDocumentManager.getInstance(project).getDocument(item.typeCodeFragment)
|
val document = PsiDocumentManager.getInstance(project).getDocument(item.typeCodeFragment)
|
||||||
editor = EditorTextField(document, project, fileType)
|
editor = EditorTextField(document, project, fileType)
|
||||||
component = editor
|
component = editor
|
||||||
}
|
} else if (KotlinCallableParameterTableModel.isNameColumn(columnInfo)) {
|
||||||
else if (KotlinCallableParameterTableModel.isNameColumn(columnInfo)) {
|
|
||||||
editor = nameEditor
|
editor = nameEditor
|
||||||
component = editor
|
component = editor
|
||||||
updateNameEditor()
|
updateNameEditor()
|
||||||
}
|
} else if (KotlinCallableParameterTableModel.isDefaultValueColumn(columnInfo) && isDefaultColumnEnabled()) {
|
||||||
else if (KotlinCallableParameterTableModel.isDefaultValueColumn(columnInfo) && isDefaultColumnEnabled()) {
|
|
||||||
val document = PsiDocumentManager.getInstance(project).getDocument(item.defaultValueCodeFragment)
|
val document = PsiDocumentManager.getInstance(project).getDocument(item.defaultValueCodeFragment)
|
||||||
editor = EditorTextField(document, project, fileType)
|
editor = EditorTextField(document, project, fileType)
|
||||||
component = editor
|
component = editor
|
||||||
}
|
} else if (KotlinPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo)) {
|
||||||
else if (KotlinPrimaryConstructorParameterTableModel.isValVarColumn(columnInfo)) {
|
|
||||||
val comboBox = JComboBox(KotlinValVar.values())
|
val comboBox = JComboBox(KotlinValVar.values())
|
||||||
comboBox.selectedItem = item.parameter.valOrVar
|
comboBox.selectedItem = item.parameter.valOrVar
|
||||||
comboBox.addItemListener {
|
comboBox.addItemListener {
|
||||||
@@ -205,8 +205,7 @@ class KotlinChangeSignatureDialog(
|
|||||||
}
|
}
|
||||||
component = comboBox
|
component = comboBox
|
||||||
editor = null
|
editor = null
|
||||||
}
|
} else if (KotlinFunctionParameterTableModel.isReceiverColumn(columnInfo)) {
|
||||||
else if (KotlinFunctionParameterTableModel.isReceiverColumn(columnInfo)) {
|
|
||||||
val checkBox = JCheckBox()
|
val checkBox = JCheckBox()
|
||||||
checkBox.isSelected = parametersTableModel.receiver == item.parameter
|
checkBox.isSelected = parametersTableModel.receiver == item.parameter
|
||||||
checkBox.addItemListener {
|
checkBox.addItemListener {
|
||||||
@@ -217,8 +216,7 @@ class KotlinChangeSignatureDialog(
|
|||||||
}
|
}
|
||||||
component = checkBox
|
component = checkBox
|
||||||
editor = null
|
editor = null
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
continue
|
continue
|
||||||
|
|
||||||
val label = JBLabel(columnInfo.name, UIUtil.ComponentStyle.SMALL)
|
val label = JBLabel(columnInfo.name, UIUtil.ComponentStyle.SMALL)
|
||||||
@@ -277,7 +275,7 @@ class KotlinChangeSignatureDialog(
|
|||||||
intArrayOf(4, getParamNamesMaxLength(), getTypesMaxLength())
|
intArrayOf(4, getParamNamesMaxLength(), getTypesMaxLength())
|
||||||
|
|
||||||
var columnIndex = 0
|
var columnIndex = 0
|
||||||
for (i in (if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) 0 else 1)..columnLetters.size - 1) {
|
for (i in (if (myMethod.kind === Kind.PRIMARY_CONSTRUCTOR) 0 else 1) until columnLetters.size) {
|
||||||
val width = getColumnWidth(columnLetters[i])
|
val width = getColumnWidth(columnLetters[i])
|
||||||
|
|
||||||
if (x <= width)
|
if (x <= width)
|
||||||
@@ -311,13 +309,15 @@ class KotlinChangeSignatureDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun calculateSignature(): String {
|
override fun calculateSignature(): String {
|
||||||
val changeInfo = evaluateChangeInfo(parametersTableModel,
|
val changeInfo = evaluateChangeInfo(
|
||||||
|
parametersTableModel,
|
||||||
myReturnTypeCodeFragment,
|
myReturnTypeCodeFragment,
|
||||||
getMethodDescriptor(),
|
getMethodDescriptor(),
|
||||||
visibility,
|
visibility,
|
||||||
methodName,
|
methodName,
|
||||||
myDefaultValueContext,
|
myDefaultValueContext,
|
||||||
true)
|
true
|
||||||
|
)
|
||||||
return changeInfo.getNewSignature(getMethodDescriptor().originalPrimaryCallable)
|
return changeInfo.getNewSignature(getMethodDescriptor().originalPrimaryCallable)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -332,27 +332,30 @@ class KotlinChangeSignatureDialog(
|
|||||||
|
|
||||||
override fun validateAndCommitData(): String? {
|
override fun validateAndCommitData(): String? {
|
||||||
if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite &&
|
if (myMethod.canChangeReturnType() == MethodDescriptor.ReadWriteOption.ReadWrite &&
|
||||||
myReturnTypeCodeFragment.getTypeInfo(true, false).type == null) {
|
myReturnTypeCodeFragment.getTypeInfo(isCovariant = true, forPreview = false).type == null
|
||||||
|
) {
|
||||||
if (Messages.showOkCancelDialog(
|
if (Messages.showOkCancelDialog(
|
||||||
myProject,
|
myProject,
|
||||||
"Return type '${myReturnTypeCodeFragment!!.text}' cannot be resolved.\nContinue?",
|
"Return type '${myReturnTypeCodeFragment!!.text}' cannot be resolved.\nContinue?",
|
||||||
RefactoringBundle.message("changeSignature.refactoring.name"),
|
RefactoringBundle.message("changeSignature.refactoring.name"),
|
||||||
Messages.getWarningIcon()
|
Messages.getWarningIcon()
|
||||||
) != Messages.OK) {
|
) != Messages.OK
|
||||||
return ChangeSignatureDialogBase.EXIT_SILENTLY
|
) {
|
||||||
|
return EXIT_SILENTLY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
for (item in parametersTableModel.items) {
|
for (item in parametersTableModel.items) {
|
||||||
if (item.typeCodeFragment.getTypeInfo(true, false).type == null) {
|
if (item.typeCodeFragment.getTypeInfo(isCovariant = true, forPreview = false).type == null) {
|
||||||
val paramText = if (item.parameter != parametersTableModel.receiver) "parameter '${item.parameter.name}'" else "receiver"
|
val paramText = if (item.parameter != parametersTableModel.receiver) "parameter '${item.parameter.name}'" else "receiver"
|
||||||
if (Messages.showOkCancelDialog(
|
if (Messages.showOkCancelDialog(
|
||||||
myProject,
|
myProject,
|
||||||
"Type '${item.typeCodeFragment.text}' for $paramText cannot be resolved.\nContinue?",
|
"Type '${item.typeCodeFragment.text}' for $paramText cannot be resolved.\nContinue?",
|
||||||
RefactoringBundle.message("changeSignature.refactoring.name"),
|
RefactoringBundle.message("changeSignature.refactoring.name"),
|
||||||
Messages.getWarningIcon()
|
Messages.getWarningIcon()
|
||||||
) != Messages.OK) {
|
) != Messages.OK
|
||||||
return ChangeSignatureDialogBase.EXIT_SILENTLY
|
) {
|
||||||
|
return EXIT_SILENTLY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -382,13 +385,15 @@ class KotlinChangeSignatureDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun createRefactoringProcessor(): BaseRefactoringProcessor {
|
override fun createRefactoringProcessor(): BaseRefactoringProcessor {
|
||||||
val changeInfo = evaluateChangeInfo(parametersTableModel,
|
val changeInfo = evaluateChangeInfo(
|
||||||
|
parametersTableModel,
|
||||||
myReturnTypeCodeFragment,
|
myReturnTypeCodeFragment,
|
||||||
getMethodDescriptor(),
|
getMethodDescriptor(),
|
||||||
visibility,
|
visibility,
|
||||||
methodName,
|
methodName,
|
||||||
myDefaultValueContext,
|
myDefaultValueContext,
|
||||||
false)
|
false
|
||||||
|
)
|
||||||
changeInfo.primaryPropagationTargets = myMethodsToPropagateParameters ?: emptyList()
|
changeInfo.primaryPropagationTargets = myMethodsToPropagateParameters ?: emptyList()
|
||||||
return KotlinChangeSignatureProcessor(myProject, changeInfo, commandName ?: title)
|
return KotlinChangeSignatureProcessor(myProject, changeInfo, commandName ?: title)
|
||||||
}
|
}
|
||||||
@@ -401,12 +406,15 @@ class KotlinChangeSignatureDialog(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private fun createParametersInfoModel(descriptor: KotlinMethodDescriptor, defaultValueContext: PsiElement): KotlinCallableParameterTableModel {
|
private fun createParametersInfoModel(
|
||||||
|
descriptor: KotlinMethodDescriptor,
|
||||||
|
defaultValueContext: PsiElement
|
||||||
|
): KotlinCallableParameterTableModel {
|
||||||
val typeContext = getTypeCodeFragmentContext(descriptor.baseDeclaration)
|
val typeContext = getTypeCodeFragmentContext(descriptor.baseDeclaration)
|
||||||
return when (descriptor.kind) {
|
return when (descriptor.kind) {
|
||||||
KotlinMethodDescriptor.Kind.FUNCTION -> KotlinFunctionParameterTableModel(descriptor, typeContext, defaultValueContext)
|
Kind.FUNCTION -> KotlinFunctionParameterTableModel(descriptor, typeContext, defaultValueContext)
|
||||||
KotlinMethodDescriptor.Kind.PRIMARY_CONSTRUCTOR -> KotlinPrimaryConstructorParameterTableModel(descriptor, typeContext, defaultValueContext)
|
Kind.PRIMARY_CONSTRUCTOR -> KotlinPrimaryConstructorParameterTableModel(descriptor, typeContext, defaultValueContext)
|
||||||
KotlinMethodDescriptor.Kind.SECONDARY_CONSTRUCTOR -> KotlinSecondaryConstructorParameterTableModel(descriptor, typeContext, defaultValueContext)
|
Kind.SECONDARY_CONSTRUCTOR -> KotlinSecondaryConstructorParameterTableModel(descriptor, typeContext, defaultValueContext)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -427,19 +435,23 @@ class KotlinChangeSignatureDialog(
|
|||||||
private fun createReturnTypeCodeFragment(project: Project, method: KotlinMethodDescriptor) =
|
private fun createReturnTypeCodeFragment(project: Project, method: KotlinMethodDescriptor) =
|
||||||
KtPsiFactory(project).createTypeCodeFragment(method.returnTypeInfo.render(), getTypeCodeFragmentContext(method.baseDeclaration))
|
KtPsiFactory(project).createTypeCodeFragment(method.returnTypeInfo.render(), getTypeCodeFragmentContext(method.baseDeclaration))
|
||||||
|
|
||||||
fun createRefactoringProcessorForSilentChangeSignature(project: Project,
|
fun createRefactoringProcessorForSilentChangeSignature(
|
||||||
|
project: Project,
|
||||||
commandName: String,
|
commandName: String,
|
||||||
method: KotlinMethodDescriptor,
|
method: KotlinMethodDescriptor,
|
||||||
defaultValueContext: PsiElement): BaseRefactoringProcessor {
|
defaultValueContext: PsiElement
|
||||||
|
): BaseRefactoringProcessor {
|
||||||
val parameterTableModel = createParametersInfoModel(method, defaultValueContext)
|
val parameterTableModel = createParametersInfoModel(method, defaultValueContext)
|
||||||
parameterTableModel.setParameterInfos(method.parameters)
|
parameterTableModel.setParameterInfos(method.parameters)
|
||||||
val changeInfo = evaluateChangeInfo(parameterTableModel,
|
val changeInfo = evaluateChangeInfo(
|
||||||
|
parameterTableModel,
|
||||||
createReturnTypeCodeFragment(project, method),
|
createReturnTypeCodeFragment(project, method),
|
||||||
method,
|
method,
|
||||||
method.visibility,
|
method.visibility,
|
||||||
method.name,
|
method.name,
|
||||||
defaultValueContext,
|
defaultValueContext,
|
||||||
false)
|
false
|
||||||
|
)
|
||||||
return KotlinChangeSignatureProcessor(project, changeInfo, commandName)
|
return KotlinChangeSignatureProcessor(project, changeInfo, commandName)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -455,13 +467,15 @@ class KotlinChangeSignatureDialog(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun evaluateChangeInfo(parametersModel: KotlinCallableParameterTableModel,
|
private fun evaluateChangeInfo(
|
||||||
|
parametersModel: KotlinCallableParameterTableModel,
|
||||||
returnTypeCodeFragment: PsiCodeFragment?,
|
returnTypeCodeFragment: PsiCodeFragment?,
|
||||||
methodDescriptor: KotlinMethodDescriptor,
|
methodDescriptor: KotlinMethodDescriptor,
|
||||||
visibility: Visibility?,
|
visibility: Visibility?,
|
||||||
methodName: String,
|
methodName: String,
|
||||||
defaultValueContext: PsiElement,
|
defaultValueContext: PsiElement,
|
||||||
forPreview: Boolean): KotlinChangeInfo {
|
forPreview: Boolean
|
||||||
|
): KotlinChangeInfo {
|
||||||
val parameters = parametersModel.items.map { parameter ->
|
val parameters = parametersModel.items.map { parameter ->
|
||||||
val parameterInfo = parameter.parameter
|
val parameterInfo = parameter.parameter
|
||||||
|
|
||||||
@@ -476,13 +490,15 @@ class KotlinChangeSignatureDialog(
|
|||||||
parameterInfo
|
parameterInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
return KotlinChangeInfo(methodDescriptor.original,
|
return KotlinChangeInfo(
|
||||||
|
methodDescriptor.original,
|
||||||
methodName,
|
methodName,
|
||||||
returnTypeCodeFragment.getTypeInfo(true, forPreview),
|
returnTypeCodeFragment.getTypeInfo(true, forPreview),
|
||||||
visibility ?: Visibilities.DEFAULT_VISIBILITY,
|
visibility ?: Visibilities.DEFAULT_VISIBILITY,
|
||||||
parameters,
|
parameters,
|
||||||
parametersModel.receiver,
|
parametersModel.receiver,
|
||||||
defaultValueContext)
|
defaultValueContext
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -131,7 +131,7 @@ class KotlinCallableDefinitionUsage<T : PsiElement>(
|
|||||||
val receiverTypeText = changeInfo.renderReceiverType(this)
|
val receiverTypeText = changeInfo.renderReceiverType(this)
|
||||||
val receiverTypeRef = if (receiverTypeText != null) psiFactory.createType(receiverTypeText) else null
|
val receiverTypeRef = if (receiverTypeText != null) psiFactory.createType(receiverTypeText) else null
|
||||||
val newReceiverTypeRef = element.setReceiverTypeReference(receiverTypeRef)
|
val newReceiverTypeRef = element.setReceiverTypeReference(receiverTypeRef)
|
||||||
newReceiverTypeRef?.addToShorteningWaitSet(ShortenReferences.Options.DEFAULT)
|
newReceiverTypeRef?.addToShorteningWaitSet(Options.DEFAULT)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (changeInfo.isVisibilityChanged() && !KtPsiUtil.isLocal(element as KtDeclaration)) {
|
if (changeInfo.isVisibilityChanged() && !KtPsiUtil.isLocal(element as KtDeclaration)) {
|
||||||
|
|||||||
+23
-25
@@ -25,6 +25,7 @@ import com.intellij.util.containers.ContainerUtil
|
|||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.*
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||||
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
import org.jetbrains.kotlin.idea.codeInsight.shorten.addToShorteningWaitSet
|
||||||
|
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
||||||
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
import org.jetbrains.kotlin.idea.core.moveFunctionLiteralOutsideParentheses
|
||||||
import org.jetbrains.kotlin.idea.core.replaced
|
import org.jetbrains.kotlin.idea.core.replaced
|
||||||
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeInfo
|
import org.jetbrains.kotlin.idea.refactoring.changeSignature.KotlinChangeInfo
|
||||||
@@ -33,7 +34,6 @@ import org.jetbrains.kotlin.idea.refactoring.changeSignature.isInsideOfCallerBod
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.createNameCounterpartMap
|
import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.createNameCounterpartMap
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
|
import org.jetbrains.kotlin.idea.refactoring.introduce.introduceVariable.KotlinIntroduceVariableHandler
|
||||||
import org.jetbrains.kotlin.idea.refactoring.replaceListPsiAndKeepDelimiters
|
import org.jetbrains.kotlin.idea.refactoring.replaceListPsiAndKeepDelimiters
|
||||||
import org.jetbrains.kotlin.idea.core.ShortenReferences
|
|
||||||
import org.jetbrains.kotlin.load.java.JvmAbi
|
import org.jetbrains.kotlin.load.java.JvmAbi
|
||||||
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
import org.jetbrains.kotlin.load.java.descriptors.JavaMethodDescriptor
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
@@ -78,8 +78,7 @@ class KotlinFunctionCallUsage(
|
|||||||
if (element.valueArgumentList != null) {
|
if (element.valueArgumentList != null) {
|
||||||
if (changeInfo.isParameterSetOrOrderChanged) {
|
if (changeInfo.isParameterSetOrOrderChanged) {
|
||||||
result = updateArgumentsAndReceiver(changeInfo, element, allUsages)
|
result = updateArgumentsAndReceiver(changeInfo, element, allUsages)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
changeArgumentNames(changeInfo, element)
|
changeArgumentNames(changeInfo, element)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -121,8 +120,7 @@ class KotlinFunctionCallUsage(
|
|||||||
private fun changeNameIfNeeded(changeInfo: KotlinChangeInfo, element: KtCallElement) {
|
private fun changeNameIfNeeded(changeInfo: KotlinChangeInfo, element: KtCallElement) {
|
||||||
if (!changeInfo.isNameChanged) return
|
if (!changeInfo.isNameChanged) return
|
||||||
|
|
||||||
val callee = element.calleeExpression
|
val callee = element.calleeExpression as? KtSimpleNameExpression ?: return
|
||||||
if (callee !is KtSimpleNameExpression) return
|
|
||||||
|
|
||||||
var newName = changeInfo.newName
|
var newName = changeInfo.newName
|
||||||
if (isPropertyJavaUsage) {
|
if (isPropertyJavaUsage) {
|
||||||
@@ -146,8 +144,7 @@ class KotlinFunctionCallUsage(
|
|||||||
// to simplify checking against receiver value in the corresponding resolved call
|
// to simplify checking against receiver value in the corresponding resolved call
|
||||||
val adjustedDescriptor = if (originalDescriptor is CallableDescriptor && originalDescriptor !is ReceiverParameterDescriptor) {
|
val adjustedDescriptor = if (originalDescriptor is CallableDescriptor && originalDescriptor !is ReceiverParameterDescriptor) {
|
||||||
originalDescriptor.extensionReceiverParameter ?: return null
|
originalDescriptor.extensionReceiverParameter ?: return null
|
||||||
}
|
} else originalDescriptor
|
||||||
else originalDescriptor
|
|
||||||
|
|
||||||
val currentIsExtension = resolvedCall!!.extensionReceiver == receiverValue
|
val currentIsExtension = resolvedCall!!.extensionReceiver == receiverValue
|
||||||
val originalIsExtension = adjustedDescriptor is ReceiverParameterDescriptor && adjustedDescriptor.value is ExtensionReceiver
|
val originalIsExtension = adjustedDescriptor is ReceiverParameterDescriptor && adjustedDescriptor.value is ExtensionReceiver
|
||||||
@@ -199,8 +196,7 @@ class KotlinFunctionCallUsage(
|
|||||||
|
|
||||||
addReceiver = false
|
addReceiver = false
|
||||||
argumentExpression = argument.getArgumentExpression()
|
argumentExpression = argument.getArgumentExpression()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
addReceiver = descriptor !is ReceiverParameterDescriptor
|
addReceiver = descriptor !is ReceiverParameterDescriptor
|
||||||
argumentExpression =
|
argumentExpression =
|
||||||
getReceiverExpressionIfMatched(resolvedCall.extensionReceiver, descriptor, psiFactory)
|
getReceiverExpressionIfMatched(resolvedCall.extensionReceiver, descriptor, psiFactory)
|
||||||
@@ -209,10 +205,13 @@ class KotlinFunctionCallUsage(
|
|||||||
if (argumentExpression == null) continue
|
if (argumentExpression == null) continue
|
||||||
|
|
||||||
if (needSeparateVariable(argumentExpression)
|
if (needSeparateVariable(argumentExpression)
|
||||||
&& PsiTreeUtil.getNonStrictParentOfType(element,
|
&& PsiTreeUtil.getNonStrictParentOfType(
|
||||||
|
element,
|
||||||
KtConstructorDelegationCall::class.java,
|
KtConstructorDelegationCall::class.java,
|
||||||
KtSuperTypeListEntry::class.java,
|
KtSuperTypeListEntry::class.java,
|
||||||
KtParameter::class.java) == null) {
|
KtParameter::class.java
|
||||||
|
) == null
|
||||||
|
) {
|
||||||
|
|
||||||
KotlinIntroduceVariableHandler.doRefactoring(
|
KotlinIntroduceVariableHandler.doRefactoring(
|
||||||
project, null, argumentExpression,
|
project, null, argumentExpression,
|
||||||
@@ -239,8 +238,7 @@ class KotlinFunctionCallUsage(
|
|||||||
|
|
||||||
val replacement = psiFactory.createExpression("${argumentExpression!!.text}.${expressionToReplace.text}")
|
val replacement = psiFactory.createExpression("${argumentExpression!!.text}.${expressionToReplace.text}")
|
||||||
replacements.add(expressionToReplace to replacement)
|
replacements.add(expressionToReplace to replacement)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
replacements.add(expressionToReplace to argumentExpression!!)
|
replacements.add(expressionToReplace to argumentExpression!!)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -316,7 +314,11 @@ class KotlinFunctionCallUsage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun updateArgumentsAndReceiver(changeInfo: KotlinChangeInfo, element: KtCallElement, allUsages: Array<out UsageInfo>): KtElement {
|
private fun updateArgumentsAndReceiver(
|
||||||
|
changeInfo: KotlinChangeInfo,
|
||||||
|
element: KtCallElement,
|
||||||
|
allUsages: Array<out UsageInfo>
|
||||||
|
): KtElement {
|
||||||
if (isPropertyJavaUsage) return updateJavaPropertyCall(changeInfo, element)
|
if (isPropertyJavaUsage) return updateJavaPropertyCall(changeInfo, element)
|
||||||
|
|
||||||
val fullCallElement = element.getQualifiedExpressionForSelector() ?: element
|
val fullCallElement = element.getQualifiedExpressionForSelector() ?: element
|
||||||
@@ -377,8 +379,7 @@ class KotlinFunctionCallUsage(
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
val resolvedArgument = argInfo.resolvedArgument
|
when (val resolvedArgument = argInfo.resolvedArgument) {
|
||||||
when (resolvedArgument) {
|
|
||||||
null, is DefaultValueArgument -> addArgument(argInfo.getArgumentByDefaultValue(element, allUsages, psiFactory))
|
null, is DefaultValueArgument -> addArgument(argInfo.getArgumentByDefaultValue(element, allUsages, psiFactory))
|
||||||
|
|
||||||
is ExpressionValueArgument -> {
|
is ExpressionValueArgument -> {
|
||||||
@@ -422,15 +423,14 @@ class KotlinFunctionCallUsage(
|
|||||||
|
|
||||||
if (lambdaArgumentNotTouched) {
|
if (lambdaArgumentNotTouched) {
|
||||||
newArgumentList.removeArgument(newArgumentList.arguments.last())
|
newArgumentList.removeArgument(newArgumentList.arguments.last())
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val lambdaArguments = element.lambdaArguments
|
val lambdaArguments = element.lambdaArguments
|
||||||
if (lambdaArguments.isNotEmpty()) {
|
if (lambdaArguments.isNotEmpty()) {
|
||||||
element.deleteChildRange(lambdaArguments.first(), lambdaArguments.last())
|
element.deleteChildRange(lambdaArguments.first(), lambdaArguments.last())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var oldArgumentList = element.valueArgumentList.sure { "Argument list is expected: " + element.text }
|
val oldArgumentList = element.valueArgumentList.sure { "Argument list is expected: " + element.text }
|
||||||
replaceListPsiAndKeepDelimiters(oldArgumentList, newArgumentList) { arguments }
|
replaceListPsiAndKeepDelimiters(oldArgumentList, newArgumentList) { arguments }
|
||||||
|
|
||||||
element.accept(
|
element.accept(
|
||||||
@@ -455,8 +455,7 @@ class KotlinFunctionCallUsage(
|
|||||||
?: psiFactory.createExpression("_")
|
?: psiFactory.createExpression("_")
|
||||||
|
|
||||||
psiFactory.createExpressionByPattern("$0.$1", receiver, element)
|
psiFactory.createExpressionByPattern("$0.$1", receiver, element)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
psiFactory.createExpression(element.text)
|
psiFactory.createExpression(element.text)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -489,7 +488,7 @@ class KotlinFunctionCallUsage(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
private val REVERSED_TEXT_OFFSET_COMPARATOR = Comparator<kotlin.Pair<KtElement, KtElement>> { p1, p2 ->
|
private val REVERSED_TEXT_OFFSET_COMPARATOR = Comparator<Pair<KtElement, KtElement>> { p1, p2 ->
|
||||||
val offset1 = p1.first.startOffset
|
val offset1 = p1.first.startOffset
|
||||||
val offset2 = p2.first.startOffset
|
val offset2 = p2.first.startOffset
|
||||||
when {
|
when {
|
||||||
@@ -499,7 +498,7 @@ class KotlinFunctionCallUsage(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val SHORTEN_ARGUMENTS_OPTIONS = ShortenReferences.Options(true, true)
|
private val SHORTEN_ARGUMENTS_OPTIONS = ShortenReferences.Options(removeThisLabels = true, removeThis = true)
|
||||||
|
|
||||||
private fun updateJavaPropertyCall(changeInfo: KotlinChangeInfo, element: KtCallElement): KtElement {
|
private fun updateJavaPropertyCall(changeInfo: KotlinChangeInfo, element: KtCallElement): KtElement {
|
||||||
val newReceiverInfo = changeInfo.receiverParameterInfo
|
val newReceiverInfo = changeInfo.receiverParameterInfo
|
||||||
@@ -520,8 +519,7 @@ class KotlinFunctionCallUsage(
|
|||||||
|
|
||||||
if (originalReceiverInfo != null) {
|
if (originalReceiverInfo != null) {
|
||||||
firstArgument?.replace(newReceiverArgument)
|
firstArgument?.replace(newReceiverArgument)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
arguments.addArgumentAfter(newReceiverArgument, null)
|
arguments.addArgumentAfter(newReceiverArgument, null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,6 @@
|
|||||||
package org.jetbrains.kotlin.idea.refactoring.inline
|
package org.jetbrains.kotlin.idea.refactoring.inline
|
||||||
|
|
||||||
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
|
import com.intellij.openapi.editor.ex.EditorSettingsExternalizable
|
||||||
import com.intellij.openapi.ui.DialogWrapper
|
|
||||||
import com.intellij.refactoring.JavaRefactoringSettings
|
import com.intellij.refactoring.JavaRefactoringSettings
|
||||||
import org.jetbrains.kotlin.idea.codeInliner.UsageReplacementStrategy
|
import org.jetbrains.kotlin.idea.codeInliner.UsageReplacementStrategy
|
||||||
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
import org.jetbrains.kotlin.idea.references.KtSimpleNameReference
|
||||||
@@ -39,7 +38,7 @@ class KotlinInlineValDialog(
|
|||||||
init {
|
init {
|
||||||
setPreviewResults(withPreview && shouldBeShown())
|
setPreviewResults(withPreview && shouldBeShown())
|
||||||
if (simpleLocal) {
|
if (simpleLocal) {
|
||||||
setDoNotAskOption(object : DialogWrapper.DoNotAskOption {
|
setDoNotAskOption(object : DoNotAskOption {
|
||||||
override fun isToBeShown() = EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog
|
override fun isToBeShown() = EditorSettingsExternalizable.getInstance().isShowInlineLocalDialog
|
||||||
|
|
||||||
override fun setToBeShown(value: Boolean, exitCode: Int) {
|
override fun setToBeShown(value: Boolean, exitCode: Int) {
|
||||||
@@ -62,10 +61,12 @@ class KotlinInlineValDialog(
|
|||||||
|
|
||||||
public override fun doAction() {
|
public override fun doAction() {
|
||||||
invokeRefactoring(
|
invokeRefactoring(
|
||||||
KotlinInlineCallableProcessor(project, replacementStrategy, callable, reference,
|
KotlinInlineCallableProcessor(
|
||||||
|
project, replacementStrategy, callable, reference,
|
||||||
inlineThisOnly = isInlineThisOnly,
|
inlineThisOnly = isInlineThisOnly,
|
||||||
deleteAfter = !isInlineThisOnly && !isKeepTheDeclaration,
|
deleteAfter = !isInlineThisOnly && !isKeepTheDeclaration,
|
||||||
statementToDelete = assignmentToDelete)
|
statementToDelete = assignmentToDelete
|
||||||
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
val settings = JavaRefactoringSettings.getInstance()
|
val settings = JavaRefactoringSettings.getInstance()
|
||||||
|
|||||||
+4
-2
@@ -30,11 +30,13 @@ import org.jetbrains.kotlin.idea.refactoring.introduce.extractionEngine.*
|
|||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetSibling
|
import org.jetbrains.kotlin.idea.refactoring.introduce.selectElementsWithTargetSibling
|
||||||
import org.jetbrains.kotlin.idea.refactoring.introduce.validateExpressionElements
|
import org.jetbrains.kotlin.idea.refactoring.introduce.validateExpressionElements
|
||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.KtBlockExpression
|
||||||
|
import org.jetbrains.kotlin.psi.KtFile
|
||||||
|
|
||||||
class ExtractKotlinFunctionHandler(
|
class ExtractKotlinFunctionHandler(
|
||||||
private val allContainersEnabled: Boolean = false,
|
private val allContainersEnabled: Boolean = false,
|
||||||
private val helper: ExtractionEngineHelper = ExtractKotlinFunctionHandler.InteractiveExtractionHelper) : RefactoringActionHandler {
|
private val helper: ExtractionEngineHelper = InteractiveExtractionHelper
|
||||||
|
) : RefactoringActionHandler {
|
||||||
|
|
||||||
object InteractiveExtractionHelper : ExtractionEngineHelper(EXTRACT_FUNCTION) {
|
object InteractiveExtractionHelper : ExtractionEngineHelper(EXTRACT_FUNCTION) {
|
||||||
override fun configureAndRun(
|
override fun configureAndRun(
|
||||||
|
|||||||
+8
-8
@@ -29,7 +29,7 @@ import javax.swing.table.DefaultTableCellRenderer
|
|||||||
|
|
||||||
open class ExtractFunctionParameterTablePanel : AbstractParameterTablePanel<Parameter, ExtractFunctionParameterTablePanel.ParameterInfo>() {
|
open class ExtractFunctionParameterTablePanel : AbstractParameterTablePanel<Parameter, ExtractFunctionParameterTablePanel.ParameterInfo>() {
|
||||||
companion object {
|
companion object {
|
||||||
val PARAMETER_TYPE_COLUMN = 2
|
const val PARAMETER_TYPE_COLUMN = 2
|
||||||
}
|
}
|
||||||
|
|
||||||
class ParameterInfo(
|
class ParameterInfo(
|
||||||
@@ -45,7 +45,7 @@ open class ExtractFunctionParameterTablePanel : AbstractParameterTablePanel<Para
|
|||||||
override fun toParameter() = originalParameter.copy(name, type)
|
override fun toParameter() = originalParameter.copy(name, type)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createTableModel(): AbstractParameterTablePanel<Parameter, ParameterInfo>.TableModelBase = MyTableModel()
|
override fun createTableModel(): TableModelBase = MyTableModel()
|
||||||
|
|
||||||
override fun createAdditionalColumns() {
|
override fun createAdditionalColumns() {
|
||||||
with(table.columnModel.getColumn(PARAMETER_TYPE_COLUMN)) {
|
with(table.columnModel.getColumn(PARAMETER_TYPE_COLUMN)) {
|
||||||
@@ -61,20 +61,20 @@ open class ExtractFunctionParameterTablePanel : AbstractParameterTablePanel<Para
|
|||||||
myLabel.foreground = if (isSelected) table.selectionForeground else table.foreground
|
myLabel.foreground = if (isSelected) table.selectionForeground else table.foreground
|
||||||
if (isSelected) {
|
if (isSelected) {
|
||||||
myLabel.setSelectionIcon()
|
myLabel.setSelectionIcon()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
myLabel.setRegularIcon()
|
myLabel.setRegularIcon()
|
||||||
}
|
}
|
||||||
return myLabel
|
return myLabel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
cellEditor = object : AbstractTableCellEditor() {
|
cellEditor = object : AbstractTableCellEditor() {
|
||||||
internal val myEditorComponent = JBComboBoxTableCellEditorComponent()
|
val myEditorComponent = JBComboBoxTableCellEditorComponent()
|
||||||
|
|
||||||
override fun getCellEditorValue() = myEditorComponent.editorValue
|
override fun getCellEditorValue() = myEditorComponent.editorValue
|
||||||
|
|
||||||
override fun getTableCellEditorComponent(
|
override fun getTableCellEditorComponent(
|
||||||
table: JTable, value: Any, isSelected: Boolean, row: Int, column: Int): Component {
|
table: JTable, value: Any, isSelected: Boolean, row: Int, column: Int
|
||||||
|
): Component {
|
||||||
val info = parameterInfos[row]
|
val info = parameterInfos[row]
|
||||||
|
|
||||||
myEditorComponent.setCell(table, row, column)
|
myEditorComponent.setCell(table, row, column)
|
||||||
@@ -96,7 +96,7 @@ open class ExtractFunctionParameterTablePanel : AbstractParameterTablePanel<Para
|
|||||||
super.init()
|
super.init()
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class MyTableModel : AbstractParameterTablePanel<Parameter, ParameterInfo>.TableModelBase() {
|
private inner class MyTableModel : TableModelBase() {
|
||||||
override fun getColumnCount() = 3
|
override fun getColumnCount() = 3
|
||||||
|
|
||||||
override fun getValueAt(rowIndex: Int, columnIndex: Int): Any? {
|
override fun getValueAt(rowIndex: Int, columnIndex: Int): Any? {
|
||||||
@@ -117,7 +117,7 @@ open class ExtractFunctionParameterTablePanel : AbstractParameterTablePanel<Para
|
|||||||
override fun isCellEditable(rowIndex: Int, columnIndex: Int): Boolean {
|
override fun isCellEditable(rowIndex: Int, columnIndex: Int): Boolean {
|
||||||
val info = parameterInfos[rowIndex]
|
val info = parameterInfos[rowIndex]
|
||||||
return when (columnIndex) {
|
return when (columnIndex) {
|
||||||
AbstractParameterTablePanel.PARAMETER_NAME_COLUMN -> super.isCellEditable(rowIndex, columnIndex) && !info.isReceiver
|
PARAMETER_NAME_COLUMN -> super.isCellEditable(rowIndex, columnIndex) && !info.isReceiver
|
||||||
PARAMETER_TYPE_COLUMN -> isEnabled && info.isEnabled && info.originalParameter.getParameterTypeCandidates().size > 1
|
PARAMETER_TYPE_COLUMN -> isEnabled && info.isEnabled && info.originalParameter.getParameterTypeCandidates().size > 1
|
||||||
else -> super.isCellEditable(rowIndex, columnIndex)
|
else -> super.isCellEditable(rowIndex, columnIndex)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-2
@@ -67,7 +67,6 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
|||||||
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
|
||||||
import org.jetbrains.kotlin.types.*
|
import org.jetbrains.kotlin.types.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
import org.jetbrains.kotlin.types.typeUtil.makeNullable
|
||||||
import org.jetbrains.kotlin.utils.DFS
|
|
||||||
import org.jetbrains.kotlin.utils.DFS.*
|
import org.jetbrains.kotlin.utils.DFS.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
@@ -407,7 +406,7 @@ internal fun ExtractionData.createTemporaryCodeBlock(): KtBlockExpression {
|
|||||||
|
|
||||||
private fun KotlinType.collectReferencedTypes(processTypeArguments: Boolean): List<KotlinType> {
|
private fun KotlinType.collectReferencedTypes(processTypeArguments: Boolean): List<KotlinType> {
|
||||||
if (!processTypeArguments) return Collections.singletonList(this)
|
if (!processTypeArguments) return Collections.singletonList(this)
|
||||||
return DFS.dfsFromNode(
|
return dfsFromNode(
|
||||||
this,
|
this,
|
||||||
Neighbors<KotlinType> { current -> current.arguments.map { it.type } },
|
Neighbors<KotlinType> { current -> current.arguments.map { it.type } },
|
||||||
VisitedWithSet(),
|
VisitedWithSet(),
|
||||||
|
|||||||
+10
-11
@@ -168,7 +168,7 @@ class DuplicateInfo(
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun ExtractableCodeDescriptor.findDuplicates(): List<DuplicateInfo> {
|
fun ExtractableCodeDescriptor.findDuplicates(): List<DuplicateInfo> {
|
||||||
fun processWeakMatch(match: UnificationResult.WeaklyMatched, newControlFlow: ControlFlow): Boolean {
|
fun processWeakMatch(match: WeaklyMatched, newControlFlow: ControlFlow): Boolean {
|
||||||
val valueCount = controlFlow.outputValues.size
|
val valueCount = controlFlow.outputValues.size
|
||||||
|
|
||||||
val weakMatches = HashMap(match.weakMatches)
|
val weakMatches = HashMap(match.weakMatches)
|
||||||
@@ -234,7 +234,7 @@ fun ExtractableCodeDescriptor.findDuplicates(): List<DuplicateInfo> {
|
|||||||
|
|
||||||
controlFlow?.let {
|
controlFlow?.let {
|
||||||
DuplicateInfo(range, it, unifierParameters.map { param ->
|
DuplicateInfo(range, it, unifierParameters.map { param ->
|
||||||
match.substitution[param]!!.text!!
|
match.substitution.getValue(param).text!!
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -254,14 +254,13 @@ private fun makeCall(
|
|||||||
) {
|
) {
|
||||||
fun insertCall(anchor: PsiElement, wrappedCall: KtExpression): KtExpression? {
|
fun insertCall(anchor: PsiElement, wrappedCall: KtExpression): KtExpression? {
|
||||||
val firstExpression = rangeToReplace.elements.firstOrNull { it is KtExpression } as? KtExpression
|
val firstExpression = rangeToReplace.elements.firstOrNull { it is KtExpression } as? KtExpression
|
||||||
if (firstExpression?.isLambdaOutsideParentheses() ?: false) {
|
if (firstExpression?.isLambdaOutsideParentheses() == true) {
|
||||||
val functionLiteralArgument = firstExpression?.getStrictParentOfType<KtLambdaArgument>()!!
|
val functionLiteralArgument = firstExpression.getStrictParentOfType<KtLambdaArgument>()!!
|
||||||
return functionLiteralArgument.moveInsideParenthesesAndReplaceWith(wrappedCall, extractableDescriptor.originalContext)
|
return functionLiteralArgument.moveInsideParenthesesAndReplaceWith(wrappedCall, extractableDescriptor.originalContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anchor is KtOperationReferenceExpression) {
|
if (anchor is KtOperationReferenceExpression) {
|
||||||
val operationExpression = anchor.parent as? KtOperationExpression ?: return null
|
val newNameExpression = when (val operationExpression = anchor.parent as? KtOperationExpression ?: return null) {
|
||||||
val newNameExpression = when (operationExpression) {
|
|
||||||
is KtUnaryExpression -> OperatorToFunctionIntention.convert(operationExpression).second
|
is KtUnaryExpression -> OperatorToFunctionIntention.convert(operationExpression).second
|
||||||
is KtBinaryExpression -> {
|
is KtBinaryExpression -> {
|
||||||
InfixCallToOrdinaryIntention.convert(operationExpression).getCalleeExpressionIfAny()
|
InfixCallToOrdinaryIntention.convert(operationExpression).getCalleeExpressionIfAny()
|
||||||
@@ -353,7 +352,7 @@ private fun makeCall(
|
|||||||
|
|
||||||
fun wrapCall(outputValue: OutputValue, callText: String): List<PsiElement> {
|
fun wrapCall(outputValue: OutputValue, callText: String): List<PsiElement> {
|
||||||
return when (outputValue) {
|
return when (outputValue) {
|
||||||
is OutputValue.ExpressionValue -> {
|
is ExpressionValue -> {
|
||||||
val exprText = if (outputValue.callSiteReturn) {
|
val exprText = if (outputValue.callSiteReturn) {
|
||||||
val firstReturn = outputValue.originalExpressions.asSequence().filterIsInstance<KtReturnExpression>().firstOrNull()
|
val firstReturn = outputValue.originalExpressions.asSequence().filterIsInstance<KtReturnExpression>().firstOrNull()
|
||||||
val label = firstReturn?.getTargetLabel()?.text ?: ""
|
val label = firstReturn?.getTargetLabel()?.text ?: ""
|
||||||
@@ -397,7 +396,7 @@ private fun makeCall(
|
|||||||
|
|
||||||
controlFlow.outputValues
|
controlFlow.outputValues
|
||||||
.filter { it != defaultValue }
|
.filter { it != defaultValue }
|
||||||
.flatMap { wrapCall(it, unboxingExpressions[it]!!) }
|
.flatMap { wrapCall(it, unboxingExpressions.getValue(it)) }
|
||||||
.withIndex()
|
.withIndex()
|
||||||
.forEach {
|
.forEach {
|
||||||
val (i, e) = it
|
val (i, e) = it
|
||||||
@@ -412,7 +411,7 @@ private fun makeCall(
|
|||||||
if (!inlinableCall) {
|
if (!inlinableCall) {
|
||||||
block.addBefore(newLine, anchorInBlock)
|
block.addBefore(newLine, anchorInBlock)
|
||||||
}
|
}
|
||||||
insertCall(anchor, wrapCall(it, unboxingExpressions[it]!!).first() as KtExpression)?.removeTemplateEntryBracesIfPossible()
|
insertCall(anchor, wrapCall(it, unboxingExpressions.getValue(it)).first() as KtExpression)?.removeTemplateEntryBracesIfPossible()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (anchor.isValid) {
|
if (anchor.isValid) {
|
||||||
@@ -533,7 +532,7 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
}
|
}
|
||||||
val originalRef = resolveResult.originalRefExpr
|
val originalRef = resolveResult.originalRefExpr
|
||||||
val newRef = descriptor.replacementMap[originalRef]
|
val newRef = descriptor.replacementMap[originalRef]
|
||||||
.fold(currentRef as KtElement) { currentRef, replacement -> replacement(descriptor, currentRef) }
|
.fold(currentRef as KtElement) { ref, replacement -> replacement(descriptor, ref) }
|
||||||
(newRef as? KtSimpleNameExpression)?.resolveResult = resolveResult
|
(newRef as? KtSimpleNameExpression)?.resolveResult = resolveResult
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -608,7 +607,7 @@ fun ExtractionGeneratorConfiguration.generateDeclaration(
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
(targetContainer.addAfter(declaration, anchor) as KtNamedDeclaration).apply {
|
(targetContainer.addAfter(declaration, anchor) as KtNamedDeclaration).apply {
|
||||||
if (!(targetContainer is KtClassBody && (targetContainer.parent as? KtClass)?.isEnum() ?: false)) {
|
if (!(targetContainer is KtClassBody && (targetContainer.parent as? KtClass)?.isEnum() == true)) {
|
||||||
targetContainer.addAfter(emptyLines, anchor)
|
targetContainer.addAfter(emptyLines, anchor)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+7
-9
@@ -40,7 +40,7 @@ import org.jetbrains.kotlin.psi.KtProperty
|
|||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
class KotlinIntroducePropertyHandler(
|
class KotlinIntroducePropertyHandler(
|
||||||
val helper: ExtractionEngineHelper = KotlinIntroducePropertyHandler.InteractiveExtractionHelper
|
val helper: ExtractionEngineHelper = InteractiveExtractionHelper
|
||||||
) : RefactoringActionHandler {
|
) : RefactoringActionHandler {
|
||||||
object InteractiveExtractionHelper : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
object InteractiveExtractionHelper : ExtractionEngineHelper(INTRODUCE_PROPERTY) {
|
||||||
private fun getExtractionTarget(descriptor: ExtractableCodeDescriptor) =
|
private fun getExtractionTarget(descriptor: ExtractableCodeDescriptor) =
|
||||||
@@ -60,8 +60,7 @@ class KotlinIntroducePropertyHandler(
|
|||||||
if (target != null) {
|
if (target != null) {
|
||||||
val options = ExtractionGeneratorOptions.DEFAULT.copy(target = target, delayInitialOccurrenceReplacement = true)
|
val options = ExtractionGeneratorOptions.DEFAULT.copy(target = target, delayInitialOccurrenceReplacement = true)
|
||||||
doRefactor(ExtractionGeneratorConfiguration(descriptor, options), onFinish)
|
doRefactor(ExtractionGeneratorConfiguration(descriptor, options), onFinish)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
showErrorHint(project, editor, "Can't introduce property for this expression", INTRODUCE_PROPERTY)
|
showErrorHint(project, editor, "Can't introduce property for this expression", INTRODUCE_PROPERTY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -76,7 +75,8 @@ class KotlinIntroducePropertyHandler(
|
|||||||
listOf(CodeInsightUtils.ElementKind.EXPRESSION),
|
listOf(CodeInsightUtils.ElementKind.EXPRESSION),
|
||||||
::validateExpressionElements,
|
::validateExpressionElements,
|
||||||
{ _, parent ->
|
{ _, parent ->
|
||||||
parent.getExtractionContainers(strict = true, includeAll = true).filter { it is KtClassBody || (it is KtFile && !it.isScript()) }
|
parent.getExtractionContainers(strict = true, includeAll = true)
|
||||||
|
.filter { it is KtClassBody || (it is KtFile && !it.isScript()) }
|
||||||
},
|
},
|
||||||
continuation
|
continuation
|
||||||
)
|
)
|
||||||
@@ -107,16 +107,14 @@ class KotlinIntroducePropertyHandler(
|
|||||||
doNotChangeVar = false,
|
doNotChangeVar = false,
|
||||||
exprType = descriptor.returnType,
|
exprType = descriptor.returnType,
|
||||||
extractionResult = it,
|
extractionResult = it,
|
||||||
availableTargets = propertyTargets.filter { it.isAvailable(descriptor) }
|
availableTargets = propertyTargets.filter { target -> target.isAvailable(descriptor) }
|
||||||
)
|
)
|
||||||
introducer.performInplaceRefactoring(LinkedHashSet(descriptor.suggestedNames))
|
introducer.performInplaceRefactoring(LinkedHashSet(descriptor.suggestedNames))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
processDuplicatesSilently(it.duplicateReplacers, project)
|
processDuplicatesSilently(it.duplicateReplacers, project)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
showErrorHintByKey(project, editor, "cannot.refactor.no.expression", INTRODUCE_PROPERTY)
|
showErrorHintByKey(project, editor, "cannot.refactor.no.expression", INTRODUCE_PROPERTY)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+20
-25
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.idea.util.psi.patternMatching.UnifierParameter
|
|||||||
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||||
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
import org.jetbrains.kotlin.incremental.components.NoLookupLocation
|
||||||
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
import org.jetbrains.kotlin.lexer.KtModifierKeywordToken
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
|
||||||
import org.jetbrains.kotlin.lexer.KtTokens.*
|
import org.jetbrains.kotlin.lexer.KtTokens.*
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.psi.*
|
import org.jetbrains.kotlin.psi.*
|
||||||
@@ -63,8 +62,10 @@ fun IntroduceTypeAliasData.analyze(): IntroduceTypeAliasAnalysisResult {
|
|||||||
|
|
||||||
val dummyVar = psiFactory.createProperty("val a: Int").apply {
|
val dummyVar = psiFactory.createProperty("val a: Int").apply {
|
||||||
typeReference!!.replace(
|
typeReference!!.replace(
|
||||||
originalTypeElement.parent as? KtTypeReference ?:
|
originalTypeElement.parent as? KtTypeReference ?: if (originalTypeElement is KtTypeElement) psiFactory.createType(
|
||||||
if (originalTypeElement is KtTypeElement) psiFactory.createType(originalTypeElement) else psiFactory.createType(originalTypeElement.text))
|
originalTypeElement
|
||||||
|
) else psiFactory.createType(originalTypeElement.text)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
val newTypeReference = dummyVar.typeReference!!
|
val newTypeReference = dummyVar.typeReference!!
|
||||||
val newReferences = newTypeReference.collectDescendantsOfType<KtTypeReference> { it.resolveInfo != null }
|
val newReferences = newTypeReference.collectDescendantsOfType<KtTypeReference> { it.resolveInfo != null }
|
||||||
@@ -90,8 +91,7 @@ fun IntroduceTypeAliasData.analyze(): IntroduceTypeAliasAnalysisResult {
|
|||||||
.firstOrNull { unifier.unify(it.reference, resolveInfo.reference).matched }
|
.firstOrNull { unifier.unify(it.reference, resolveInfo.reference).matched }
|
||||||
if (equivalenceRepresentative != null) {
|
if (equivalenceRepresentative != null) {
|
||||||
groupedReferencesToExtract.putValue(equivalenceRepresentative, resolveInfo)
|
groupedReferencesToExtract.putValue(equivalenceRepresentative, resolveInfo)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
groupedReferencesToExtract.putValue(resolveInfo, resolveInfo)
|
groupedReferencesToExtract.putValue(resolveInfo, resolveInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -109,7 +109,7 @@ fun IntroduceTypeAliasData.analyze(): IntroduceTypeAliasAnalysisResult {
|
|||||||
val typeParameterNames = KotlinNameSuggester.suggestNamesForTypeParameters(brokenReferences.size, typeParameterNameValidator)
|
val typeParameterNames = KotlinNameSuggester.suggestNamesForTypeParameters(brokenReferences.size, typeParameterNameValidator)
|
||||||
val typeParameters = (typeParameterNames zip brokenReferences).map { TypeParameter(it.first, groupedReferencesToExtract[it.second]) }
|
val typeParameters = (typeParameterNames zip brokenReferences).map { TypeParameter(it.first, groupedReferencesToExtract[it.second]) }
|
||||||
|
|
||||||
if (typeParameters.any { it.typeReferenceInfos.any { it.reference.typeElement == originalTypeElement } }) {
|
if (typeParameters.any { it.typeReferenceInfos.any { info -> info.reference.typeElement == originalTypeElement } }) {
|
||||||
return IntroduceTypeAliasAnalysisResult.Error("Type alias cannot refer to types which aren't accessible in the scope where it's defined")
|
return IntroduceTypeAliasAnalysisResult.Error("Type alias cannot refer to types which aren't accessible in the scope where it's defined")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -122,14 +122,11 @@ fun IntroduceTypeAliasData.analyze(): IntroduceTypeAliasAnalysisResult {
|
|||||||
return IntroduceTypeAliasAnalysisResult.Success(descriptor.copy(name = initialName))
|
return IntroduceTypeAliasAnalysisResult.Success(descriptor.copy(name = initialName))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun IntroduceTypeAliasData.getApplicableVisibilities(): List<KtModifierKeywordToken>{
|
fun IntroduceTypeAliasData.getApplicableVisibilities(): List<KtModifierKeywordToken> = when (targetSibling.parent) {
|
||||||
val parent = targetSibling.parent
|
|
||||||
return when (parent) {
|
|
||||||
is KtClassBody -> listOf(PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD)
|
is KtClassBody -> listOf(PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD)
|
||||||
is KtFile -> listOf(PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD)
|
is KtFile -> listOf(PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD)
|
||||||
else -> emptyList()
|
else -> emptyList()
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fun IntroduceTypeAliasDescriptor.validate(): IntroduceTypeAliasDescriptorWithConflicts {
|
fun IntroduceTypeAliasDescriptor.validate(): IntroduceTypeAliasDescriptorWithConflicts {
|
||||||
val conflicts = MultiMap<PsiElement, String>()
|
val conflicts = MultiMap<PsiElement, String>()
|
||||||
@@ -188,9 +185,11 @@ fun findDuplicates(typeAlias: KtTypeAlias): Map<KotlinPsiRange, () -> Unit> {
|
|||||||
val typeArgumentList = callExpression.typeArgumentList
|
val typeArgumentList = callExpression.typeArgumentList
|
||||||
if (arguments.isNotEmpty()) {
|
if (arguments.isNotEmpty()) {
|
||||||
val newTypeArgumentList = psiFactory.createTypeArguments(typeArgumentsText)
|
val newTypeArgumentList = psiFactory.createTypeArguments(typeArgumentsText)
|
||||||
typeArgumentList?.replace(newTypeArgumentList) ?: callExpression.addAfter(newTypeArgumentList, callExpression.calleeExpression)
|
typeArgumentList?.replace(newTypeArgumentList) ?: callExpression.addAfter(
|
||||||
}
|
newTypeArgumentList,
|
||||||
else {
|
callExpression.calleeExpression
|
||||||
|
)
|
||||||
|
} else {
|
||||||
typeArgumentList?.delete()
|
typeArgumentList?.delete()
|
||||||
}
|
}
|
||||||
callExpression.calleeExpression?.replace(psiFactory.createExpression(aliasName))
|
callExpression.calleeExpression?.replace(psiFactory.createExpression(aliasName))
|
||||||
@@ -217,19 +216,18 @@ fun findDuplicates(typeAlias: KtTypeAlias): Map<KotlinPsiRange, () -> Unit> {
|
|||||||
if (callElement != null) {
|
if (callElement != null) {
|
||||||
occurrence = callElement
|
occurrence = callElement
|
||||||
arguments = callElement.typeArguments.mapNotNull { it.typeReference?.typeElement }
|
arguments = callElement.typeArguments.mapNotNull { it.typeReference?.typeElement }
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val userType = element.getParentOfTypeAndBranch<KtUserType> { referenceExpression }
|
val userType = element.getParentOfTypeAndBranch<KtUserType> { referenceExpression }
|
||||||
if (userType != null) {
|
if (userType != null) {
|
||||||
occurrence = userType
|
occurrence = userType
|
||||||
arguments = userType.typeArgumentsAsTypes.mapNotNull { it.typeElement }
|
arguments = userType.typeArgumentsAsTypes.mapNotNull { it.typeElement }
|
||||||
}
|
} else continue
|
||||||
else continue
|
|
||||||
}
|
}
|
||||||
if (arguments.size != typeAliasDescriptor.declaredTypeParameters.size) continue
|
if (arguments.size != typeAliasDescriptor.declaredTypeParameters.size) continue
|
||||||
if (TypeUtils.isNullableType(typeAliasDescriptor.underlyingType)
|
if (TypeUtils.isNullableType(typeAliasDescriptor.underlyingType)
|
||||||
&& occurrence is KtUserType
|
&& occurrence is KtUserType
|
||||||
&& occurrence.parent !is KtNullableType) continue
|
&& occurrence.parent !is KtNullableType
|
||||||
|
) continue
|
||||||
rangesWithReplacers += occurrence.toRange() to { replaceOccurrence(occurrence, arguments) }
|
rangesWithReplacers += occurrence.toRange() to { replaceOccurrence(occurrence, arguments) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -263,11 +261,10 @@ fun IntroduceTypeAliasDescriptor.generateTypeAlias(previewOnly: Boolean = false)
|
|||||||
val typeParameterNames = typeParameters.map { it.name }
|
val typeParameterNames = typeParameters.map { it.name }
|
||||||
val typeAlias = if (originalElement is KtTypeElement) {
|
val typeAlias = if (originalElement is KtTypeElement) {
|
||||||
psiFactory.createTypeAlias(name, typeParameterNames, originalElement)
|
psiFactory.createTypeAlias(name, typeParameterNames, originalElement)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
psiFactory.createTypeAlias(name, typeParameterNames, originalElement.text)
|
psiFactory.createTypeAlias(name, typeParameterNames, originalElement.text)
|
||||||
}
|
}
|
||||||
if (visibility != null && visibility != KtTokens.DEFAULT_VISIBILITY_KEYWORD) {
|
if (visibility != null && visibility != DEFAULT_VISIBILITY_KEYWORD) {
|
||||||
typeAlias.addModifier(visibility)
|
typeAlias.addModifier(visibility)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,8 +276,7 @@ fun IntroduceTypeAliasDescriptor.generateTypeAlias(previewOnly: Boolean = false)
|
|||||||
fun replaceUsage() {
|
fun replaceUsage() {
|
||||||
val aliasInstanceText = if (typeParameters.isNotEmpty()) {
|
val aliasInstanceText = if (typeParameters.isNotEmpty()) {
|
||||||
"$name<${typeParameters.joinToString { it.typeReferenceInfos.first().reference.text }}>"
|
"$name<${typeParameters.joinToString { it.typeReferenceInfos.first().reference.text }}>"
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
name
|
name
|
||||||
}
|
}
|
||||||
when (originalElement) {
|
when (originalElement) {
|
||||||
@@ -300,8 +296,7 @@ fun IntroduceTypeAliasDescriptor.generateTypeAlias(previewOnly: Boolean = false)
|
|||||||
return if (previewOnly) {
|
return if (previewOnly) {
|
||||||
introduceTypeParameters()
|
introduceTypeParameters()
|
||||||
typeAlias
|
typeAlias
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
replaceUsage()
|
replaceUsage()
|
||||||
introduceTypeParameters()
|
introduceTypeParameters()
|
||||||
insertDeclaration(typeAlias, originalData.targetSibling)
|
insertDeclaration(typeAlias, originalData.targetSibling)
|
||||||
|
|||||||
+1
-1
@@ -66,7 +66,7 @@ class KotlinMemberSelectionTable(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun getOverrideIcon(memberInfo: KotlinMemberInfo): Icon? {
|
override fun getOverrideIcon(memberInfo: KotlinMemberInfo): Icon? {
|
||||||
val defaultIcon = AbstractMemberSelectionTable.EMPTY_OVERRIDE_ICON
|
val defaultIcon = EMPTY_OVERRIDE_ICON
|
||||||
|
|
||||||
val member = memberInfo.member
|
val member = memberInfo.member
|
||||||
if (member !is KtNamedFunction && member !is KtProperty && member !is KtParameter) return defaultIcon
|
if (member !is KtNamedFunction && member !is KtProperty && member !is KtParameter) return defaultIcon
|
||||||
|
|||||||
+11
-15
@@ -30,7 +30,6 @@ import org.jetbrains.jps.model.java.JavaSourceRootType
|
|||||||
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
import org.jetbrains.jps.model.module.JpsModuleSourceRootType
|
||||||
import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot
|
import org.jetbrains.jps.model.module.JpsTypedModuleSourceRoot
|
||||||
import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer
|
import org.jetbrains.jps.model.serialization.facet.JpsFacetSerializer
|
||||||
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer
|
|
||||||
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer.*
|
import org.jetbrains.jps.model.serialization.module.JpsModuleRootModelSerializer.*
|
||||||
import org.jetbrains.kotlin.analyzer.common.CommonPlatform
|
import org.jetbrains.kotlin.analyzer.common.CommonPlatform
|
||||||
import org.jetbrains.kotlin.config.getFacetPlatformByConfigurationElement
|
import org.jetbrains.kotlin.config.getFacetPlatformByConfigurationElement
|
||||||
@@ -74,7 +73,7 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
val moduleSettingsImpl = moduleSettings as? ModuleSettingsImpl ?: return VirtualFile.EMPTY_ARRAY
|
val moduleSettingsImpl = moduleSettings as? ModuleSettingsImpl ?: return VirtualFile.EMPTY_ARRAY
|
||||||
return contextImpl
|
return contextImpl
|
||||||
.getClassRoots(element, moduleSettingsImpl)
|
.getClassRoots(element, moduleSettingsImpl)
|
||||||
.mapNotNull { it.toVirtualFile()?.let { JarFileSystem.getInstance().getJarRootForLocalFile(it) } }
|
.mapNotNull { it.toVirtualFile()?.let { file -> JarFileSystem.getInstance().getJarRootForLocalFile(file) } }
|
||||||
.toTypedArray()
|
.toTypedArray()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -83,7 +82,7 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
override val explicitKind: PersistentLibraryKind<*>?
|
override val explicitKind: PersistentLibraryKind<*>?
|
||||||
get() = (library as? LibraryEx)?.kind
|
get() = (library as? LibraryEx)?.kind
|
||||||
|
|
||||||
override fun getRoots() = library.getFiles(OrderRootType.CLASSES)
|
override fun getRoots(): Array<VirtualFile> = library.getFiles(OrderRootType.CLASSES)
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract val explicitKind: PersistentLibraryKind<*>?
|
abstract val explicitKind: PersistentLibraryKind<*>?
|
||||||
@@ -109,16 +108,14 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
private fun findProjectLibrary(name: String) = projectLibrariesByName[name]?.firstOrNull()
|
private fun findProjectLibrary(name: String) = projectLibrariesByName[name]?.firstOrNull()
|
||||||
|
|
||||||
private fun createLibInfo(orderEntryElement: Element, moduleSettings: ModuleSettings): LibInfo? {
|
private fun createLibInfo(orderEntryElement: Element, moduleSettings: ModuleSettings): LibInfo? {
|
||||||
val entryType = orderEntryElement.getAttributeValue(ORDER_ENTRY_TYPE_ATTR)
|
return when (orderEntryElement.getAttributeValue(ORDER_ENTRY_TYPE_ATTR)) {
|
||||||
return when (entryType) {
|
MODULE_LIBRARY_TYPE -> {
|
||||||
JpsModuleRootModelSerializer.MODULE_LIBRARY_TYPE -> {
|
|
||||||
orderEntryElement.getChild(LIBRARY_TAG)?.let { LibInfo.ByXml(it, context, moduleSettings) }
|
orderEntryElement.getChild(LIBRARY_TAG)?.let { LibInfo.ByXml(it, context, moduleSettings) }
|
||||||
}
|
}
|
||||||
|
|
||||||
JpsModuleRootModelSerializer.LIBRARY_TYPE -> {
|
LIBRARY_TYPE -> {
|
||||||
val libraryName = orderEntryElement.getAttributeValue(NAME_ATTRIBUTE) ?: return null
|
val libraryName = orderEntryElement.getAttributeValue(NAME_ATTRIBUTE) ?: return null
|
||||||
val level = orderEntryElement.getAttributeValue(LEVEL_ATTRIBUTE)
|
when (orderEntryElement.getAttributeValue(LEVEL_ATTRIBUTE)) {
|
||||||
when (level) {
|
|
||||||
LibraryTablesRegistrar.PROJECT_LEVEL ->
|
LibraryTablesRegistrar.PROJECT_LEVEL ->
|
||||||
findProjectLibrary(libraryName)?.let { LibInfo.ByXml(it, context, moduleSettings) }
|
findProjectLibrary(libraryName)?.let { LibInfo.ByXml(it, context, moduleSettings) }
|
||||||
LibraryTablesRegistrar.APPLICATION_LEVEL ->
|
LibraryTablesRegistrar.APPLICATION_LEVEL ->
|
||||||
@@ -147,8 +144,7 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
.asSequence()
|
.asSequence()
|
||||||
.mapNotNull { createLibInfo(it, this) }
|
.mapNotNull { createLibInfo(it, this) }
|
||||||
.forEach {
|
.forEach {
|
||||||
val platform = it.platform
|
when (val platform = it.platform) {
|
||||||
when (platform) {
|
|
||||||
is CommonPlatform -> {
|
is CommonPlatform -> {
|
||||||
if (!hasCommonStdlib && it.isStdlib) {
|
if (!hasCommonStdlib && it.isStdlib) {
|
||||||
hasCommonStdlib = true
|
hasCommonStdlib = true
|
||||||
@@ -189,7 +185,7 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
if (settings.isExternalModule()) return false
|
if (settings.isExternalModule()) return false
|
||||||
|
|
||||||
val hasMigrationRoots = settings.getSourceFolderElements().any {
|
val hasMigrationRoots = settings.getSourceFolderElements().any {
|
||||||
JpsModuleRootModelSerializer.loadSourceRoot(it).rootType in rootTypesToMigrate
|
loadSourceRoot(it).rootType in rootTypesToMigrate
|
||||||
}
|
}
|
||||||
if (!hasMigrationRoots) {
|
if (!hasMigrationRoots) {
|
||||||
return false
|
return false
|
||||||
@@ -202,8 +198,8 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
override fun process(settings: ModuleSettings) {
|
override fun process(settings: ModuleSettings) {
|
||||||
for (sourceFolder in settings.getSourceFolderElements()) {
|
for (sourceFolder in settings.getSourceFolderElements()) {
|
||||||
val contentRoot = sourceFolder.parent as? Element ?: continue
|
val contentRoot = sourceFolder.parent as? Element ?: continue
|
||||||
val oldSourceRoot = JpsModuleRootModelSerializer.loadSourceRoot(sourceFolder)
|
val oldSourceRoot = loadSourceRoot(sourceFolder)
|
||||||
val url = sourceFolder.getAttributeValue(JpsModuleRootModelSerializer.URL_ATTRIBUTE)
|
val url = sourceFolder.getAttributeValue(URL_ATTRIBUTE)
|
||||||
|
|
||||||
val (newRootType, data) = oldSourceRoot.getMigratedSourceRootTypeWithProperties() ?: continue
|
val (newRootType, data) = oldSourceRoot.getMigratedSourceRootTypeWithProperties() ?: continue
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -211,7 +207,7 @@ class KotlinNonJvmSourceRootConverterProvider : ConverterProvider("kotlin-non-jv
|
|||||||
as? JpsTypedModuleSourceRoot<JpsElement> ?: continue
|
as? JpsTypedModuleSourceRoot<JpsElement> ?: continue
|
||||||
|
|
||||||
contentRoot.removeContent(sourceFolder)
|
contentRoot.removeContent(sourceFolder)
|
||||||
JpsModuleRootModelSerializer.saveSourceRoot(contentRoot, url, newSourceRoot)
|
saveSourceRoot(contentRoot, url, newSourceRoot)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,9 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.*
|
|||||||
import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ReturnValueInstruction
|
import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ReturnValueInstruction
|
||||||
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder
|
||||||
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.traverse
|
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.traverse
|
||||||
import org.jetbrains.kotlin.descriptors.*
|
import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
|
||||||
|
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
|
||||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||||
import org.jetbrains.kotlin.idea.caches.resolve.*
|
import org.jetbrains.kotlin.idea.caches.resolve.*
|
||||||
import org.jetbrains.kotlin.idea.core.isOverridable
|
import org.jetbrains.kotlin.idea.core.isOverridable
|
||||||
@@ -114,7 +116,8 @@ private fun KtDeclaration.processVariableAccesses(
|
|||||||
{
|
{
|
||||||
KotlinPropertyFindUsagesOptions(project).apply {
|
KotlinPropertyFindUsagesOptions(project).apply {
|
||||||
isReadAccess = kind == AccessKind.READ_ONLY || kind == AccessKind.READ_OR_WRITE
|
isReadAccess = kind == AccessKind.READ_ONLY || kind == AccessKind.READ_OR_WRITE
|
||||||
isWriteAccess = kind == AccessKind.WRITE_ONLY || kind == AccessKind.WRITE_WITH_OPTIONAL_READ || kind == AccessKind.READ_OR_WRITE
|
isWriteAccess =
|
||||||
|
kind == AccessKind.WRITE_ONLY || kind == AccessKind.WRITE_WITH_OPTIONAL_READ || kind == AccessKind.READ_OR_WRITE
|
||||||
isReadWriteAccess = kind == AccessKind.WRITE_WITH_OPTIONAL_READ || kind == AccessKind.READ_OR_WRITE
|
isReadWriteAccess = kind == AccessKind.WRITE_WITH_OPTIONAL_READ || kind == AccessKind.READ_OR_WRITE
|
||||||
isSearchForTextOccurrences = false
|
isSearchForTextOccurrences = false
|
||||||
isSkipImportStatements = true
|
isSkipImportStatements = true
|
||||||
@@ -138,7 +141,8 @@ abstract class Slicer(
|
|||||||
operator fun get(element: KtElement): Pseudocode? {
|
operator fun get(element: KtElement): Pseudocode? {
|
||||||
val container = element.containingDeclarationForPseudocode ?: return null
|
val container = element.containingDeclarationForPseudocode ?: return null
|
||||||
return computedPseudocodes.getOrPut(container) {
|
return computedPseudocodes.getOrPut(container) {
|
||||||
container.getContainingPseudocode(container.analyzeWithContent())?.apply { computedPseudocodes[container] = this } ?: return null
|
container.getContainingPseudocode(container.analyzeWithContent())?.apply { computedPseudocodes[container] = this }
|
||||||
|
?: return null
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -176,8 +180,7 @@ class InflowSlicer(
|
|||||||
val (accessKind, accessExpression) = refElement.readWriteAccessWithFullExpression(true)
|
val (accessKind, accessExpression) = refElement.readWriteAccessWithFullExpression(true)
|
||||||
if (accessKind == ReferenceAccess.WRITE && accessExpression is KtBinaryExpression && accessExpression.operationToken == KtTokens.EQ) {
|
if (accessKind == ReferenceAccess.WRITE && accessExpression is KtBinaryExpression && accessExpression.operationToken == KtTokens.EQ) {
|
||||||
accessExpression.right
|
accessExpression.right
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
accessExpression
|
accessExpression
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -193,7 +196,7 @@ class InflowSlicer(
|
|||||||
private fun KtPropertyAccessor.processBackingFieldAssignments() {
|
private fun KtPropertyAccessor.processBackingFieldAssignments() {
|
||||||
forEachDescendantOfType<KtBinaryExpression> body@{
|
forEachDescendantOfType<KtBinaryExpression> body@{
|
||||||
if (it.operationToken != KtTokens.EQ) return@body
|
if (it.operationToken != KtTokens.EQ) return@body
|
||||||
val lhs = it.left?.let { KtPsiUtil.safeDeparenthesize(it) } ?: return@body
|
val lhs = it.left?.let { expression -> KtPsiUtil.safeDeparenthesize(expression) } ?: return@body
|
||||||
val rhs = it.right ?: return@body
|
val rhs = it.right ?: return@body
|
||||||
if (!lhs.isBackingFieldReference()) return@body
|
if (!lhs.isBackingFieldReference()) return@body
|
||||||
rhs.passToProcessor()
|
rhs.passToProcessor()
|
||||||
@@ -229,8 +232,7 @@ class InflowSlicer(
|
|||||||
if (isDefaultGetter) {
|
if (isDefaultGetter) {
|
||||||
if (isDefaultSetter) {
|
if (isDefaultSetter) {
|
||||||
processPropertyAssignments()
|
processPropertyAssignments()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
setter!!.processBackingFieldAssignments()
|
setter!!.processBackingFieldAssignments()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -249,12 +251,13 @@ class InflowSlicer(
|
|||||||
|
|
||||||
if (function is KtNamedFunction
|
if (function is KtNamedFunction
|
||||||
&& function.name == OperatorNameConventions.SET_VALUE.asString()
|
&& function.name == OperatorNameConventions.SET_VALUE.asString()
|
||||||
&& function.hasModifier(KtTokens.OPERATOR_KEYWORD)) {
|
&& function.hasModifier(KtTokens.OPERATOR_KEYWORD)
|
||||||
|
) {
|
||||||
|
|
||||||
ReferencesSearch
|
ReferencesSearch
|
||||||
.search(function, parentUsage.scope.toSearchScope())
|
.search(function, parentUsage.scope.toSearchScope())
|
||||||
.filterIsInstance<KtPropertyDelegationMethodsReference>()
|
.filterIsInstance<KtPropertyDelegationMethodsReference>()
|
||||||
.forEach { (it.element?.parent as? KtProperty)?.processPropertyAssignments() }
|
.forEach { (it.element.parent as? KtProperty)?.processPropertyAssignments() }
|
||||||
}
|
}
|
||||||
|
|
||||||
val parameterDescriptor = resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) ?: return
|
val parameterDescriptor = resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) ?: return
|
||||||
@@ -267,8 +270,7 @@ class InflowSlicer(
|
|||||||
refElement is KtExpression -> {
|
refElement is KtExpression -> {
|
||||||
val callElement = refElement.getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return@body
|
val callElement = refElement.getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return@body
|
||||||
val resolvedCall = callElement.resolveToCall() ?: return@body
|
val resolvedCall = callElement.resolveToCall() ?: return@body
|
||||||
val resolvedArgument = resolvedCall.valueArguments[parameterDescriptor] ?: return@body
|
when (val resolvedArgument = resolvedCall.valueArguments[parameterDescriptor] ?: return@body) {
|
||||||
when (resolvedArgument) {
|
|
||||||
is DefaultValueArgument -> defaultValue
|
is DefaultValueArgument -> defaultValue
|
||||||
is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression()
|
is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression()
|
||||||
else -> null
|
else -> null
|
||||||
@@ -326,8 +328,7 @@ class InflowSlicer(
|
|||||||
|
|
||||||
val pseudocode = pseudocodeCache[this] ?: return
|
val pseudocode = pseudocodeCache[this] ?: return
|
||||||
val expressionValue = pseudocode.getElementValue(this) ?: return
|
val expressionValue = pseudocode.getElementValue(this) ?: return
|
||||||
val createdAt = expressionValue.createdAt
|
when (val createdAt = expressionValue.createdAt) {
|
||||||
when (createdAt) {
|
|
||||||
is ReadValueInstruction -> {
|
is ReadValueInstruction -> {
|
||||||
if (createdAt.target == AccessTarget.BlackBox) {
|
if (createdAt.target == AccessTarget.BlackBox) {
|
||||||
val originalElement = expressionValue.element as? KtExpression ?: return
|
val originalElement = expressionValue.element as? KtExpression ?: return
|
||||||
@@ -340,10 +341,9 @@ class InflowSlicer(
|
|||||||
val accessedDeclaration = accessedDescriptor.source.getPsi() ?: return
|
val accessedDeclaration = accessedDescriptor.source.getPsi() ?: return
|
||||||
if (accessedDescriptor is SyntheticFieldDescriptor) {
|
if (accessedDescriptor is SyntheticFieldDescriptor) {
|
||||||
val property = accessedDeclaration as? KtProperty ?: return
|
val property = accessedDeclaration as? KtProperty ?: return
|
||||||
if (accessedDescriptor.propertyDescriptor.setter?.isDefault ?: true) {
|
if (accessedDescriptor.propertyDescriptor.setter?.isDefault != false) {
|
||||||
property.processPropertyAssignments()
|
property.processPropertyAssignments()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
property.setter?.processBackingFieldAssignments()
|
property.setter?.processBackingFieldAssignments()
|
||||||
}
|
}
|
||||||
return
|
return
|
||||||
@@ -369,8 +369,7 @@ class InflowSlicer(
|
|||||||
val resultingDescriptor = resolvedCall.resultingDescriptor
|
val resultingDescriptor = resolvedCall.resultingDescriptor
|
||||||
if (resultingDescriptor is FunctionInvokeDescriptor) {
|
if (resultingDescriptor is FunctionInvokeDescriptor) {
|
||||||
(resolvedCall.dispatchReceiver as? ExpressionReceiver)?.expression?.passToProcessorAsValue(parentUsage.lambdaLevel + 1)
|
(resolvedCall.dispatchReceiver as? ExpressionReceiver)?.expression?.passToProcessorAsValue(parentUsage.lambdaLevel + 1)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
resultingDescriptor.source.getPsi()?.processHierarchyDownwardAndPass()
|
resultingDescriptor.source.getPsi()?.processHierarchyDownwardAndPass()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -442,22 +441,19 @@ class OutflowSlicer(
|
|||||||
processHierarchyUpward(parentUsage.scope) {
|
processHierarchyUpward(parentUsage.scope) {
|
||||||
if (this is KtFunction) {
|
if (this is KtFunction) {
|
||||||
processCalls(parentUsage.scope.toSearchScope()) {
|
processCalls(parentUsage.scope.toSearchScope()) {
|
||||||
val refElement = it.element
|
when (val refElement = it.element) {
|
||||||
when {
|
null -> (it.reference as? LightMemberReference)?.element?.passToProcessor()
|
||||||
refElement == null -> (it.reference as? LightMemberReference)?.element?.passToProcessor()
|
is KtExpression -> {
|
||||||
refElement is KtExpression -> {
|
|
||||||
refElement.getCallElementForExactCallee()?.passToProcessor()
|
refElement.getCallElementForExactCallee()?.passToProcessor()
|
||||||
refElement.getCallableReferenceForExactCallee()?.passToProcessor(parentUsage.lambdaLevel + 1)
|
refElement.getCallableReferenceForExactCallee()?.passToProcessor(parentUsage.lambdaLevel + 1)
|
||||||
}
|
}
|
||||||
else -> refElement.passToProcessor()
|
else -> refElement.passToProcessor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
} else if (this is PsiMethod && language == JavaLanguage.INSTANCE) {
|
||||||
else if (this is PsiMethod && language == JavaLanguage.INSTANCE) {
|
|
||||||
// todo: work around the bug in JavaSliceProvider.transform()
|
// todo: work around the bug in JavaSliceProvider.transform()
|
||||||
processor.process(JavaSliceUsage.createRootUsage(this, parentUsage.params))
|
processor.process(JavaSliceUsage.createRootUsage(this, parentUsage.params))
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
passToProcessor()
|
passToProcessor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -513,15 +509,15 @@ class OutflowSlicer(
|
|||||||
is CallInstruction -> {
|
is CallInstruction -> {
|
||||||
if (parentUsage.lambdaLevel > 0 && instr.receiverValues[pseudoValue] != null) {
|
if (parentUsage.lambdaLevel > 0 && instr.receiverValues[pseudoValue] != null) {
|
||||||
instr.element.passToProcessor(parentUsage.lambdaLevel - 1)
|
instr.element.passToProcessor(parentUsage.lambdaLevel - 1)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
instr.arguments[pseudoValue]?.source?.getPsi()?.passToProcessor()
|
instr.arguments[pseudoValue]?.source?.getPsi()?.passToProcessor()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
is ReturnValueInstruction -> instr.subroutine.passToProcessor()
|
is ReturnValueInstruction -> instr.subroutine.passToProcessor()
|
||||||
is MagicInstruction -> when (instr.kind) {
|
is MagicInstruction -> when (instr.kind) {
|
||||||
MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> instr.outputValue.element?.passToProcessor()
|
MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> instr.outputValue.element?.passToProcessor()
|
||||||
else -> { }
|
else -> {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtNamedDeclaration
|
|||||||
|
|
||||||
return TextRange(
|
return TextRange(
|
||||||
element.startOffset,
|
element.startOffset,
|
||||||
element.getSuperTypeList()?.startOffset ?: element.getBody()?.startOffset ?: element.endOffset
|
element.getSuperTypeList()?.startOffset ?: element.body?.startOffset ?: element.endOffset
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,18 +114,20 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtNamedDeclaration
|
|||||||
val srcModule = ModuleUtilCore.findModuleForPsiElement(element) ?: return
|
val srcModule = ModuleUtilCore.findModuleForPsiElement(element) ?: return
|
||||||
val propertiesComponent = PropertiesComponent.getInstance()
|
val propertiesComponent = PropertiesComponent.getInstance()
|
||||||
val testFolders = HashSet<VirtualFile>()
|
val testFolders = HashSet<VirtualFile>()
|
||||||
CreateTestAction.checkForTestRoots(srcModule, testFolders)
|
checkForTestRoots(srcModule, testFolders)
|
||||||
if (testFolders.isEmpty() && !propertiesComponent.getBoolean("create.test.in.the.same.root")) {
|
if (testFolders.isEmpty() && !propertiesComponent.getBoolean("create.test.in.the.same.root")) {
|
||||||
if (Messages.showOkCancelDialog(
|
if (Messages.showOkCancelDialog(
|
||||||
project,
|
project,
|
||||||
"Create test in the same source root?",
|
"Create test in the same source root?",
|
||||||
"No Test Roots Found",
|
"No Test Roots Found",
|
||||||
Messages.getQuestionIcon()) != Messages.OK) return
|
Messages.getQuestionIcon()
|
||||||
|
) != Messages.OK
|
||||||
|
) return
|
||||||
|
|
||||||
propertiesComponent.setValue("create.test.in.the.same.root", true)
|
propertiesComponent.setValue("create.test.in.the.same.root", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
val srcClass = CreateTestAction.getContainingClass(element) ?: return
|
val srcClass = getContainingClass(element) ?: return
|
||||||
|
|
||||||
val srcDir = element.containingFile.containingDirectory
|
val srcDir = element.containingFile.containingDirectory
|
||||||
val srcPackage = JavaDirectoryService.getInstance().getPackage(srcDir)
|
val srcPackage = JavaDirectoryService.getInstance().getPackage(srcDir)
|
||||||
@@ -163,7 +165,7 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtNamedDeclaration
|
|||||||
if (generatedClass.language == JavaLanguage.INSTANCE) {
|
if (generatedClass.language == JavaLanguage.INSTANCE) {
|
||||||
project.executeCommand("Convert class '${generatedClass.name}' to Kotlin", this) {
|
project.executeCommand("Convert class '${generatedClass.name}' to Kotlin", this) {
|
||||||
runWriteAction {
|
runWriteAction {
|
||||||
generatedClass.methods.forEach { it.throwsList.referenceElements.forEach { it.delete() } }
|
generatedClass.methods.forEach { it.throwsList.referenceElements.forEach { referenceElement -> referenceElement.delete() } }
|
||||||
}
|
}
|
||||||
|
|
||||||
if (existingClass != null) {
|
if (existingClass != null) {
|
||||||
@@ -176,12 +178,11 @@ class KotlinCreateTestIntention : SelfTargetingRangeIntention<KtNamedDeclaration
|
|||||||
generatedClass
|
generatedClass
|
||||||
.methods
|
.methods
|
||||||
.filter { it.name !in existingMethodNames }
|
.filter { it.name !in existingMethodNames }
|
||||||
.forEach { it.j2k()?.let { existingClass.addDeclaration(it) } }
|
.forEach { it.j2k()?.let { declaration -> existingClass.addDeclaration(declaration) } }
|
||||||
generatedClass.delete()
|
generatedClass.delete()
|
||||||
}
|
}
|
||||||
NavigationUtil.activateFileWithPsiElement(existingClass)
|
NavigationUtil.activateFileWithPsiElement(existingClass)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
with(PsiDocumentManager.getInstance(project)) {
|
with(PsiDocumentManager.getInstance(project)) {
|
||||||
getDocument(generatedFile)?.let { doPostponedOperationsAndUnblockDocument(it) }
|
getDocument(generatedFile)?.let { doPostponedOperationsAndUnblockDocument(it) }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ import com.intellij.openapi.fileTypes.StdFileTypes
|
|||||||
import com.intellij.util.indexing.DataIndexer
|
import com.intellij.util.indexing.DataIndexer
|
||||||
import com.intellij.util.indexing.FileBasedIndex
|
import com.intellij.util.indexing.FileBasedIndex
|
||||||
import com.intellij.util.indexing.FileContent
|
import com.intellij.util.indexing.FileContent
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
|
||||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
|
import org.jetbrains.kotlin.load.java.JvmAnnotationNames.*
|
||||||
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
import org.jetbrains.kotlin.load.kotlin.header.KotlinClassHeader
|
||||||
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
import org.jetbrains.kotlin.metadata.jvm.deserialization.JvmMetadataVersion
|
||||||
@@ -76,7 +75,7 @@ object KotlinJvmMetadataVersionIndex : KotlinMetadataVersionIndexBase<KotlinJvmM
|
|||||||
kind = KotlinClassHeader.Kind.getById(value)
|
kind = KotlinClassHeader.Kind.getById(value)
|
||||||
}
|
}
|
||||||
METADATA_EXTRA_INT_FIELD_NAME -> if (value is Int) {
|
METADATA_EXTRA_INT_FIELD_NAME -> if (value is Int) {
|
||||||
isStrictSemantics = (value and JvmAnnotationNames.METADATA_STRICT_VERSION_SEMANTICS_FLAG) != 0
|
isStrictSemantics = (value and METADATA_STRICT_VERSION_SEMANTICS_FLAG) != 0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user