Misc: Cleanup "org.jetbrains.kotlin.idea.intentions" package
This commit is contained in:
@@ -21,47 +21,47 @@ import com.intellij.psi.PsiWhiteSpace
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class AddBracesIntention : SelfTargetingIntention<KtExpression>(javaClass(), "Add braces") {
|
||||
public class AddBracesIntention : SelfTargetingIntention<KtExpression>(KtExpression::class.java, "Add braces") {
|
||||
override fun isApplicableTo(element: KtExpression, caretOffset: Int): Boolean {
|
||||
val expression = element.getTargetExpression(caretOffset) ?: return false
|
||||
if (expression is KtBlockExpression) return false
|
||||
|
||||
val description = (expression.getParent() as KtContainerNode).description()!!
|
||||
setText("Add braces to '$description' statement")
|
||||
val description = (expression.parent as KtContainerNode).description()!!
|
||||
text = "Add braces to '$description' statement"
|
||||
return true
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtExpression, editor: Editor) {
|
||||
val expression = element.getTargetExpression(editor.getCaretModel().getOffset())!!
|
||||
val expression = element.getTargetExpression(editor.caretModel.offset)!!
|
||||
|
||||
if (element.getNextSibling()?.getText() == ";") {
|
||||
element.getNextSibling()!!.delete()
|
||||
if (element.nextSibling?.text == ";") {
|
||||
element.nextSibling!!.delete()
|
||||
}
|
||||
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
expression.replace(psiFactory.createSingleStatementBlock(expression))
|
||||
|
||||
if (element is KtDoWhileExpression) { // remove new line between '}' and while
|
||||
(element.getBody()!!.getParent().getNextSibling() as? PsiWhiteSpace)?.delete()
|
||||
(element.body!!.parent.nextSibling as? PsiWhiteSpace)?.delete()
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtExpression.getTargetExpression(caretLocation: Int): KtExpression? {
|
||||
when (this) {
|
||||
is KtIfExpression -> {
|
||||
val thenExpr = getThen() ?: return null
|
||||
val elseExpr = getElse()
|
||||
if (elseExpr != null && caretLocation >= getElseKeyword()!!.startOffset) {
|
||||
val thenExpr = then ?: return null
|
||||
val elseExpr = `else`
|
||||
if (elseExpr != null && caretLocation >= elseKeyword!!.startOffset) {
|
||||
return elseExpr
|
||||
}
|
||||
return thenExpr
|
||||
}
|
||||
|
||||
is KtWhileExpression -> return getBody()
|
||||
is KtWhileExpression -> return body
|
||||
|
||||
is KtDoWhileExpression -> return getBody()
|
||||
is KtDoWhileExpression -> return body
|
||||
|
||||
is KtForExpression -> return getBody()
|
||||
is KtForExpression -> return body
|
||||
|
||||
else -> return null
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class AddForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(javaClass(), "Add indices to 'for' loop"), LowPriorityAction {
|
||||
public class AddForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(KtForExpression::class.java, "Add indices to 'for' loop"), LowPriorityAction {
|
||||
private val WITH_INDEX_NAME = "withIndex"
|
||||
private val WITH_INDEX_FQ_NAMES = listOf("collections", "sequences", "text", "ranges").map { "kotlin.$it.$WITH_INDEX_NAME" }.toSet()
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import org.jetbrains.kotlin.idea.conversion.copy.end
|
||||
import org.jetbrains.kotlin.idea.conversion.copy.start
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatchStatus
|
||||
@@ -32,16 +31,16 @@ import org.jetbrains.kotlin.resolve.calls.model.VarargValueArgument
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class AddNameToArgumentIntention
|
||||
: SelfTargetingIntention<KtValueArgument>(javaClass(), "Add name to argument"), LowPriorityAction {
|
||||
: SelfTargetingIntention<KtValueArgument>(KtValueArgument::class.java, "Add name to argument"), LowPriorityAction {
|
||||
|
||||
override fun isApplicableTo(element: KtValueArgument, caretOffset: Int): Boolean {
|
||||
val expression = element.getArgumentExpression() ?: return false
|
||||
val name = detectNameToAdd(element) ?: return false
|
||||
|
||||
setText("Add '$name =' to argument")
|
||||
text = "Add '$name =' to argument"
|
||||
|
||||
if (expression is KtLambdaExpression) {
|
||||
val range = expression.getTextRange()
|
||||
val range = expression.textRange
|
||||
return caretOffset == range.start || caretOffset == range.end
|
||||
}
|
||||
|
||||
@@ -61,21 +60,21 @@ public class AddNameToArgumentIntention
|
||||
if (argument.isNamed()) return null
|
||||
if (argument is KtLambdaArgument) return null
|
||||
|
||||
val argumentList = argument.getParent() as? KtValueArgumentList ?: return null
|
||||
val argumentList = argument.parent as? KtValueArgumentList ?: return null
|
||||
if (argument != argumentList.arguments.last { !it.isNamed() }) return null
|
||||
|
||||
val callExpr = argumentList.getParent() as? KtExpression ?: return null
|
||||
val callExpr = argumentList.parent as? KtExpression ?: return null
|
||||
val resolvedCall = callExpr.getResolvedCall(callExpr.analyze(BodyResolveMode.PARTIAL)) ?: return null
|
||||
val argumentMatch = resolvedCall.getArgumentMapping(argument) as? ArgumentMatch ?: return null
|
||||
if (argumentMatch.status != ArgumentMatchStatus.SUCCESS) return null
|
||||
|
||||
if (!resolvedCall.getResultingDescriptor().hasStableParameterNames()) return null
|
||||
if (!resolvedCall.resultingDescriptor.hasStableParameterNames()) return null
|
||||
|
||||
if (argumentMatch.valueParameter.varargElementType != null) {
|
||||
val varargArgument = resolvedCall.getValueArguments()[argumentMatch.valueParameter] as? VarargValueArgument ?: return null
|
||||
if (varargArgument.getArguments().size() != 1) return null
|
||||
val varargArgument = resolvedCall.valueArguments[argumentMatch.valueParameter] as? VarargValueArgument ?: return null
|
||||
if (varargArgument.arguments.size != 1) return null
|
||||
}
|
||||
|
||||
return argumentMatch.valueParameter.getName()
|
||||
return argumentMatch.valueParameter.name
|
||||
}
|
||||
}
|
||||
@@ -21,14 +21,13 @@ import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.inspections.RedundantSamConstructorInspection
|
||||
import org.jetbrains.kotlin.idea.util.CommentSaver
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contentRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch
|
||||
import org.jetbrains.kotlin.psi.psiUtil.parents
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getCalleeExpressionIfAny
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
class AnonymousFunctionToLambdaIntention : SelfTargetingRangeIntention<KtNamedFunction>(
|
||||
KtNamedFunction::class.java,
|
||||
|
||||
+22
-22
@@ -32,39 +32,39 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
public open class ChangeVisibilityModifierIntention protected constructor(
|
||||
val modifier: KtModifierKeywordToken
|
||||
) : SelfTargetingRangeIntention<KtDeclaration>(javaClass(), "Make ${modifier.getValue()}") {
|
||||
) : SelfTargetingRangeIntention<KtDeclaration>(KtDeclaration::class.java, "Make ${modifier.value}") {
|
||||
|
||||
override fun applicabilityRange(element: KtDeclaration): TextRange? {
|
||||
val modifierList = element.getModifierList()
|
||||
val modifierList = element.modifierList
|
||||
if (modifierList?.hasModifier(modifier) ?: false) return null
|
||||
|
||||
var descriptor = element.toDescriptor() as? DeclarationDescriptorWithVisibility ?: return null
|
||||
val targetVisibility = modifier.toVisibility()
|
||||
if (descriptor.getVisibility() == targetVisibility) return null
|
||||
if (descriptor.visibility == targetVisibility) return null
|
||||
|
||||
if (modifierList?.hasModifier(KtTokens.OVERRIDE_KEYWORD) ?: false) {
|
||||
val callableDescriptor = descriptor as? CallableDescriptor ?: return null
|
||||
// cannot make visibility less than (or non-comparable with) any of the supers
|
||||
if (callableDescriptor.getOverriddenDescriptors()
|
||||
.map { Visibilities.compare(it.getVisibility(), targetVisibility) }
|
||||
if (callableDescriptor.overriddenDescriptors
|
||||
.map { Visibilities.compare(it.visibility, targetVisibility) }
|
||||
.any { it == null || it > 0 }) return null
|
||||
}
|
||||
|
||||
setText(defaultText)
|
||||
text = defaultText
|
||||
|
||||
val modifierElement = element.visibilityModifier()
|
||||
if (modifierElement != null) {
|
||||
return modifierElement.getTextRange()
|
||||
return modifierElement.textRange
|
||||
}
|
||||
|
||||
val defaultRange = noModifierYetApplicabilityRange(element) ?: return null
|
||||
|
||||
if (element is KtPrimaryConstructor && defaultRange.isEmpty()) {
|
||||
setText("Make primary constructor ${modifier.getValue()}") // otherwise it may be confusing
|
||||
if (element is KtPrimaryConstructor && defaultRange.isEmpty) {
|
||||
text = "Make primary constructor ${modifier.value}" // otherwise it may be confusing
|
||||
}
|
||||
|
||||
return if (modifierList != null)
|
||||
TextRange(modifierList.startOffset, defaultRange.getEndOffset()) //TODO: smaller range? now it includes annotations too
|
||||
TextRange(modifierList.startOffset, defaultRange.endOffset) //TODO: smaller range? now it includes annotations too
|
||||
else
|
||||
defaultRange
|
||||
}
|
||||
@@ -73,7 +73,7 @@ public open class ChangeVisibilityModifierIntention protected constructor(
|
||||
val bindingContext = analyze()
|
||||
// TODO: temporary code
|
||||
if (this is KtPrimaryConstructor) {
|
||||
return (this.getContainingClassOrObject().resolveToDescriptor() as ClassDescriptor).getUnsubstitutedPrimaryConstructor()
|
||||
return (this.getContainingClassOrObject().resolveToDescriptor() as ClassDescriptor).unsubstitutedPrimaryConstructor
|
||||
}
|
||||
|
||||
val descriptor = bindingContext[BindingContext.DECLARATION_TO_DESCRIPTOR, this]
|
||||
@@ -100,13 +100,13 @@ public open class ChangeVisibilityModifierIntention protected constructor(
|
||||
private fun noModifierYetApplicabilityRange(declaration: KtDeclaration): TextRange? {
|
||||
if (KtPsiUtil.isLocal(declaration)) return null
|
||||
return when (declaration) {
|
||||
is KtNamedFunction -> declaration.getFunKeyword()?.getTextRange()
|
||||
is KtProperty -> declaration.getValOrVarKeyword().getTextRange()
|
||||
is KtClass -> declaration.getClassOrInterfaceKeyword()?.getTextRange()
|
||||
is KtObjectDeclaration -> declaration.getObjectKeyword().getTextRange()
|
||||
is KtPrimaryConstructor -> declaration.getValueParameterList()?.let { TextRange.from(it.startOffset, 0) } //TODO: use constructor keyword if exist
|
||||
is KtSecondaryConstructor -> declaration.getConstructorKeyword().getTextRange()
|
||||
is KtParameter -> declaration.getValOrVarKeyword()?.getTextRange()
|
||||
is KtNamedFunction -> declaration.funKeyword?.textRange
|
||||
is KtProperty -> declaration.valOrVarKeyword.textRange
|
||||
is KtClass -> declaration.getClassOrInterfaceKeyword()?.textRange
|
||||
is KtObjectDeclaration -> declaration.getObjectKeyword().textRange
|
||||
is KtPrimaryConstructor -> declaration.valueParameterList?.let { TextRange.from(it.startOffset, 0) } //TODO: use constructor keyword if exist
|
||||
is KtSecondaryConstructor -> declaration.getConstructorKeyword().textRange
|
||||
is KtParameter -> declaration.valOrVarKeyword?.textRange
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
@@ -115,11 +115,11 @@ public open class ChangeVisibilityModifierIntention protected constructor(
|
||||
|
||||
public class Private : ChangeVisibilityModifierIntention(KtTokens.PRIVATE_KEYWORD), HighPriorityAction {
|
||||
override fun applicabilityRange(element: KtDeclaration): TextRange? {
|
||||
return if (canBePrivate(element)) super<ChangeVisibilityModifierIntention>.applicabilityRange(element) else null
|
||||
return if (canBePrivate(element)) super.applicabilityRange(element) else null
|
||||
}
|
||||
|
||||
private fun canBePrivate(declaration: KtDeclaration): Boolean {
|
||||
if (declaration.getModifierList()?.hasModifier(KtTokens.ABSTRACT_KEYWORD) ?: false) return false
|
||||
if (declaration.modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) ?: false) return false
|
||||
return true
|
||||
}
|
||||
}
|
||||
@@ -130,9 +130,9 @@ public open class ChangeVisibilityModifierIntention protected constructor(
|
||||
}
|
||||
|
||||
private fun canBeProtected(declaration: KtDeclaration): Boolean {
|
||||
var parent = declaration.getParent()
|
||||
var parent = declaration.parent
|
||||
if (parent is KtClassBody) {
|
||||
parent = parent.getParent()
|
||||
parent = parent.parent
|
||||
}
|
||||
return parent is KtClass
|
||||
}
|
||||
|
||||
@@ -16,18 +16,12 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.codeInsight.completion.InsertHandler
|
||||
import com.intellij.codeInsight.completion.InsertionContext
|
||||
import com.intellij.codeInsight.lookup.LookupElement
|
||||
import com.intellij.codeInsight.lookup.LookupElementBuilder
|
||||
import com.intellij.codeInsight.template.Expression
|
||||
import com.intellij.codeInsight.template.ExpressionContext
|
||||
import com.intellij.codeInsight.template.Result
|
||||
import com.intellij.codeInsight.template.TextResult
|
||||
import com.intellij.codeInsight.template.impl.TemplateManagerImpl
|
||||
import com.intellij.codeInsight.template.impl.TemplateState
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil
|
||||
|
||||
//TODO: move it somewhere else and reuse
|
||||
@@ -41,21 +35,20 @@ public abstract class ChooseValueExpression<T : Any>(
|
||||
protected abstract fun getResult(element: T): String
|
||||
|
||||
protected val lookupItems: Array<LookupElement> = lookupItems.map { suggestion ->
|
||||
LookupElementBuilder.create(suggestion, getLookupString(suggestion)).withInsertHandler(object : InsertHandler<LookupElement> {
|
||||
override fun handleInsert(context: InsertionContext, item: LookupElement) {
|
||||
val topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(context.getEditor())
|
||||
val templateState = TemplateManagerImpl.getTemplateState(topLevelEditor)
|
||||
if (templateState != null) {
|
||||
val range = templateState.getCurrentVariableRange()
|
||||
if (range != null) {
|
||||
topLevelEditor.getDocument().replaceString(range.getStartOffset(), range.getEndOffset(), getResult(item.getObject() as T))
|
||||
}
|
||||
LookupElementBuilder.create(suggestion, getLookupString(suggestion)).withInsertHandler { context, item ->
|
||||
val topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(context.editor)
|
||||
val templateState = TemplateManagerImpl.getTemplateState(topLevelEditor)
|
||||
if (templateState != null) {
|
||||
val range = templateState.currentVariableRange
|
||||
if (range != null) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
topLevelEditor.document.replaceString(range.startOffset, range.endOffset, getResult(item.`object` as T))
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}.toTypedArray()
|
||||
|
||||
override fun calculateLookupItems(context: ExpressionContext) = if (lookupItems.size() > 1) lookupItems else null
|
||||
override fun calculateLookupItems(context: ExpressionContext) = if (lookupItems.size > 1) lookupItems else null
|
||||
|
||||
override fun calculateQuickResult(context: ExpressionContext) = calculateResult(context)
|
||||
|
||||
|
||||
+23
-23
@@ -30,24 +30,24 @@ import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCallExpression>(javaClass(), "Replace 'assert' with 'if' statement"), LowPriorityAction {
|
||||
public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCallExpression>(KtCallExpression::class.java, "Replace 'assert' with 'if' statement"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtCallExpression, caretOffset: Int): Boolean {
|
||||
val callee = element.getCalleeExpression() ?: return false
|
||||
if (!callee.getTextRange().containsOffset(caretOffset)) return false
|
||||
val callee = element.calleeExpression ?: return false
|
||||
if (!callee.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
val argumentSize = element.getValueArguments().size()
|
||||
val argumentSize = element.valueArguments.size
|
||||
if (argumentSize !in 1..2) return false
|
||||
val functionLiterals = element.getLambdaArguments()
|
||||
if (functionLiterals.size() > 1) return false
|
||||
if (functionLiterals.size() == 1 && argumentSize == 1) return false // "assert {...}" is incorrect
|
||||
val functionLiterals = element.lambdaArguments
|
||||
if (functionLiterals.size > 1) return false
|
||||
if (functionLiterals.size == 1 && argumentSize == 1) return false // "assert {...}" is incorrect
|
||||
|
||||
val resolvedCall = element.getResolvedCall(element.analyze()) ?: return false
|
||||
return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).asString() == "kotlin.assert"
|
||||
return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).asString() == "kotlin.assert"
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtCallExpression, editor: Editor) {
|
||||
val args = element.getValueArguments()
|
||||
val conditionText = args[0]?.getArgumentExpression()?.getText() ?: return
|
||||
val args = element.valueArguments
|
||||
val conditionText = args[0]?.getArgumentExpression()?.text ?: return
|
||||
val functionLiteralArgument = element.lambdaArguments.singleOrNull()
|
||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
@@ -66,29 +66,29 @@ public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCall
|
||||
val ifExpression = replaceWithIfThenThrowExpression(element)
|
||||
|
||||
// shorten java.lang.AssertionError
|
||||
ShortenReferences.DEFAULT.process(ifExpression.getThen()!!)
|
||||
ShortenReferences.DEFAULT.process(ifExpression.then!!)
|
||||
|
||||
val ifCondition = ifExpression.getCondition() as KtPrefixExpression
|
||||
ifCondition.getBaseExpression()!!.replace(psiFactory.createExpression(conditionText))
|
||||
val ifCondition = ifExpression.condition as KtPrefixExpression
|
||||
ifCondition.baseExpression!!.replace(psiFactory.createExpression(conditionText))
|
||||
|
||||
val thrownExpression = ((ifExpression.getThen() as KtBlockExpression).getStatements().single() as KtThrowExpression).getThrownExpression()
|
||||
val thrownExpression = ((ifExpression.then as KtBlockExpression).statements.single() as KtThrowExpression).thrownExpression
|
||||
val assertionErrorCall = if (thrownExpression is KtCallExpression)
|
||||
thrownExpression
|
||||
else
|
||||
(thrownExpression as KtDotQualifiedExpression).getSelectorExpression() as KtCallExpression
|
||||
(thrownExpression as KtDotQualifiedExpression).selectorExpression as KtCallExpression
|
||||
|
||||
val message = psiFactory.createExpression(
|
||||
if (messageIsFunction && messageExpr is KtCallableReferenceExpression) {
|
||||
messageExpr.getCallableReference().getText() + "()"
|
||||
messageExpr.callableReference.text + "()"
|
||||
}
|
||||
else if (messageIsFunction) {
|
||||
messageExpr.getText() + "()"
|
||||
messageExpr.text + "()"
|
||||
}
|
||||
else {
|
||||
messageExpr.getText()
|
||||
messageExpr.text
|
||||
}
|
||||
)
|
||||
assertionErrorCall.getValueArguments().single().getArgumentExpression()!!.replace(message)
|
||||
assertionErrorCall.valueArguments.single().getArgumentExpression()!!.replace(message)
|
||||
|
||||
simplifyConditionIfPossible(ifExpression)
|
||||
}
|
||||
@@ -101,12 +101,12 @@ public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCall
|
||||
|
||||
private fun messageIsFunction(callExpr: KtCallExpression, bindingContext: BindingContext): Boolean {
|
||||
val resolvedCall = callExpr.getResolvedCall(bindingContext) ?: return false
|
||||
val valParameters = resolvedCall.getResultingDescriptor().getValueParameters()
|
||||
return valParameters.size() > 1 && !KotlinBuiltIns.isAny(valParameters[1].type)
|
||||
val valParameters = resolvedCall.resultingDescriptor.valueParameters
|
||||
return valParameters.size > 1 && !KotlinBuiltIns.isAny(valParameters[1].type)
|
||||
}
|
||||
|
||||
private fun simplifyConditionIfPossible(ifExpression: KtIfExpression) {
|
||||
val condition = ifExpression.getCondition() as KtPrefixExpression
|
||||
val condition = ifExpression.condition as KtPrefixExpression
|
||||
val simplifier = SimplifyNegatedBinaryExpressionIntention()
|
||||
if (simplifier.isApplicableTo(condition)) {
|
||||
simplifier.applyTo(condition)
|
||||
@@ -115,7 +115,7 @@ public class ConvertAssertToIfWithThrowIntention : SelfTargetingIntention<KtCall
|
||||
|
||||
private fun replaceWithIfThenThrowExpression(original: KtCallExpression): KtIfExpression {
|
||||
val replacement = KtPsiFactory(original).createExpression("if (!true) { throw java.lang.AssertionError(\"\") }") as KtIfExpression
|
||||
val parent = original.getParent()
|
||||
val parent = original.parent
|
||||
return if (parent is KtDotQualifiedExpression)
|
||||
parent.replaced(replacement)
|
||||
else
|
||||
|
||||
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.scopes.receivers.ExpressionReceiver
|
||||
|
||||
public class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIntention<KtSimpleNameExpression>(javaClass(), "Replace with a 'for' loop") {
|
||||
public class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIntention<KtSimpleNameExpression>(KtSimpleNameExpression::class.java, "Replace with a 'for' loop") {
|
||||
private val FOR_EACH_NAME = "forEach"
|
||||
private val FOR_EACH_FQ_NAMES = listOf("collections", "sequences", "text", "ranges").map { "kotlin.$it.$FOR_EACH_NAME" }.toSet()
|
||||
|
||||
@@ -33,8 +33,8 @@ public class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIn
|
||||
if (element.getReferencedName() != FOR_EACH_NAME) return false
|
||||
|
||||
val data = extractData(element) ?: return false
|
||||
if (data.functionLiteral.getValueParameters().size() > 1) return false
|
||||
if (data.functionLiteral.getBodyExpression() == null) return false
|
||||
if (data.functionLiteral.valueParameters.size > 1) return false
|
||||
if (data.functionLiteral.bodyExpression == null) return false
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -57,18 +57,18 @@ public class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIn
|
||||
)
|
||||
|
||||
private fun extractData(nameExpr: KtSimpleNameExpression): Data? {
|
||||
val parent = nameExpr.getParent()
|
||||
val parent = nameExpr.parent
|
||||
val expression = (when (parent) {
|
||||
is KtCallExpression -> parent.getParent() as? KtDotQualifiedExpression
|
||||
is KtCallExpression -> parent.parent as? KtDotQualifiedExpression
|
||||
is KtBinaryExpression -> parent
|
||||
else -> null
|
||||
} ?: return null) as KtExpression //TODO: submit bug
|
||||
|
||||
val resolvedCall = expression.getResolvedCall(expression.analyze()) ?: return null
|
||||
if (DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() !in FOR_EACH_FQ_NAMES) return null
|
||||
if (DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).toString() !in FOR_EACH_FQ_NAMES) return null
|
||||
|
||||
val receiver = resolvedCall.getCall().getExplicitReceiver() as? ExpressionReceiver ?: return null
|
||||
val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null
|
||||
val receiver = resolvedCall.call.explicitReceiver as? ExpressionReceiver ?: return null
|
||||
val argument = resolvedCall.call.valueArguments.singleOrNull() ?: return null
|
||||
val functionLiteral = argument.getArgumentExpression() as? KtLambdaExpression ?: return null
|
||||
return Data(expression, receiver.expression, functionLiteral)
|
||||
}
|
||||
@@ -76,8 +76,8 @@ public class ConvertForEachToForLoopIntention : SelfTargetingOffsetIndependentIn
|
||||
private fun generateLoop(functionLiteral: KtLambdaExpression, receiver: KtExpression): KtExpression {
|
||||
val factory = KtPsiFactory(functionLiteral)
|
||||
val loopRange = KtPsiUtil.safeDeparenthesize(receiver)
|
||||
val body = functionLiteral.getBodyExpression()!!
|
||||
val parameter = functionLiteral.getValueParameters().singleOrNull()
|
||||
val body = functionLiteral.bodyExpression!!
|
||||
val parameter = functionLiteral.valueParameters.singleOrNull()
|
||||
return factory.createExpressionByPattern("for($0 in $1){ $2 }", parameter ?: "it", loopRange, body)
|
||||
}
|
||||
}
|
||||
|
||||
+30
-30
@@ -56,13 +56,13 @@ import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
import org.jetbrains.kotlin.types.typeUtil.supertypes
|
||||
import java.util.*
|
||||
|
||||
public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamedFunction>(javaClass(), "Convert function to property"), LowPriorityAction {
|
||||
public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamedFunction>(KtNamedFunction::class.java, "Convert function to property"), LowPriorityAction {
|
||||
private var KtNamedFunction.typeFqNameToAdd: String? by UserDataProperty(Key.create("TYPE_FQ_NAME_TO_ADD"))
|
||||
|
||||
private inner class Converter(
|
||||
project: Project,
|
||||
descriptor: FunctionDescriptor
|
||||
): CallableRefactoring<FunctionDescriptor>(project, descriptor, getText()) {
|
||||
): CallableRefactoring<FunctionDescriptor>(project, descriptor, text) {
|
||||
private val elementsToShorten = ArrayList<KtElement>()
|
||||
|
||||
private val newName: String by lazy {
|
||||
@@ -75,31 +75,31 @@ public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamed
|
||||
|
||||
val propertySample = psiFactory.createProperty("val foo: Int get() = 1")
|
||||
|
||||
val needsExplicitType = function.getTypeReference() == null
|
||||
val needsExplicitType = function.typeReference == null
|
||||
if (needsExplicitType) {
|
||||
originalFunction.typeFqNameToAdd?.let { function.setTypeReference(psiFactory.createType(it)) }
|
||||
}
|
||||
|
||||
function.getFunKeyword()!!.replace(propertySample.getValOrVarKeyword())
|
||||
function.getValueParameterList()?.delete()
|
||||
val insertAfter = (function.getEqualsToken() ?: function.getBodyExpression())
|
||||
function.funKeyword!!.replace(propertySample.valOrVarKeyword)
|
||||
function.valueParameterList?.delete()
|
||||
val insertAfter = (function.equalsToken ?: function.bodyExpression)
|
||||
?.siblings(forward = false, withItself = false)
|
||||
?.firstOrNull { it !is PsiWhiteSpace }
|
||||
if (insertAfter != null) {
|
||||
function.addAfter(psiFactory.createParameterList("()"), insertAfter)
|
||||
function.addAfter(propertySample.getGetter()!!.getNamePlaceholder(), insertAfter)
|
||||
function.addAfter(propertySample.getter!!.namePlaceholder, insertAfter)
|
||||
}
|
||||
function.setName(newName)
|
||||
|
||||
val property = originalFunction.replace(psiFactory.createProperty(function.getText())) as KtProperty
|
||||
val property = originalFunction.replace(psiFactory.createProperty(function.text)) as KtProperty
|
||||
if (needsExplicitType) {
|
||||
elementsToShorten.add(property.getTypeReference()!!)
|
||||
elementsToShorten.add(property.typeReference!!)
|
||||
}
|
||||
}
|
||||
|
||||
override fun performRefactoring(descriptorsForChange: Collection<CallableDescriptor>) {
|
||||
val conflicts = MultiMap<PsiElement, String>()
|
||||
val getterName = JvmAbi.getterName(callableDescriptor.getName().asString())
|
||||
val getterName = JvmAbi.getterName(callableDescriptor.name.asString())
|
||||
val callables = getAffectedCallables(project, descriptorsForChange)
|
||||
val kotlinCalls = ArrayList<KtCallElement>()
|
||||
val kotlinRefsToRename = ArrayList<PsiReference>()
|
||||
@@ -112,13 +112,13 @@ public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamed
|
||||
}
|
||||
|
||||
if (callable is KtNamedFunction) {
|
||||
if (callable.getTypeReference() == null) {
|
||||
if (callable.typeReference == null) {
|
||||
val functionDescriptor = callable.resolveToDescriptor() as FunctionDescriptor
|
||||
val type = functionDescriptor.getReturnType()
|
||||
val type = functionDescriptor.returnType
|
||||
val typeToInsert = when {
|
||||
type == null || type.isError() -> null
|
||||
type.getConstructor().isDenotable() -> type
|
||||
else -> type.supertypes().firstOrNull { it.getConstructor().isDenotable() }
|
||||
type == null || type.isError -> null
|
||||
type.constructor.isDenotable -> type
|
||||
else -> type.supertypes().firstOrNull { it.constructor.isDenotable }
|
||||
} ?: functionDescriptor.builtIns.nullableAnyType
|
||||
callable.typeFqNameToAdd = IdeDescriptorRenderers.SOURCE_CODE.renderType(typeToInsert)
|
||||
}
|
||||
@@ -130,10 +130,10 @@ public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamed
|
||||
}
|
||||
|
||||
if (callable is PsiMethod) {
|
||||
callable.getContainingClass()
|
||||
callable.containingClass
|
||||
?.findMethodsByName(getterName, true)
|
||||
// as is necessary here: see KT-10386
|
||||
?.firstOrNull { it.getParameterList().getParametersCount() == 0 && it.namedUnwrappedElement as PsiElement? !in callables }
|
||||
?.firstOrNull { it.parameterList.parametersCount == 0 && !callables.contains(it.namedUnwrappedElement as PsiElement?) }
|
||||
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
|
||||
}
|
||||
|
||||
@@ -141,19 +141,19 @@ public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamed
|
||||
for (usage in usages) {
|
||||
if (usage is KtSimpleNameReference) {
|
||||
val expression = usage.expression
|
||||
val callElement = expression.getParentOfTypeAndBranch<KtCallElement> { getCalleeExpression() }
|
||||
val callElement = expression.getParentOfTypeAndBranch<KtCallElement> { calleeExpression }
|
||||
if (callElement != null && expression.getStrictParentOfType<KtCallableReferenceExpression>() == null) {
|
||||
if (callElement.getTypeArguments().isNotEmpty()) {
|
||||
if (callElement.typeArguments.isNotEmpty()) {
|
||||
conflicts.putValue(
|
||||
callElement,
|
||||
"Type arguments will be lost after conversion: ${StringUtil.htmlEmphasize(callElement.getText())}"
|
||||
"Type arguments will be lost after conversion: ${StringUtil.htmlEmphasize(callElement.text)}"
|
||||
)
|
||||
}
|
||||
|
||||
if (callElement.getValueArguments().isNotEmpty()) {
|
||||
if (callElement.valueArguments.isNotEmpty()) {
|
||||
conflicts.putValue(
|
||||
callElement,
|
||||
"Call with arguments will be skipped: ${StringUtil.htmlEmphasize(callElement.getText())}"
|
||||
"Call with arguments will be skipped: ${StringUtil.htmlEmphasize(callElement.text)}"
|
||||
)
|
||||
continue
|
||||
}
|
||||
@@ -171,7 +171,7 @@ public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamed
|
||||
}
|
||||
|
||||
project.checkConflictsInteractively(conflicts) {
|
||||
project.executeWriteCommand(getText()) {
|
||||
project.executeWriteCommand(text) {
|
||||
val psiFactory = KtPsiFactory(project)
|
||||
val newGetterName = JvmAbi.getterName(newName)
|
||||
val newRefExpr = psiFactory.createExpression(newName)
|
||||
@@ -195,25 +195,25 @@ public class ConvertFunctionToPropertyIntention : SelfTargetingIntention<KtNamed
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
override fun isApplicableTo(element: KtNamedFunction, caretOffset: Int): Boolean {
|
||||
val identifier = element.getNameIdentifier() ?: return false
|
||||
if (!identifier.getTextRange().containsOffset(caretOffset)) return false
|
||||
val identifier = element.nameIdentifier ?: return false
|
||||
if (!identifier.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
if (element.getValueParameters().isNotEmpty() || element.isLocal()) return false
|
||||
if (element.valueParameters.isNotEmpty() || element.isLocal) return false
|
||||
|
||||
val name = element.getName()!!
|
||||
if (name == "invoke" || name == "iterator" || Name.identifier(name) in OperatorConventions.UNARY_OPERATION_NAMES.inverse().keySet()) {
|
||||
val name = element.name!!
|
||||
if (name == "invoke" || name == "iterator" || Name.identifier(name) in OperatorConventions.UNARY_OPERATION_NAMES.inverse().keys) {
|
||||
return false
|
||||
}
|
||||
|
||||
val descriptor = element.analyze(BodyResolveMode.PARTIAL)[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? FunctionDescriptor
|
||||
?: return false
|
||||
val returnType = descriptor.getReturnType() ?: return false
|
||||
val returnType = descriptor.returnType ?: return false
|
||||
return !KotlinBuiltIns.isUnit(returnType) && !KotlinBuiltIns.isNothing(returnType)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtNamedFunction, editor: Editor) {
|
||||
val context = element.analyze(BodyResolveMode.PARTIAL)
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as FunctionDescriptor
|
||||
Converter(element.getProject(), descriptor).run()
|
||||
Converter(element.project, descriptor).run()
|
||||
}
|
||||
}
|
||||
|
||||
+19
-21
@@ -17,48 +17,46 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.unwrapBlockOrParenthesis
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.idea.core.copied
|
||||
import org.jetbrains.kotlin.idea.core.replaced
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isNullExpression
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.unwrapBlockOrParenthesis
|
||||
import org.jetbrains.kotlin.idea.util.ShortenReferences
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
|
||||
public class ConvertIfWithThrowToAssertIntention : SelfTargetingOffsetIndependentIntention<KtIfExpression>(javaClass(), "Replace 'if' with 'assert' statement") {
|
||||
|
||||
public class ConvertIfWithThrowToAssertIntention : SelfTargetingOffsetIndependentIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' with 'assert' statement") {
|
||||
override fun isApplicableTo(element: KtIfExpression): Boolean {
|
||||
if (element.getElse() != null) return false
|
||||
if (element.`else` != null) return false
|
||||
|
||||
val throwExpr = element.getThen()?.unwrapBlockOrParenthesis() as? KtThrowExpression
|
||||
val thrownExpr = getSelector(throwExpr?.getThrownExpression())
|
||||
val throwExpr = element.then?.unwrapBlockOrParenthesis() as? KtThrowExpression
|
||||
val thrownExpr = getSelector(throwExpr?.thrownExpression)
|
||||
if (thrownExpr !is KtCallExpression) return false
|
||||
|
||||
if (thrownExpr.getValueArguments().size() > 1) return false
|
||||
if (thrownExpr.valueArguments.size > 1) return false
|
||||
|
||||
val resolvedCall = thrownExpr.getResolvedCall(thrownExpr.analyze()) ?: return false
|
||||
return DescriptorUtils.getFqName(resolvedCall.getResultingDescriptor()).toString() == "java.lang.AssertionError.<init>"
|
||||
return DescriptorUtils.getFqName(resolvedCall.resultingDescriptor).toString() == "java.lang.AssertionError.<init>"
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
val condition = element.getCondition() ?: return
|
||||
val condition = element.condition ?: return
|
||||
|
||||
val thenExpr = element.getThen()?.unwrapBlockOrParenthesis() as KtThrowExpression
|
||||
val thrownExpr = getSelector(thenExpr.getThrownExpression()) as KtCallExpression
|
||||
val thenExpr = element.then?.unwrapBlockOrParenthesis() as KtThrowExpression
|
||||
val thrownExpr = getSelector(thenExpr.thrownExpression) as KtCallExpression
|
||||
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
condition.replace(psiFactory.createExpressionByPattern("!$0", condition))
|
||||
|
||||
var newCondition = element.getCondition()!!
|
||||
var newCondition = element.condition!!
|
||||
val simplifier = SimplifyNegatedBinaryExpressionIntention()
|
||||
if (simplifier.isApplicableTo(newCondition as KtPrefixExpression)) {
|
||||
simplifier.applyTo(newCondition, editor)
|
||||
newCondition = element.getCondition()!!
|
||||
newCondition = element.condition!!
|
||||
}
|
||||
|
||||
val arg = thrownExpr.getValueArguments().singleOrNull()?.getArgumentExpression()
|
||||
val arg = thrownExpr.valueArguments.singleOrNull()?.getArgumentExpression()
|
||||
val assertExpr = if (arg != null && !arg.isNullExpression())
|
||||
psiFactory.createExpressionByPattern("kotlin.assert($0) {$1}", newCondition, arg)
|
||||
else
|
||||
@@ -70,7 +68,7 @@ public class ConvertIfWithThrowToAssertIntention : SelfTargetingOffsetIndependen
|
||||
|
||||
private fun getSelector(element: KtExpression?): KtExpression? {
|
||||
if (element is KtDotQualifiedExpression) {
|
||||
return element.getSelectorExpression()
|
||||
return element.selectorExpression
|
||||
}
|
||||
return element
|
||||
}
|
||||
|
||||
+14
-16
@@ -17,32 +17,30 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.lexer.KtSingleValueToken
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.LinkedList
|
||||
|
||||
import java.util.*
|
||||
|
||||
public class ConvertNegatedBooleanSequenceIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(
|
||||
javaClass(), "Replace negated sequence with DeMorgan equivalent") {
|
||||
|
||||
KtBinaryExpression::class.java, "Replace negated sequence with DeMorgan equivalent"
|
||||
) {
|
||||
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
||||
if (element.getParent() is KtBinaryExpression) return false // operate only on the longest sequence
|
||||
val opToken = element.getOperationToken()
|
||||
if (element.parent is KtBinaryExpression) return false // operate only on the longest sequence
|
||||
val opToken = element.operationToken
|
||||
if (opToken != KtTokens.ANDAND && opToken != KtTokens.OROR) return false
|
||||
|
||||
return splitBooleanSequence(element) != null
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
val operatorText = when(element.getOperationToken()) {
|
||||
KtTokens.ANDAND -> KtTokens.OROR.getValue()
|
||||
KtTokens.OROR -> KtTokens.ANDAND.getValue()
|
||||
val operatorText = when(element.operationToken) {
|
||||
KtTokens.ANDAND -> KtTokens.OROR.value
|
||||
KtTokens.OROR -> KtTokens.ANDAND.value
|
||||
else -> throw IllegalArgumentException() // checked in isApplicableTo
|
||||
}
|
||||
|
||||
val elements = splitBooleanSequence(element)!!
|
||||
val bareExpressions = elements.map { prefixExpression -> prefixExpression.getBaseExpression()!!.getText() }
|
||||
val bareExpressions = elements.map { prefixExpression -> prefixExpression.baseExpression!!.text }
|
||||
val negatedExpression = bareExpressions.subList(0, bareExpressions.lastIndex).foldRight(
|
||||
"!(${bareExpressions.last()}", { negated, expression -> "$expression $operatorText $negated" }
|
||||
)
|
||||
@@ -50,7 +48,7 @@ public class ConvertNegatedBooleanSequenceIntention : SelfTargetingOffsetIndepen
|
||||
val newExpression = KtPsiFactory(element).createExpression("$negatedExpression)")
|
||||
|
||||
val insertedElement = element.replace(newExpression)
|
||||
val insertedElementParent = insertedElement.getParent() as? KtParenthesizedExpression ?: return
|
||||
val insertedElementParent = insertedElement.parent as? KtParenthesizedExpression ?: return
|
||||
|
||||
if (KtPsiUtil.areParenthesesUseless(insertedElementParent)) {
|
||||
insertedElementParent.replace(insertedElement)
|
||||
@@ -59,16 +57,16 @@ public class ConvertNegatedBooleanSequenceIntention : SelfTargetingOffsetIndepen
|
||||
|
||||
private fun splitBooleanSequence(expression: KtBinaryExpression): List<KtPrefixExpression>? {
|
||||
val itemList = LinkedList<KtPrefixExpression>()
|
||||
val firstOperator = expression.getOperationToken()
|
||||
val firstOperator = expression.operationToken
|
||||
|
||||
var currentItem: KtBinaryExpression? = expression
|
||||
while (currentItem != null) {
|
||||
if (currentItem.getOperationToken() != firstOperator) return null //Boolean sequence must be homogeneous
|
||||
if (currentItem.operationToken != firstOperator) return null //Boolean sequence must be homogeneous
|
||||
|
||||
val rightChild = currentItem.getRight() as? KtPrefixExpression ?: return null
|
||||
val rightChild = currentItem.right as? KtPrefixExpression ?: return null
|
||||
itemList.add(rightChild)
|
||||
|
||||
val leftChild = currentItem.getLeft()
|
||||
val leftChild = currentItem.left
|
||||
when (leftChild) {
|
||||
is KtPrefixExpression -> itemList.add(leftChild)
|
||||
!is KtBinaryExpression -> return null
|
||||
|
||||
+16
-17
@@ -21,18 +21,17 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.*
|
||||
|
||||
public class ConvertNegatedExpressionWithDemorgansLawIntention : SelfTargetingOffsetIndependentIntention<KtPrefixExpression>(javaClass(), "DeMorgan Law") {
|
||||
|
||||
public class ConvertNegatedExpressionWithDemorgansLawIntention : SelfTargetingOffsetIndependentIntention<KtPrefixExpression>(KtPrefixExpression::class.java, "DeMorgan Law") {
|
||||
override fun isApplicableTo(element: KtPrefixExpression): Boolean {
|
||||
val prefixOperator = element.getOperationReference().getReferencedNameElementType()
|
||||
val prefixOperator = element.operationReference.getReferencedNameElementType()
|
||||
if (prefixOperator != KtTokens.EXCL) return false
|
||||
|
||||
val parenthesizedExpression = element.getBaseExpression() as? KtParenthesizedExpression
|
||||
val baseExpression = parenthesizedExpression?.getExpression() as? KtBinaryExpression ?: return false
|
||||
val parenthesizedExpression = element.baseExpression as? KtParenthesizedExpression
|
||||
val baseExpression = parenthesizedExpression?.expression as? KtBinaryExpression ?: return false
|
||||
|
||||
when (baseExpression.getOperationToken()) {
|
||||
KtTokens.ANDAND -> setText("Replace '&&' with '||'")
|
||||
KtTokens.OROR -> setText("Replace '||' with '&&'")
|
||||
when (baseExpression.operationToken) {
|
||||
KtTokens.ANDAND -> text = "Replace '&&' with '||'"
|
||||
KtTokens.OROR -> text = "Replace '||' with '&&'"
|
||||
else -> return false
|
||||
}
|
||||
|
||||
@@ -44,12 +43,12 @@ public class ConvertNegatedExpressionWithDemorgansLawIntention : SelfTargetingOf
|
||||
}
|
||||
|
||||
fun applyTo(element: KtPrefixExpression) {
|
||||
val parenthesizedExpression = element.getBaseExpression() as KtParenthesizedExpression
|
||||
val baseExpression = parenthesizedExpression.getExpression() as KtBinaryExpression
|
||||
val parenthesizedExpression = element.baseExpression as KtParenthesizedExpression
|
||||
val baseExpression = parenthesizedExpression.expression as KtBinaryExpression
|
||||
|
||||
val operatorText = when (baseExpression.getOperationToken()) {
|
||||
KtTokens.ANDAND -> KtTokens.OROR.getValue()
|
||||
KtTokens.OROR -> KtTokens.ANDAND.getValue()
|
||||
val operatorText = when (baseExpression.operationToken) {
|
||||
KtTokens.ANDAND -> KtTokens.OROR.value
|
||||
KtTokens.OROR -> KtTokens.ANDAND.value
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
|
||||
@@ -64,19 +63,19 @@ public class ConvertNegatedExpressionWithDemorgansLawIntention : SelfTargetingOf
|
||||
|
||||
private fun splitBooleanSequence(expression: KtBinaryExpression): List<KtExpression>? {
|
||||
val result = ArrayList<KtExpression>()
|
||||
val firstOperator = expression.getOperationToken()
|
||||
val firstOperator = expression.operationToken
|
||||
|
||||
var remainingExpression: KtExpression = expression
|
||||
while (true) {
|
||||
if (remainingExpression !is KtBinaryExpression) break
|
||||
|
||||
val operation = remainingExpression.getOperationToken()
|
||||
val operation = remainingExpression.operationToken
|
||||
if (operation != KtTokens.ANDAND && operation != KtTokens.OROR) break
|
||||
|
||||
if (operation != firstOperator) return null //Boolean sequence must be homogenous
|
||||
|
||||
result.add(remainingExpression.getRight() ?: return null)
|
||||
remainingExpression = remainingExpression.getLeft() ?: return null
|
||||
result.add(remainingExpression.right ?: return null)
|
||||
remainingExpression = remainingExpression.left ?: return null
|
||||
}
|
||||
|
||||
result.add(remainingExpression)
|
||||
|
||||
+8
-8
@@ -29,19 +29,19 @@ import org.jetbrains.kotlin.psi.KtParameter
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
public class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(javaClass(), "Convert parameter to receiver") {
|
||||
public class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtParameter>(KtParameter::class.java, "Convert parameter to receiver") {
|
||||
override fun isApplicableTo(element: KtParameter, caretOffset: Int): Boolean {
|
||||
val identifier = element.getNameIdentifier() ?: return false
|
||||
if (!identifier.getTextRange().containsOffset(caretOffset)) return false
|
||||
if (element.isVarArg()) return false
|
||||
val identifier = element.nameIdentifier ?: return false
|
||||
if (!identifier.textRange.containsOffset(caretOffset)) return false
|
||||
if (element.isVarArg) return false
|
||||
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return false
|
||||
return function.getValueParameterList() == element.getParent() && function.getReceiverTypeReference() == null
|
||||
return function.valueParameterList == element.parent && function.receiverTypeReference == null
|
||||
}
|
||||
|
||||
private fun configureChangeSignature(parameterIndex: Int): KotlinChangeSignatureConfiguration {
|
||||
return object : KotlinChangeSignatureConfiguration {
|
||||
override fun configure(originalDescriptor: KotlinMethodDescriptor): KotlinMethodDescriptor {
|
||||
return originalDescriptor.modify { it.receiver = originalDescriptor.getParameters()[parameterIndex] }
|
||||
return originalDescriptor.modify { it.receiver = originalDescriptor.parameters[parameterIndex] }
|
||||
}
|
||||
|
||||
override fun performSilently(affectedFunctions: Collection<PsiElement>) = true
|
||||
@@ -52,9 +52,9 @@ public class ConvertParameterToReceiverIntention : SelfTargetingIntention<KtPara
|
||||
|
||||
override fun applyTo(element: KtParameter, editor: Editor) {
|
||||
val function = element.getStrictParentOfType<KtNamedFunction>() ?: return
|
||||
val parameterIndex = function.getValueParameters().indexOf(element)
|
||||
val parameterIndex = function.valueParameters.indexOf(element)
|
||||
val context = function.analyze()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return
|
||||
runChangeSignature(element.project, descriptor, configureChangeSignature(parameterIndex), element, getText())
|
||||
runChangeSignature(element.project, descriptor, configureChangeSignature(parameterIndex), element, text)
|
||||
}
|
||||
}
|
||||
|
||||
+3
-8
@@ -17,16 +17,11 @@
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.psi.KtClassOrObject
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.isExtensionDeclaration
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class ConvertPropertyInitializerToGetterIntention : SelfTargetingIntention<KtProperty>(javaClass(), "Convert property initializer to getter") {
|
||||
class ConvertPropertyInitializerToGetterIntention : SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Convert property initializer to getter") {
|
||||
override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean {
|
||||
return element.initializer != null
|
||||
&& element.initializer?.textRange?.containsOffset(caretOffset) == true
|
||||
@@ -35,8 +30,8 @@ class ConvertPropertyInitializerToGetterIntention : SelfTargetingIntention<KtPro
|
||||
&& !element.isLocal
|
||||
}
|
||||
|
||||
override fun applyTo(property: KtProperty, editor: Editor) {
|
||||
convertPropertyInitializerToGetter(property, editor)
|
||||
override fun applyTo(element: KtProperty, editor: Editor) {
|
||||
convertPropertyInitializerToGetter(element, editor)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
+25
-25
@@ -50,44 +50,44 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.resolve.scopes.utils.findFunction
|
||||
import java.util.*
|
||||
|
||||
public class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtProperty>(javaClass(), "Convert property to function"), LowPriorityAction {
|
||||
public class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Convert property to function"), LowPriorityAction {
|
||||
private inner class Converter(
|
||||
project: Project,
|
||||
descriptor: CallableDescriptor
|
||||
): CallableRefactoring<CallableDescriptor>(project, descriptor, getText()) {
|
||||
): CallableRefactoring<CallableDescriptor>(project, descriptor, text) {
|
||||
private val newName: String = JvmAbi.getterName(callableDescriptor.name.asString())
|
||||
|
||||
private fun convertProperty(originalProperty: KtProperty, psiFactory: KtPsiFactory) {
|
||||
val property = originalProperty.copy() as KtProperty;
|
||||
val getter = property.getGetter();
|
||||
val getter = property.getter;
|
||||
|
||||
val sampleFunction = psiFactory.createFunction("fun foo() {\n\n}");
|
||||
|
||||
property.getValOrVarKeyword().replace(sampleFunction.getFunKeyword()!!);
|
||||
property.addAfter(psiFactory.createParameterList("()"), property.getNameIdentifier());
|
||||
if (property.getInitializer() == null) {
|
||||
property.valOrVarKeyword.replace(sampleFunction.funKeyword!!);
|
||||
property.addAfter(psiFactory.createParameterList("()"), property.nameIdentifier);
|
||||
if (property.initializer == null) {
|
||||
if (getter != null) {
|
||||
val dropGetterTo = (getter.getEqualsToken() ?: getter.getBodyExpression())
|
||||
val dropGetterTo = (getter.equalsToken ?: getter.bodyExpression)
|
||||
?.siblings(forward = false, withItself = false)
|
||||
?.firstOrNull { it !is PsiWhiteSpace }
|
||||
getter.deleteChildRange(getter.getFirstChild(), dropGetterTo)
|
||||
getter.deleteChildRange(getter.firstChild, dropGetterTo)
|
||||
|
||||
val dropPropertyFrom = getter
|
||||
.siblings(forward = false, withItself = false)
|
||||
.first { it !is PsiWhiteSpace }
|
||||
.getNextSibling()
|
||||
property.deleteChildRange(dropPropertyFrom, getter.getPrevSibling())
|
||||
.nextSibling
|
||||
property.deleteChildRange(dropPropertyFrom, getter.prevSibling)
|
||||
}
|
||||
}
|
||||
property.setName(newName)
|
||||
|
||||
originalProperty.replace(psiFactory.createFunction(property.getText()))
|
||||
originalProperty.replace(psiFactory.createFunction(property.text))
|
||||
}
|
||||
|
||||
override fun performRefactoring(descriptorsForChange: Collection<CallableDescriptor>) {
|
||||
val propertyName = callableDescriptor.getName().asString()
|
||||
val propertyName = callableDescriptor.name.asString()
|
||||
val nameChanged = propertyName != newName
|
||||
val getterName = JvmAbi.getterName(callableDescriptor.getName().asString())
|
||||
val getterName = JvmAbi.getterName(callableDescriptor.name.asString())
|
||||
val conflicts = MultiMap<PsiElement, String>()
|
||||
val callables = getAffectedCallables(project, descriptorsForChange)
|
||||
val kotlinRefsToReplaceWithCall = ArrayList<KtSimpleNameExpression>()
|
||||
@@ -108,10 +108,10 @@ public class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtPrope
|
||||
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
|
||||
}
|
||||
else if (callable is PsiMethod) {
|
||||
callable.getContainingClass()
|
||||
callable.containingClass
|
||||
?.findMethodsByName(propertyName, true)
|
||||
// as is necessary here: see KT-10386
|
||||
?.firstOrNull { it.getParameterList().getParametersCount() == 0 && it.namedUnwrappedElement as PsiElement? !in callables }
|
||||
?.firstOrNull { it.parameterList.parametersCount == 0 && !callables.contains(it.namedUnwrappedElement as PsiElement?) }
|
||||
?.let { reportDeclarationConflict(conflicts, it) { "$it already exists" } }
|
||||
}
|
||||
|
||||
@@ -129,18 +129,18 @@ public class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtPrope
|
||||
}
|
||||
}
|
||||
else {
|
||||
val refElement = usage.getElement()
|
||||
val refElement = usage.element
|
||||
conflicts.putValue(
|
||||
refElement,
|
||||
"Unrecognized reference will be skipped: " + StringUtil.htmlEmphasize(refElement.getText())
|
||||
"Unrecognized reference will be skipped: " + StringUtil.htmlEmphasize(refElement.text)
|
||||
)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
||||
val refElement = usage.getElement()
|
||||
val refElement = usage.element
|
||||
|
||||
if (refElement.getText().endsWith(getterName)) continue
|
||||
if (refElement.text.endsWith(getterName)) continue
|
||||
|
||||
if (usage is PsiJavaReference) {
|
||||
if (usage.resolve() is PsiField && usage is PsiReferenceExpression) {
|
||||
@@ -151,13 +151,13 @@ public class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtPrope
|
||||
|
||||
conflicts.putValue(
|
||||
refElement,
|
||||
"Can't replace foreign reference with call expression: " + StringUtil.htmlEmphasize(refElement.getText())
|
||||
"Can't replace foreign reference with call expression: " + StringUtil.htmlEmphasize(refElement.text)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
project.checkConflictsInteractively(conflicts) {
|
||||
project.executeWriteCommand(getText()) {
|
||||
project.executeWriteCommand(text) {
|
||||
val kotlinPsiFactory = KtPsiFactory(project)
|
||||
val javaPsiFactory = PsiElementFactory.SERVICE.getInstance(project)
|
||||
val newKotlinCallExpr = kotlinPsiFactory.createExpression("$newName()")
|
||||
@@ -182,14 +182,14 @@ public class ConvertPropertyToFunctionIntention : SelfTargetingIntention<KtPrope
|
||||
override fun startInWriteAction(): Boolean = false
|
||||
|
||||
override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean {
|
||||
val identifier = element.getNameIdentifier() ?: return false
|
||||
if (!identifier.getTextRange().containsOffset(caretOffset)) return false
|
||||
return element.getDelegate() == null && !element.isVar() && !element.isLocal()
|
||||
val identifier = element.nameIdentifier ?: return false
|
||||
if (!identifier.textRange.containsOffset(caretOffset)) return false
|
||||
return element.delegate == null && !element.isVar && !element.isLocal
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtProperty, editor: Editor) {
|
||||
val context = element.analyze()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, element] as? CallableDescriptor ?: return
|
||||
Converter(element.getProject(), descriptor).run()
|
||||
Converter(element.project, descriptor).run()
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -28,9 +28,9 @@ import org.jetbrains.kotlin.psi.KtNamedFunction
|
||||
import org.jetbrains.kotlin.psi.KtTypeReference
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
public class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntention<KtTypeReference>(javaClass(), "Convert receiver to parameter"), LowPriorityAction {
|
||||
public class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependentIntention<KtTypeReference>(KtTypeReference::class.java, "Convert receiver to parameter"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtTypeReference): Boolean {
|
||||
return (element.getParent() as? KtNamedFunction)?.getReceiverTypeReference() == element
|
||||
return (element.parent as? KtNamedFunction)?.receiverTypeReference == element
|
||||
}
|
||||
|
||||
private fun configureChangeSignature(): KotlinChangeSignatureConfiguration {
|
||||
@@ -44,9 +44,9 @@ public class ConvertReceiverToParameterIntention : SelfTargetingOffsetIndependen
|
||||
override fun startInWriteAction() = false
|
||||
|
||||
override fun applyTo(element: KtTypeReference, editor: Editor) {
|
||||
val function = element.getParent() as? KtNamedFunction ?: return
|
||||
val function = element.parent as? KtNamedFunction ?: return
|
||||
val context = function.analyze()
|
||||
val descriptor = context[BindingContext.DECLARATION_TO_DESCRIPTOR, function] as? FunctionDescriptor ?: return
|
||||
runChangeSignature(element.project, descriptor, configureChangeSignature(), element, getText())
|
||||
runChangeSignature(element.project, descriptor, configureChangeSignature(), element, text)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
public class ConvertToBlockBodyIntention : SelfTargetingIntention<KtDeclarationWithBody>(
|
||||
javaClass(), "Convert to block body"
|
||||
KtDeclarationWithBody::class.java, "Convert to block body"
|
||||
), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtDeclarationWithBody, caretOffset: Int): Boolean {
|
||||
if (element is KtFunctionLiteral || element.hasBlockBody() || !element.hasBody()) return false
|
||||
@@ -35,7 +35,7 @@ public class ConvertToBlockBodyIntention : SelfTargetingIntention<KtDeclarationW
|
||||
when (element) {
|
||||
is KtNamedFunction -> {
|
||||
val returnType = element.returnType() ?: return false
|
||||
if (!element.hasDeclaredReturnType() && returnType.isError()) return false// do not convert when type is implicit and unknown
|
||||
if (!element.hasDeclaredReturnType() && returnType.isError) return false// do not convert when type is implicit and unknown
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -53,7 +53,7 @@ public class ConvertToBlockBodyIntention : SelfTargetingIntention<KtDeclarationW
|
||||
|
||||
companion object {
|
||||
public fun convert(declaration: KtDeclarationWithBody): KtDeclarationWithBody {
|
||||
val body = declaration.getBodyExpression()!!
|
||||
val body = declaration.bodyExpression!!
|
||||
|
||||
fun generateBody(returnsValue: Boolean): KtExpression {
|
||||
val bodyType = body.analyze().getType(body)
|
||||
@@ -74,19 +74,19 @@ public class ConvertToBlockBodyIntention : SelfTargetingIntention<KtDeclarationW
|
||||
generateBody(!KotlinBuiltIns.isUnit(returnType) && !KotlinBuiltIns.isNothing(returnType))
|
||||
}
|
||||
|
||||
is KtPropertyAccessor -> generateBody(declaration.isGetter())
|
||||
is KtPropertyAccessor -> generateBody(declaration.isGetter)
|
||||
|
||||
else -> throw RuntimeException("Unknown declaration type: $declaration")
|
||||
}
|
||||
|
||||
declaration.getEqualsToken()!!.delete()
|
||||
declaration.equalsToken!!.delete()
|
||||
body.replace(newBody)
|
||||
return declaration
|
||||
}
|
||||
|
||||
private fun KtNamedFunction.returnType(): KotlinType? {
|
||||
val descriptor = analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, this] ?: return null
|
||||
return (descriptor as FunctionDescriptor).getReturnType()
|
||||
return (descriptor as FunctionDescriptor).returnType
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+11
-12
@@ -22,21 +22,20 @@ import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.BindingContextUtils
|
||||
|
||||
public class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(javaClass(), "Convert template to concatenated string"), LowPriorityAction {
|
||||
public class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndependentIntention<KtStringTemplateExpression>(KtStringTemplateExpression::class.java, "Convert template to concatenated string"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtStringTemplateExpression): Boolean {
|
||||
if (element.getLastChild().getNode().getElementType() != KtTokens.CLOSING_QUOTE) return false // not available for unclosed literal
|
||||
return element.getEntries().any { it is KtStringTemplateEntryWithExpression }
|
||||
if (element.lastChild.node.elementType != KtTokens.CLOSING_QUOTE) return false // not available for unclosed literal
|
||||
return element.entries.any { it is KtStringTemplateEntryWithExpression }
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtStringTemplateExpression, editor: Editor) {
|
||||
val tripleQuoted = isTripleQuoted(element.getText()!!)
|
||||
val tripleQuoted = isTripleQuoted(element.text!!)
|
||||
val quote = if (tripleQuoted) "\"\"\"" else "\""
|
||||
val entries = element.getEntries()
|
||||
val entries = element.entries
|
||||
|
||||
val text = entries
|
||||
.filterNot { it is KtStringTemplateEntryWithExpression && it.getExpression() == null }
|
||||
.filterNot { it is KtStringTemplateEntryWithExpression && it.expression == null }
|
||||
.mapIndexed { index, entry ->
|
||||
entry.toSeparateString(quote, convertExplicitly = (index == 0), isFinalEntry = (index == entries.lastIndex))
|
||||
}
|
||||
@@ -51,15 +50,15 @@ public class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndepende
|
||||
|
||||
private fun KtStringTemplateEntry.toSeparateString(quote: String, convertExplicitly: Boolean, isFinalEntry: Boolean): String {
|
||||
if (this !is KtStringTemplateEntryWithExpression) {
|
||||
return getText().quote(quote)
|
||||
return text.quote(quote)
|
||||
}
|
||||
|
||||
val expression = getExpression()!! // checked before
|
||||
val expression = expression!! // checked before
|
||||
|
||||
val text = if (needsParenthesis(expression, isFinalEntry))
|
||||
"(" + expression.getText() + ")"
|
||||
"(" + expression.text + ")"
|
||||
else
|
||||
expression.getText()
|
||||
expression.text
|
||||
|
||||
return if (convertExplicitly && !expression.isStringExpression())
|
||||
text + ".toString()"
|
||||
@@ -70,7 +69,7 @@ public class ConvertToConcatenatedStringIntention : SelfTargetingOffsetIndepende
|
||||
private fun needsParenthesis(expression: KtExpression, isFinalEntry: Boolean): Boolean {
|
||||
return when (expression) {
|
||||
is KtBinaryExpression -> true
|
||||
is KtIfExpression -> expression.getElse() !is KtBlockExpression && !isFinalEntry
|
||||
is KtIfExpression -> expression.`else` !is KtBlockExpression && !isFinalEntry
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
|
||||
public class ConvertToExpressionBodyIntention : SelfTargetingOffsetIndependentIntention<KtDeclarationWithBody>(
|
||||
javaClass(), "Convert to expression body"
|
||||
KtDeclarationWithBody::class.java, "Convert to expression body"
|
||||
) {
|
||||
override fun isApplicableTo(element: KtDeclarationWithBody): Boolean {
|
||||
val value = calcValue(element) ?: return false
|
||||
@@ -53,7 +53,7 @@ public class ConvertToExpressionBodyIntention : SelfTargetingOffsetIndependentIn
|
||||
|
||||
public fun applyTo(declaration: KtDeclarationWithBody, canDeleteTypeRef: Boolean) {
|
||||
val deleteTypeHandler: (KtCallableDeclaration) -> Unit = {
|
||||
it.deleteChildRange(it.getColon()!!, it.getTypeReference()!!)
|
||||
it.deleteChildRange(it.colon!!, it.typeReference!!)
|
||||
}
|
||||
applyTo(declaration, deleteTypeHandler.check { canDeleteTypeRef })
|
||||
}
|
||||
@@ -68,7 +68,7 @@ public class ConvertToExpressionBodyIntention : SelfTargetingOffsetIndependentIn
|
||||
}
|
||||
}
|
||||
|
||||
val body = declaration.getBodyExpression()!!
|
||||
val body = declaration.bodyExpression!!
|
||||
|
||||
val commentSaver = CommentSaver(body)
|
||||
|
||||
@@ -86,13 +86,13 @@ public class ConvertToExpressionBodyIntention : SelfTargetingOffsetIndependentIn
|
||||
|
||||
private fun calcValue(declaration: KtDeclarationWithBody): KtExpression? {
|
||||
if (declaration is KtFunctionLiteral) return null
|
||||
val body = declaration.getBodyExpression()
|
||||
val body = declaration.bodyExpression
|
||||
if (!declaration.hasBlockBody() || body !is KtBlockExpression) return null
|
||||
|
||||
val statement = body.getStatements().singleOrNull() ?: return null
|
||||
val statement = body.statements.singleOrNull() ?: return null
|
||||
when(statement) {
|
||||
is KtReturnExpression -> {
|
||||
return statement.getReturnedExpression()
|
||||
return statement.returnedExpression
|
||||
}
|
||||
|
||||
//TODO: IMO this is not good code, there should be a way to detect that JetExpression does not have value
|
||||
|
||||
+6
-6
@@ -25,23 +25,23 @@ import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
import org.jetbrains.kotlin.psi.psiUtil.contentRange
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
|
||||
public class ConvertToForEachFunctionCallIntention : SelfTargetingIntention<KtForExpression>(javaClass(), "Replace with a 'forEach' function call") {
|
||||
public class ConvertToForEachFunctionCallIntention : SelfTargetingIntention<KtForExpression>(KtForExpression::class.java, "Replace with a 'forEach' function call") {
|
||||
override fun isApplicableTo(element: KtForExpression, caretOffset: Int): Boolean {
|
||||
val rParen = element.getRightParenthesis() ?: return false
|
||||
val rParen = element.rightParenthesis ?: return false
|
||||
if (caretOffset > rParen.endOffset) return false // available only on the loop header, not in the body
|
||||
return element.getLoopRange() != null && element.getLoopParameter() != null && element.getBody() != null
|
||||
return element.loopRange != null && element.loopParameter != null && element.body != null
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtForExpression, editor: Editor) {
|
||||
val commentSaver = CommentSaver(element)
|
||||
|
||||
val body = element.getBody()!!
|
||||
val loopParameter = element.getLoopParameter()!!
|
||||
val body = element.body!!
|
||||
val loopParameter = element.loopParameter!!
|
||||
|
||||
val functionBodyArgument: Any = if (body is KtBlockExpression) body.contentRange() else body
|
||||
|
||||
val foreachExpression = KtPsiFactory(element).createExpressionByPattern(
|
||||
"$0.forEach{$1->$2}", element.getLoopRange()!!, loopParameter, functionBodyArgument)
|
||||
"$0.forEach{$1->$2}", element.loopRange!!, loopParameter, functionBodyArgument)
|
||||
val result = element.replace(foreachExpression)
|
||||
|
||||
commentSaver.restore(result)
|
||||
|
||||
@@ -32,11 +32,11 @@ public class ConvertToStringTemplateInspection : IntentionBasedInspection<KtBina
|
||||
{ ConvertToStringTemplateIntention().shouldSuggestToConvert(it) }
|
||||
)
|
||||
|
||||
public class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(javaClass(), "Convert concatenation to template") {
|
||||
public class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Convert concatenation to template") {
|
||||
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
||||
if (!isApplicableToNoParentCheck(element)) return false
|
||||
|
||||
val parent = element.getParent()
|
||||
val parent = element.parent
|
||||
if (parent is KtBinaryExpression && isApplicableToNoParentCheck(parent)) return false
|
||||
|
||||
return true
|
||||
@@ -58,25 +58,25 @@ public class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIn
|
||||
}
|
||||
|
||||
private fun isApplicableToNoParentCheck(expression: KtBinaryExpression): Boolean {
|
||||
if (expression.getOperationToken() != KtTokens.PLUS) return false
|
||||
if (expression.operationToken != KtTokens.PLUS) return false
|
||||
if (!KotlinBuiltIns.isString(expression.analyze().getType(expression))) return false
|
||||
|
||||
val left = expression.getLeft() ?: return false
|
||||
val right = expression.getRight() ?: return false
|
||||
val left = expression.left ?: return false
|
||||
val right = expression.right ?: return false
|
||||
return !PsiUtilCore.hasErrorElementChild(left) && !PsiUtilCore.hasErrorElementChild(right)
|
||||
}
|
||||
|
||||
private fun buildReplacement(expression: KtBinaryExpression): KtStringTemplateExpression {
|
||||
val rightText = buildText(expression.getRight(), false)
|
||||
return fold(expression.getLeft(), rightText, KtPsiFactory(expression))
|
||||
val rightText = buildText(expression.right, false)
|
||||
return fold(expression.left, rightText, KtPsiFactory(expression))
|
||||
}
|
||||
|
||||
private fun fold(left: KtExpression?, right: String, factory: KtPsiFactory): KtStringTemplateExpression {
|
||||
val forceBraces = !right.isEmpty() && right.first() != '$' && right.first().isJavaIdentifierPart()
|
||||
|
||||
if (left is KtBinaryExpression && isApplicableToNoParentCheck(left)) {
|
||||
val leftRight = buildText(left.getRight(), forceBraces)
|
||||
return fold(left.getLeft(), leftRight + right, factory)
|
||||
val leftRight = buildText(left.right, forceBraces)
|
||||
return fold(left.left, leftRight + right, factory)
|
||||
}
|
||||
else {
|
||||
val leftText = buildText(left, forceBraces)
|
||||
@@ -87,7 +87,7 @@ public class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIn
|
||||
private fun buildText(expr: KtExpression?, forceBraces: Boolean): String {
|
||||
if (expr == null) return ""
|
||||
val expression = KtPsiUtil.safeDeparenthesize(expr)
|
||||
val expressionText = expression.getText()
|
||||
val expressionText = expression.text
|
||||
return when (expression) {
|
||||
is KtConstantExpression -> {
|
||||
val bindingContext = expression.analyze()
|
||||
@@ -97,7 +97,7 @@ public class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIn
|
||||
|
||||
is KtStringTemplateExpression -> {
|
||||
val base = if (expressionText.startsWith("\"\"\"") && expressionText.endsWith("\"\"\"")) {
|
||||
val unquoted = expressionText.substring(3, expressionText.length() - 3)
|
||||
val unquoted = expressionText.substring(3, expressionText.length - 3)
|
||||
StringUtil.escapeStringCharacters(unquoted)
|
||||
}
|
||||
else {
|
||||
@@ -114,8 +114,6 @@ public class ConvertToStringTemplateIntention : SelfTargetingOffsetIndependentIn
|
||||
is KtNameReferenceExpression ->
|
||||
"$" + (if (forceBraces) "{$expressionText}" else expressionText)
|
||||
|
||||
null -> ""
|
||||
|
||||
else -> "\${" + expressionText.replace("\n+".toRegex(), " ") + "}"
|
||||
}
|
||||
}
|
||||
|
||||
+28
-28
@@ -45,14 +45,14 @@ import java.util.*
|
||||
public class DeprecatedCallableAddReplaceWithInspection : IntentionBasedInspection<KtCallableDeclaration>(DeprecatedCallableAddReplaceWithIntention())
|
||||
|
||||
public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(
|
||||
javaClass(), "Add 'replaceWith' argument to specify replacement pattern", "Add 'replaceWith' argument to 'Deprecated' annotation"
|
||||
KtCallableDeclaration::class.java, "Add 'replaceWith' argument to specify replacement pattern", "Add 'replaceWith' argument to 'Deprecated' annotation"
|
||||
) {
|
||||
private class ReplaceWith(val expression: String, vararg val imports: String)
|
||||
|
||||
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? {
|
||||
val annotationEntry = element.deprecatedAnnotationWithNoReplaceWith() ?: return null
|
||||
if (element.suggestReplaceWith() == null) return null
|
||||
return annotationEntry.getTextRange()
|
||||
return annotationEntry.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtCallableDeclaration, editor: Editor) {
|
||||
@@ -69,9 +69,9 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
|
||||
// escape '$' if it's followed by a letter or '{'
|
||||
if (escapedText.contains('$')) {
|
||||
escapedText = StringBuilder {
|
||||
escapedText = StringBuilder().apply {
|
||||
var i = 0
|
||||
val length = escapedText.length()
|
||||
val length = escapedText.length
|
||||
while (i < length) {
|
||||
val c = escapedText[i++]
|
||||
if (c == '$' && i < length) {
|
||||
@@ -85,7 +85,7 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
}.toString()
|
||||
}
|
||||
|
||||
val argumentText = StringBuilder {
|
||||
val argumentText = StringBuilder().apply {
|
||||
append("kotlin.ReplaceWith(\"")
|
||||
append(escapedText)
|
||||
append("\"")
|
||||
@@ -95,30 +95,30 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
}.toString()
|
||||
|
||||
var argument = psiFactory.createArgument(psiFactory.createExpression(argumentText))
|
||||
argument = annotationEntry.getValueArgumentList()!!.addArgument(argument)
|
||||
argument = annotationEntry.valueArgumentList!!.addArgument(argument)
|
||||
argument = ShortenReferences.DEFAULT.process(argument) as KtValueArgument
|
||||
|
||||
PsiDocumentManager.getInstance(argument.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
editor.moveCaret(argument.getTextOffset())
|
||||
PsiDocumentManager.getInstance(argument.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
editor.moveCaret(argument.textOffset)
|
||||
}
|
||||
|
||||
private fun KtCallableDeclaration.deprecatedAnnotationWithNoReplaceWith(): KtAnnotationEntry? {
|
||||
val bindingContext = this.analyze()
|
||||
// val deprecatedConstructor = KotlinBuiltIns.getInstance().getDeprecatedAnnotation().getUnsubstitutedPrimaryConstructor()
|
||||
for (entry in getAnnotationEntries()) {
|
||||
for (entry in annotationEntries) {
|
||||
entry.analyze()
|
||||
val resolvedCall = entry.getCalleeExpression().getResolvedCall(bindingContext) ?: continue
|
||||
val resolvedCall = entry.calleeExpression.getResolvedCall(bindingContext) ?: continue
|
||||
if (!resolvedCall.isReallySuccess()) continue
|
||||
// if (resolvedCall.getResultingDescriptor() != deprecatedConstructor) continue
|
||||
|
||||
//TODO
|
||||
val descriptor = resolvedCall.getResultingDescriptor().getContainingDeclaration()
|
||||
val descriptor = resolvedCall.resultingDescriptor.containingDeclaration
|
||||
val descriptorFqName = DescriptorUtils.getFqName(descriptor).toSafe()
|
||||
if (descriptorFqName != KotlinBuiltIns.FQ_NAMES.deprecated) continue
|
||||
|
||||
val replaceWithArguments = resolvedCall.getValueArguments().entrySet()
|
||||
.single { it.key.getName().asString() == "replaceWith"/*TODO: kotlin.deprecated::replaceWith.name*/ }.value
|
||||
return if (replaceWithArguments.getArguments().isEmpty()) entry else null
|
||||
val replaceWithArguments = resolvedCall.valueArguments.entries
|
||||
.single { it.key.name.asString() == "replaceWith"/*TODO: kotlin.deprecated::replaceWith.name*/ }.value
|
||||
return if (replaceWithArguments.arguments.isEmpty()) entry else null
|
||||
}
|
||||
return null
|
||||
}
|
||||
@@ -128,8 +128,8 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
is KtNamedFunction -> replacementExpressionFromBody()
|
||||
|
||||
is KtProperty -> {
|
||||
if (isVar()) return null //TODO
|
||||
getGetter()?.replacementExpressionFromBody()
|
||||
if (isVar) return null //TODO
|
||||
getter?.replacementExpressionFromBody()
|
||||
}
|
||||
|
||||
else -> null
|
||||
@@ -146,7 +146,7 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
}
|
||||
|
||||
override fun visitBlockExpression(expression: KtBlockExpression) {
|
||||
if (expression.getStatements().size() > 1) {
|
||||
if (expression.statements.size > 1) {
|
||||
isGood = false
|
||||
return
|
||||
}
|
||||
@@ -155,7 +155,7 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
|
||||
override fun visitSimpleNameExpression(expression: KtSimpleNameExpression) {
|
||||
val target = expression.analyze()[BindingContext.REFERENCE_TARGET, expression] as? DeclarationDescriptorWithVisibility ?: return
|
||||
if (Visibilities.isPrivate((target.getVisibility()))) {
|
||||
if (Visibilities.isPrivate((target.visibility))) {
|
||||
isGood = false
|
||||
}
|
||||
}
|
||||
@@ -168,34 +168,34 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
|
||||
//TODO: check that no receivers that cannot be referenced from outside involved
|
||||
|
||||
val text = replacementExpression.getText()
|
||||
val text = replacementExpression.text
|
||||
var expression = try {
|
||||
KtPsiFactory(this).createExpression(text.replace('\n', ' '))
|
||||
}
|
||||
catch(e: Throwable) { // does not parse in one line
|
||||
return null
|
||||
}
|
||||
expression = CodeStyleManager.getInstance(getProject()).reformat(expression, true) as KtExpression
|
||||
expression = CodeStyleManager.getInstance(project).reformat(expression, true) as KtExpression
|
||||
|
||||
return ReplaceWith(expression.getText(), *extractImports(replacementExpression).toTypedArray())
|
||||
return ReplaceWith(expression.text, *extractImports(replacementExpression).toTypedArray())
|
||||
}
|
||||
|
||||
private fun KtDeclarationWithBody.replacementExpressionFromBody(): KtExpression? {
|
||||
val body = getBodyExpression() ?: return null
|
||||
val body = bodyExpression ?: return null
|
||||
if (!hasBlockBody()) return body
|
||||
val block = body as? KtBlockExpression ?: return null
|
||||
val statement = block.getStatements().singleOrNull() as? KtExpression ?: return null
|
||||
val returnsUnit = (analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, this] as? FunctionDescriptor)?.getReturnType()?.isUnit() ?: return null
|
||||
val statement = block.statements.singleOrNull() as? KtExpression ?: return null
|
||||
val returnsUnit = (analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, this] as? FunctionDescriptor)?.returnType?.isUnit() ?: return null
|
||||
return when (statement) {
|
||||
is KtReturnExpression -> statement.getReturnedExpression()
|
||||
is KtReturnExpression -> statement.returnedExpression
|
||||
else -> if (returnsUnit) statement else null
|
||||
}
|
||||
}
|
||||
|
||||
private fun extractImports(expression: KtExpression): Collection<String> {
|
||||
val file = expression.getContainingKtFile()
|
||||
val currentPackageFqName = file.getPackageFqName()
|
||||
val importHelper = ImportInsertHelper.getInstance(expression.getProject())
|
||||
val currentPackageFqName = file.packageFqName
|
||||
val importHelper = ImportInsertHelper.getInstance(expression.project)
|
||||
|
||||
val result = ArrayList<String>()
|
||||
expression.accept(object : KtVisitorVoid(){
|
||||
@@ -207,7 +207,7 @@ public class DeprecatedCallableAddReplaceWithIntention : SelfTargetingRangeInten
|
||||
if (target.isExtension || expression.getReceiverExpression() == null) {
|
||||
val fqName = target.importableFqName ?: return
|
||||
if (!importHelper.isImportedWithDefault(ImportPath(fqName, false), file)
|
||||
&& (target.getContainingDeclaration() as? PackageFragmentDescriptor)?.fqName != currentPackageFqName) {
|
||||
&& (target.containingDeclaration as? PackageFragmentDescriptor)?.fqName != currentPackageFqName) {
|
||||
result.add(fqName.asString())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,27 +36,27 @@ import java.util.*
|
||||
|
||||
public class IfNullToElvisInspection : IntentionBasedInspection<KtIfExpression>(IfNullToElvisIntention())
|
||||
|
||||
public class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression>(javaClass(), "Replace 'if' with elvis operator"){
|
||||
public class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' with elvis operator"){
|
||||
override fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||
val data = calcData(element) ?: return null
|
||||
|
||||
val type = data.ifNullExpression.analyze().getType(data.ifNullExpression) ?: return null
|
||||
if (!type.isNothing()) return null
|
||||
|
||||
val rParen = element.getRightParenthesis() ?: return null
|
||||
val rParen = element.rightParenthesis ?: return null
|
||||
return TextRange(element.startOffset, rParen.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
val newElvis = applyTo(element)
|
||||
editor.getCaretModel().moveToOffset(newElvis.getRight()!!.getTextOffset())
|
||||
editor.caretModel.moveToOffset(newElvis.right!!.textOffset)
|
||||
}
|
||||
|
||||
public fun applyTo(element: KtIfExpression): KtBinaryExpression {
|
||||
val (initializer, declaration, ifNullExpr) = calcData(element)!!
|
||||
val factory = KtPsiFactory(element)
|
||||
|
||||
val explicitTypeToAdd = if (declaration.isVar() && declaration.getTypeReference() == null)
|
||||
val explicitTypeToAdd = if (declaration.isVar && declaration.typeReference == null)
|
||||
initializer.analyze().getType(initializer)
|
||||
else
|
||||
null
|
||||
@@ -73,7 +73,7 @@ public class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression
|
||||
val newElvis = initializer.replaced(elvis)
|
||||
element.delete()
|
||||
|
||||
if (explicitTypeToAdd != null && !explicitTypeToAdd.isError()) {
|
||||
if (explicitTypeToAdd != null && !explicitTypeToAdd.isError) {
|
||||
declaration.setType(explicitTypeToAdd)
|
||||
}
|
||||
|
||||
@@ -87,22 +87,22 @@ public class IfNullToElvisIntention : SelfTargetingRangeIntention<KtIfExpression
|
||||
)
|
||||
|
||||
private fun calcData(ifExpression: KtIfExpression): Data? {
|
||||
if (ifExpression.getElse() != null) return null
|
||||
if (ifExpression.`else` != null) return null
|
||||
|
||||
val binaryExpression = ifExpression.getCondition() as? KtBinaryExpression ?: return null
|
||||
if (binaryExpression.getOperationToken() != KtTokens.EQEQ) return null
|
||||
val binaryExpression = ifExpression.condition as? KtBinaryExpression ?: return null
|
||||
if (binaryExpression.operationToken != KtTokens.EQEQ) return null
|
||||
val value = binaryExpression.expressionComparedToNull() as? KtNameReferenceExpression ?: return null
|
||||
|
||||
if (ifExpression.getParent() !is KtBlockExpression) return null
|
||||
if (ifExpression.parent !is KtBlockExpression) return null
|
||||
val prevStatement = ifExpression.siblings(forward = false, withItself = false)
|
||||
.firstIsInstanceOrNull<KtExpression>() ?: return null
|
||||
if (prevStatement !is KtVariableDeclaration) return null
|
||||
if (prevStatement.getNameAsName() != value.getReferencedNameAsName()) return null
|
||||
val initializer = prevStatement.getInitializer() ?: return null
|
||||
val then = ifExpression.getThen() ?: return null
|
||||
if (prevStatement.nameAsName != value.getReferencedNameAsName()) return null
|
||||
val initializer = prevStatement.initializer ?: return null
|
||||
val then = ifExpression.then ?: return null
|
||||
|
||||
if (then is KtBlockExpression) {
|
||||
val statement = then.getStatements().singleOrNull() ?: return null
|
||||
val statement = then.statements.singleOrNull() ?: return null
|
||||
return Data(initializer, prevStatement, statement)
|
||||
}
|
||||
else {
|
||||
|
||||
@@ -20,10 +20,10 @@ import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class InfixCallToOrdinaryIntention : SelfTargetingIntention<KtBinaryExpression>(javaClass(), "Replace infix call with ordinary call") {
|
||||
public class InfixCallToOrdinaryIntention : SelfTargetingIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Replace infix call with ordinary call") {
|
||||
override fun isApplicableTo(element: KtBinaryExpression, caretOffset: Int): Boolean {
|
||||
if (element.getOperationToken() != KtTokens.IDENTIFIER || element.getLeft() == null || element.getRight() == null) return false
|
||||
return element.getOperationReference().getTextRange().containsOffset(caretOffset)
|
||||
if (element.operationToken != KtTokens.IDENTIFIER || element.left == null || element.right == null) return false
|
||||
return element.operationReference.textRange.containsOffset(caretOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
@@ -32,12 +32,12 @@ public class InfixCallToOrdinaryIntention : SelfTargetingIntention<KtBinaryExpre
|
||||
|
||||
companion object {
|
||||
public fun convert(element: KtBinaryExpression): KtExpression {
|
||||
val argument = KtPsiUtil.safeDeparenthesize(element.getRight()!!)
|
||||
val argument = KtPsiUtil.safeDeparenthesize(element.right!!)
|
||||
val pattern = "$0.$1" + when (argument) {
|
||||
is KtLambdaExpression -> " $2:'{}'"
|
||||
else -> "($2)"
|
||||
}
|
||||
val replacement = KtPsiFactory(element).createExpressionByPattern(pattern, element.getLeft()!!, element.getOperationReference().getText(), argument)
|
||||
val replacement = KtPsiFactory(element).createExpressionByPattern(pattern, element.left!!, element.operationReference.text, argument)
|
||||
return element.replace(replacement) as KtExpression
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -22,12 +22,12 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.KtSimpleNameStringTemplateEntry
|
||||
|
||||
public class InsertCurlyBracesToTemplateIntention : SelfTargetingOffsetIndependentIntention<KtSimpleNameStringTemplateEntry> (
|
||||
javaClass(), "Insert curly braces around variable"), LowPriorityAction {
|
||||
KtSimpleNameStringTemplateEntry::class.java, "Insert curly braces around variable"), LowPriorityAction {
|
||||
|
||||
override fun isApplicableTo(element: KtSimpleNameStringTemplateEntry): Boolean = true
|
||||
|
||||
override fun applyTo(element: KtSimpleNameStringTemplateEntry, editor: Editor) {
|
||||
val expression = element.getExpression() ?: return
|
||||
val expression = element.expression ?: return
|
||||
element.replace(KtPsiFactory(element).createBlockStringTemplateEntry(expression))
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -29,15 +29,15 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.types.ErrorUtils
|
||||
|
||||
public class InsertExplicitTypeArgumentsIntention : SelfTargetingRangeIntention<KtCallExpression>(javaClass(), "Add explicit type arguments"), LowPriorityAction {
|
||||
public class InsertExplicitTypeArgumentsIntention : SelfTargetingRangeIntention<KtCallExpression>(KtCallExpression::class.java, "Add explicit type arguments"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtCallExpression): TextRange? {
|
||||
return if (isApplicableTo(element, element.analyze())) element.getCalleeExpression()!!.getTextRange() else null
|
||||
return if (isApplicableTo(element, element.analyze())) element.calleeExpression!!.textRange else null
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtCallExpression, editor: Editor) {
|
||||
val argumentList = createTypeArguments(element, element.analyze())!!
|
||||
|
||||
val callee = element.getCalleeExpression()!!
|
||||
val callee = element.calleeExpression!!
|
||||
val newArgumentList = element.addAfter(argumentList, callee) as KtTypeArgumentList
|
||||
|
||||
ShortenReferences.DEFAULT.process(newArgumentList)
|
||||
@@ -45,19 +45,19 @@ public class InsertExplicitTypeArgumentsIntention : SelfTargetingRangeIntention<
|
||||
|
||||
companion object {
|
||||
public fun isApplicableTo(element: KtCallExpression, bindingContext: BindingContext): Boolean {
|
||||
if (!element.getTypeArguments().isEmpty()) return false
|
||||
if (element.getCalleeExpression() == null) return false
|
||||
if (!element.typeArguments.isEmpty()) return false
|
||||
if (element.calleeExpression == null) return false
|
||||
|
||||
val resolvedCall = element.getResolvedCall(bindingContext) ?: return false
|
||||
val typeArgs = resolvedCall.getTypeArguments()
|
||||
return typeArgs.isNotEmpty() && typeArgs.values().none { ErrorUtils.containsErrorType(it) }
|
||||
val typeArgs = resolvedCall.typeArguments
|
||||
return typeArgs.isNotEmpty() && typeArgs.values.none { ErrorUtils.containsErrorType(it) }
|
||||
}
|
||||
|
||||
public fun createTypeArguments(element: KtCallExpression, bindingContext: BindingContext): KtTypeArgumentList? {
|
||||
val resolvedCall = element.getResolvedCall(bindingContext) ?: return null
|
||||
|
||||
val args = resolvedCall.getTypeArguments()
|
||||
val types = resolvedCall.getCandidateDescriptor().getTypeParameters()
|
||||
val args = resolvedCall.typeArguments
|
||||
val types = resolvedCall.candidateDescriptor.typeParameters
|
||||
|
||||
val text = types.map { IdeDescriptorRenderers.SOURCE_CODE.renderType(args[it]!!) }.joinToString(", ", "<", ">")
|
||||
|
||||
|
||||
@@ -16,24 +16,17 @@
|
||||
|
||||
package org.jetbrains.kotlin.idea.intentions
|
||||
|
||||
import com.intellij.codeInsight.intention.IntentionAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.project.Project
|
||||
import com.intellij.psi.search.LocalSearchScope
|
||||
import com.intellij.psi.search.searches.ReferencesSearch
|
||||
import org.jetbrains.kotlin.descriptors.PropertyDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
|
||||
import org.jetbrains.kotlin.diagnostics.Diagnostic
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinQuickFixAction
|
||||
import org.jetbrains.kotlin.idea.quickfix.KotlinSingleIntentionActionFactory
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getStrictParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
class IntroduceBackingPropertyIntention(): SelfTargetingIntention<KtProperty>(javaClass(), "Introduce backing property") {
|
||||
class IntroduceBackingPropertyIntention(): SelfTargetingIntention<KtProperty>(KtProperty::class.java, "Introduce backing property") {
|
||||
override fun isApplicableTo(element: KtProperty, caretOffset: Int): Boolean {
|
||||
if (!canIntroduceBackingProperty(element)) return false
|
||||
return element.nameIdentifier?.textRange?.containsOffset(caretOffset) == true
|
||||
@@ -97,7 +90,7 @@ class IntroduceBackingPropertyIntention(): SelfTargetingIntention<KtProperty>(ja
|
||||
}
|
||||
|
||||
private fun KtProperty.addAccessor(newAccessor: KtPropertyAccessor) {
|
||||
val semicolon = getNode().findChildByType(KtTokens.SEMICOLON)
|
||||
val semicolon = node.findChildByType(KtTokens.SEMICOLON)
|
||||
addBefore(newAccessor, semicolon?.psi)
|
||||
}
|
||||
|
||||
@@ -136,24 +129,3 @@ class IntroduceBackingPropertyIntention(): SelfTargetingIntention<KtProperty>(ja
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class IntroduceBackingPropertyFix(prop: KtProperty): KotlinQuickFixAction<KtProperty>(prop) {
|
||||
override fun getText(): String = "Introduce backing property"
|
||||
override fun getFamilyName(): String = getText()
|
||||
|
||||
override fun invoke(project: Project, editor: Editor?, file: KtFile) {
|
||||
IntroduceBackingPropertyIntention.introduceBackingProperty(element)
|
||||
}
|
||||
|
||||
companion object : KotlinSingleIntentionActionFactory() {
|
||||
override fun createAction(diagnostic: Diagnostic): IntentionAction? {
|
||||
val resolveResult = diagnostic.psiElement.reference?.resolve()
|
||||
if (resolveResult is KtProperty &&
|
||||
IntroduceBackingPropertyIntention.canIntroduceBackingProperty(resolveResult)) {
|
||||
return IntroduceBackingPropertyFix(resolveResult)
|
||||
}
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -29,14 +29,14 @@ import org.jetbrains.kotlin.types.typeUtil.isUnit
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstance
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.lastIsInstanceOrNull
|
||||
|
||||
public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>(javaClass(), "Invert 'if' condition") {
|
||||
public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>(KtIfExpression::class.java, "Invert 'if' condition") {
|
||||
override fun isApplicableTo(element: KtIfExpression, caretOffset: Int): Boolean {
|
||||
if (!element.getIfKeyword().getTextRange().containsOffset(caretOffset)) return false
|
||||
return element.getCondition() != null && element.getThen() != null
|
||||
if (!element.ifKeyword.textRange.containsOffset(caretOffset)) return false
|
||||
return element.condition != null && element.then != null
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
val newCondition = element.getCondition()!!.negate()
|
||||
val newCondition = element.condition!!.negate()
|
||||
|
||||
val newIf = handleSpecialCases(element, newCondition)
|
||||
?: handleStandardCase(element, newCondition)
|
||||
@@ -47,22 +47,22 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
simplifyIntention.applyTo(newIfCondition)
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(newIf.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
editor.moveCaret(newIf.getTextOffset())
|
||||
PsiDocumentManager.getInstance(newIf.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
editor.moveCaret(newIf.textOffset)
|
||||
}
|
||||
|
||||
private fun handleStandardCase(ifExpression: KtIfExpression, newCondition: KtExpression): KtIfExpression {
|
||||
val psiFactory = KtPsiFactory(ifExpression)
|
||||
|
||||
val thenBranch = ifExpression.getThen()!!
|
||||
val elseBranch = ifExpression.getElse() ?: psiFactory.createEmptyBody()
|
||||
val thenBranch = ifExpression.then!!
|
||||
val elseBranch = ifExpression.`else` ?: psiFactory.createEmptyBody()
|
||||
|
||||
val newThen = if (elseBranch is KtIfExpression)
|
||||
psiFactory.createSingleStatementBlock(elseBranch)
|
||||
else
|
||||
elseBranch
|
||||
|
||||
val newElse = if (thenBranch is KtBlockExpression && thenBranch.getStatements().isEmpty())
|
||||
val newElse = if (thenBranch is KtBlockExpression && thenBranch.statements.isEmpty())
|
||||
null
|
||||
else
|
||||
thenBranch
|
||||
@@ -71,17 +71,17 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
}
|
||||
|
||||
private fun handleSpecialCases(ifExpression: KtIfExpression, newCondition: KtExpression): KtIfExpression? {
|
||||
val elseBranch = ifExpression.getElse()
|
||||
val elseBranch = ifExpression.`else`
|
||||
if (elseBranch != null) return null
|
||||
|
||||
val factory = KtPsiFactory(ifExpression)
|
||||
|
||||
val thenBranch = ifExpression.getThen()!!
|
||||
val thenBranch = ifExpression.then!!
|
||||
val lastThenStatement = thenBranch.lastBlockStatementOrThis()
|
||||
if (lastThenStatement.isExitStatement()) {
|
||||
val block = ifExpression.getParent() as? KtBlockExpression
|
||||
val block = ifExpression.parent as? KtBlockExpression
|
||||
if (block != null) {
|
||||
val rBrace = block.getRBrace()
|
||||
val rBrace = block.rBrace
|
||||
val afterIfInBlock = ifExpression.siblings(withItself = false)
|
||||
.takeWhile { it != rBrace }
|
||||
.toList()
|
||||
@@ -95,12 +95,12 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
val first = afterIfInBlock.first()
|
||||
val last = afterIfInBlock.last()
|
||||
// build new then branch text from statements after if (we will add exit statement if necessary later)
|
||||
var newIfBodyText = ifExpression.getContainingFile().getText().substring(first.startOffset, last.endOffset).trim()
|
||||
var newIfBodyText = ifExpression.containingFile.text.substring(first.startOffset, last.endOffset).trim()
|
||||
|
||||
// remove statements after if as they are moving under if
|
||||
block.deleteChildRange(first, last)
|
||||
|
||||
if (lastThenStatement is KtReturnExpression && lastThenStatement.getReturnedExpression() == null) {
|
||||
if (lastThenStatement is KtReturnExpression && lastThenStatement.returnedExpression == null) {
|
||||
lastThenStatement.delete()
|
||||
}
|
||||
val updatedIf = copyThenBranchAfter(ifExpression)
|
||||
@@ -110,7 +110,7 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
// don't insert the exit statement, if the new if statement placement has the same exit statement executed after it
|
||||
val exitAfterNewIf = exitStatementExecutedAfter(updatedIf)
|
||||
if (exitAfterNewIf == null || !exitAfterNewIf.matches(exitStatementAfterIf)) {
|
||||
newIfBodyText += "\n" + exitStatementAfterIf.getText()
|
||||
newIfBodyText += "\n" + exitStatementAfterIf.text
|
||||
}
|
||||
}
|
||||
|
||||
@@ -132,15 +132,15 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
|
||||
private fun copyThenBranchAfter(ifExpression: KtIfExpression): KtIfExpression {
|
||||
val factory = KtPsiFactory(ifExpression)
|
||||
val thenBranch = ifExpression.getThen() ?: return ifExpression
|
||||
val thenBranch = ifExpression.then ?: return ifExpression
|
||||
|
||||
val parent = ifExpression.getParent()
|
||||
val parent = ifExpression.parent
|
||||
if (parent !is KtBlockExpression) {
|
||||
assert(parent is KtContainerNode)
|
||||
val block = factory.createEmptyBody()
|
||||
block.addAfter(ifExpression, block.getLBrace())
|
||||
block.addAfter(ifExpression, block.lBrace)
|
||||
val newBlock = ifExpression.replaced(block)
|
||||
val newIf = newBlock.getStatements().single() as KtIfExpression
|
||||
val newIf = newBlock.statements.single() as KtIfExpression
|
||||
return copyThenBranchAfter(newIf)
|
||||
}
|
||||
|
||||
@@ -159,9 +159,9 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
}
|
||||
|
||||
private fun exitStatementExecutedAfter(expression: KtExpression): KtExpression? {
|
||||
val parent = expression.getParent()
|
||||
val parent = expression.parent
|
||||
if (parent is KtBlockExpression) {
|
||||
val lastStatement = parent.getStatements().last()
|
||||
val lastStatement = parent.statements.last()
|
||||
if (expression == lastStatement) {
|
||||
return exitStatementExecutedAfter(parent)
|
||||
}
|
||||
@@ -175,25 +175,25 @@ public class InvertIfConditionIntention : SelfTargetingIntention<KtIfExpression>
|
||||
|
||||
when (parent) {
|
||||
is KtNamedFunction -> {
|
||||
if (parent.getBodyExpression() == expression) {
|
||||
if (parent.bodyExpression == expression) {
|
||||
if (!parent.hasBlockBody()) return null
|
||||
val returnType = (parent.resolveToDescriptor() as FunctionDescriptor).getReturnType()
|
||||
val returnType = (parent.resolveToDescriptor() as FunctionDescriptor).returnType
|
||||
if (returnType == null || !returnType.isUnit()) return null
|
||||
return KtPsiFactory(expression).createExpression("return")
|
||||
}
|
||||
}
|
||||
|
||||
is KtContainerNode -> {
|
||||
val pparent = parent.getParent()
|
||||
val pparent = parent.parent
|
||||
when (pparent) {
|
||||
is KtLoopExpression -> {
|
||||
if (expression == pparent.getBody()) {
|
||||
if (expression == pparent.body) {
|
||||
return KtPsiFactory(expression).createExpression("continue")
|
||||
}
|
||||
}
|
||||
|
||||
is KtIfExpression -> {
|
||||
if (expression == pparent.getThen() || expression == pparent.getElse()) {
|
||||
if (expression == pparent.then || expression == pparent.`else`) {
|
||||
return exitStatementExecutedAfter(pparent)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,13 +32,13 @@ import org.jetbrains.kotlin.psi.psiUtil.siblings
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
public class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(javaClass(), "Iterate over collection"), HighPriorityAction {
|
||||
public class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(KtExpression::class.java, "Iterate over collection"), HighPriorityAction {
|
||||
override fun isApplicableTo(element: KtExpression, caretOffset: Int): Boolean {
|
||||
if (element.getParent() !is KtBlockExpression) return false
|
||||
val range = element.getTextRange()
|
||||
if (caretOffset != range.getStartOffset() && caretOffset != range.getEndOffset()) return false
|
||||
if (element.parent !is KtBlockExpression) return false
|
||||
val range = element.textRange
|
||||
if (caretOffset != range.startOffset && caretOffset != range.endOffset) return false
|
||||
val data = data(element) ?: return false
|
||||
setText("Iterate over '${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(data.collectionType)}'")
|
||||
text = "Iterate over '${IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(data.collectionType)}'"
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -65,12 +65,12 @@ public class IterateExpressionIntention : SelfTargetingIntention<KtExpression>(j
|
||||
var forExpression = KtPsiFactory(element).createExpressionByPattern("for($0 in $1) {\nx\n}", names.first(), element) as KtForExpression
|
||||
forExpression = element.replaced(forExpression)
|
||||
|
||||
PsiDocumentManager.getInstance(forExpression.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
PsiDocumentManager.getInstance(forExpression.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
val bodyPlaceholder = (forExpression.getBody() as KtBlockExpression).getStatements().single()
|
||||
val bodyPlaceholder = (forExpression.body as KtBlockExpression).statements.single()
|
||||
|
||||
val templateBuilder = TemplateBuilderImpl(forExpression)
|
||||
templateBuilder.replaceElement(forExpression.getLoopParameter()!!, ChooseStringExpression(names))
|
||||
templateBuilder.replaceElement(forExpression.loopParameter!!, ChooseStringExpression(names))
|
||||
templateBuilder.replaceElement(bodyPlaceholder, ConstantNode(""), false)
|
||||
templateBuilder.setEndVariableAfter(bodyPlaceholder)
|
||||
|
||||
|
||||
+1
-1
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstIsInstanceOrNull
|
||||
|
||||
public class MoveAssignmentToInitializerIntention :
|
||||
SelfTargetingIntention<KtBinaryExpression>(javaClass(), "Move assignment to initializer") {
|
||||
SelfTargetingIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Move assignment to initializer") {
|
||||
|
||||
override fun isApplicableTo(element: KtBinaryExpression, caretOffset: Int): Boolean {
|
||||
if (element.operationToken != KtTokens.EQ) {
|
||||
|
||||
+3
-4
@@ -19,15 +19,14 @@ package org.jetbrains.kotlin.idea.intentions
|
||||
import com.intellij.codeInsight.intention.LowPriorityAction
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyzeFully
|
||||
import org.jetbrains.kotlin.idea.core.moveInsideParentheses
|
||||
import org.jetbrains.kotlin.psi.KtLambdaArgument
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containsInside
|
||||
|
||||
public class MoveLambdaInsideParenthesesIntention : SelfTargetingIntention<KtLambdaArgument>(javaClass(), "Move lambda argument into parentheses"), LowPriorityAction {
|
||||
public class MoveLambdaInsideParenthesesIntention : SelfTargetingIntention<KtLambdaArgument>(KtLambdaArgument::class.java, "Move lambda argument into parentheses"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtLambdaArgument, caretOffset: Int): Boolean {
|
||||
val body = element.getLambdaExpression().getBodyExpression() ?: return true
|
||||
return !body.getTextRange().containsInside(caretOffset)
|
||||
val body = element.getLambdaExpression().bodyExpression ?: return true
|
||||
return !body.textRange.containsInside(caretOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtLambdaArgument, editor: Editor) {
|
||||
|
||||
+7
-7
@@ -29,14 +29,14 @@ import org.jetbrains.kotlin.psi.unpackFunctionLiteral
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class MoveLambdaOutsideParenthesesIntention : SelfTargetingIntention<KtCallExpression>(javaClass(), "Move lambda argument out of parentheses") {
|
||||
public class MoveLambdaOutsideParenthesesIntention : SelfTargetingIntention<KtCallExpression>(KtCallExpression::class.java, "Move lambda argument out of parentheses") {
|
||||
override fun isApplicableTo(element: KtCallExpression, caretOffset: Int): Boolean {
|
||||
if (element.getLambdaArguments().isNotEmpty()) return false
|
||||
val argument = element.getValueArguments().lastOrNull() ?: return false
|
||||
if (element.lambdaArguments.isNotEmpty()) return false
|
||||
val argument = element.valueArguments.lastOrNull() ?: return false
|
||||
val expression = argument.getArgumentExpression() ?: return false
|
||||
val functionLiteral = expression.unpackFunctionLiteral() ?: return false
|
||||
|
||||
val callee = element.getCalleeExpression()
|
||||
val callee = element.calleeExpression
|
||||
if (callee is KtNameReferenceExpression) {
|
||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||
val targets = bindingContext[BindingContext.REFERENCE_TARGET, callee]?.let { listOf(it) }
|
||||
@@ -45,15 +45,15 @@ public class MoveLambdaOutsideParenthesesIntention : SelfTargetingIntention<KtCa
|
||||
val candidates = targets.filterIsInstance<FunctionDescriptor>()
|
||||
// if there are functions among candidates but none of them have last function parameter then not show the intention
|
||||
if (candidates.isNotEmpty() && candidates.none {
|
||||
val lastParameter = it.getValueParameters().lastOrNull()
|
||||
lastParameter != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(lastParameter.getType())
|
||||
val lastParameter = it.valueParameters.lastOrNull()
|
||||
lastParameter != null && KotlinBuiltIns.isExactFunctionOrExtensionFunctionType(lastParameter.type)
|
||||
}) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
if (caretOffset < argument.asElement().startOffset) return false
|
||||
val bodyRange = functionLiteral.getBodyExpression()?.getTextRange() ?: return true
|
||||
val bodyRange = functionLiteral.bodyExpression?.textRange ?: return true
|
||||
return !bodyRange.containsInside(caretOffset)
|
||||
}
|
||||
|
||||
|
||||
@@ -27,26 +27,26 @@ import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
public class ReconstructTypeInCastOrIsIntention : SelfTargetingOffsetIndependentIntention<KtTypeReference>(javaClass(), "Replace by reconstructed type"), LowPriorityAction {
|
||||
public class ReconstructTypeInCastOrIsIntention : SelfTargetingOffsetIndependentIntention<KtTypeReference>(KtTypeReference::class.java, "Replace by reconstructed type"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtTypeReference): Boolean {
|
||||
// Only user types (like Foo) are interesting
|
||||
val typeElement = element.typeElement as? KtUserType ?: return false
|
||||
|
||||
// If there are generic arguments already, there's nothing to reconstruct
|
||||
if (typeElement.getTypeArguments().isNotEmpty()) return false
|
||||
if (typeElement.typeArguments.isNotEmpty()) return false
|
||||
|
||||
// We must be on the RHS of as/as?/is/!is or inside an is/!is-condition in when()
|
||||
val expression = element.getParentOfType<KtExpression>(true)
|
||||
if (expression !is KtBinaryExpressionWithTypeRHS && element.getParentOfType<KtWhenConditionIsPattern>(true) == null) return false
|
||||
|
||||
val type = getReconstructedType(element)
|
||||
if (type == null || type.isError()) return false
|
||||
if (type == null || type.isError) return false
|
||||
|
||||
// No type parameters expected => nothing to reconstruct
|
||||
if (type.getConstructor().getParameters().isEmpty()) return false
|
||||
if (type.constructor.parameters.isEmpty()) return false
|
||||
|
||||
val typePresentation = IdeDescriptorRenderers.SOURCE_CODE_SHORT_NAMES_IN_TYPES.renderType(type)
|
||||
setText("Replace by '$typePresentation'")
|
||||
text = "Replace by '$typePresentation'"
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -29,16 +29,16 @@ import org.jetbrains.kotlin.resolve.calls.model.ArgumentMatch
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class RemoveArgumentNameIntention
|
||||
: SelfTargetingRangeIntention<KtValueArgument>(javaClass(), "Remove argument name") {
|
||||
: SelfTargetingRangeIntention<KtValueArgument>(KtValueArgument::class.java, "Remove argument name") {
|
||||
|
||||
override fun applicabilityRange(element: KtValueArgument): TextRange? {
|
||||
if (!element.isNamed()) return null
|
||||
|
||||
val argumentList = element.getParent() as? KtValueArgumentList ?: return null
|
||||
val arguments = argumentList.getArguments()
|
||||
val argumentList = element.parent as? KtValueArgumentList ?: return null
|
||||
val arguments = argumentList.arguments
|
||||
if (arguments.takeWhile { it != element }.any { it.isNamed() }) return null
|
||||
|
||||
val callExpr = argumentList.getParent() as? KtExpression ?: return null
|
||||
val callExpr = argumentList.parent as? KtExpression ?: return null
|
||||
val resolvedCall = callExpr.getResolvedCall(callExpr.analyze(BodyResolveMode.PARTIAL)) ?: return null
|
||||
val argumentMatch = resolvedCall.getArgumentMapping(element) as? ArgumentMatch ?: return null
|
||||
if (argumentMatch.valueParameter.index != arguments.indexOf(element)) return null
|
||||
|
||||
@@ -20,51 +20,50 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiComment
|
||||
import com.intellij.psi.PsiWhiteSpace
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.getParentOfType
|
||||
|
||||
public class RemoveBracesIntention : SelfTargetingIntention<KtBlockExpression>(javaClass(), "Remove braces") {
|
||||
public class RemoveBracesIntention : SelfTargetingIntention<KtBlockExpression>(KtBlockExpression::class.java, "Remove braces") {
|
||||
override fun isApplicableTo(element: KtBlockExpression, caretOffset: Int): Boolean {
|
||||
if (element.getStatements().size() != 1) return false
|
||||
if (element.statements.size != 1) return false
|
||||
|
||||
val containerNode = element.getParent() as? KtContainerNode ?: return false
|
||||
val containerNode = element.parent as? KtContainerNode ?: return false
|
||||
|
||||
val lBrace = element.getLBrace() ?: return false
|
||||
val rBrace = element.getRBrace() ?: return false
|
||||
if (!lBrace.getTextRange().containsOffset(caretOffset) && !rBrace.getTextRange().containsOffset(caretOffset)) return false
|
||||
val lBrace = element.lBrace ?: return false
|
||||
val rBrace = element.rBrace ?: return false
|
||||
if (!lBrace.textRange.containsOffset(caretOffset) && !rBrace.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
val description = containerNode.description() ?: return false
|
||||
setText("Remove braces from '$description' statement")
|
||||
text = "Remove braces from '$description' statement"
|
||||
return true
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBlockExpression, editor: Editor) {
|
||||
val statement = element.getStatements().single()
|
||||
val statement = element.statements.single()
|
||||
|
||||
val containerNode = element.getParent() as KtContainerNode
|
||||
val construct = containerNode.getParent() as KtExpression
|
||||
val containerNode = element.parent as KtContainerNode
|
||||
val construct = containerNode.parent as KtExpression
|
||||
handleComments(construct, element)
|
||||
|
||||
val newElement = element.replace(statement.copy())
|
||||
|
||||
if (construct is KtDoWhileExpression) {
|
||||
newElement.getParent()!!.addAfter(KtPsiFactory(element).createNewLine(), newElement)
|
||||
newElement.parent!!.addAfter(KtPsiFactory(element).createNewLine(), newElement)
|
||||
}
|
||||
}
|
||||
|
||||
private fun handleComments(construct: KtExpression, block: KtBlockExpression) {
|
||||
var sibling = block.getFirstChild()?.getNextSibling()
|
||||
var sibling = block.firstChild?.nextSibling
|
||||
|
||||
while (sibling != null) {
|
||||
if (sibling is PsiComment) {
|
||||
//cleans up extra whitespace
|
||||
val psiFactory = KtPsiFactory(construct)
|
||||
if (construct.getPrevSibling() is PsiWhiteSpace) {
|
||||
construct.getPrevSibling()!!.replace(psiFactory.createNewLine())
|
||||
if (construct.prevSibling is PsiWhiteSpace) {
|
||||
construct.prevSibling!!.replace(psiFactory.createNewLine())
|
||||
}
|
||||
val commentElement = construct.getParent()!!.addBefore(sibling, construct.getPrevSibling())
|
||||
construct.getParent()!!.addBefore(psiFactory.createNewLine(), commentElement)
|
||||
val commentElement = construct.parent!!.addBefore(sibling, construct.prevSibling)
|
||||
construct.parent!!.addBefore(psiFactory.createNewLine(), commentElement)
|
||||
}
|
||||
sibling = sibling.getNextSibling()
|
||||
sibling = sibling.nextSibling
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -27,9 +27,9 @@ import org.jetbrains.kotlin.psi.psiUtil.canPlaceAfterSimpleNameEntry
|
||||
|
||||
public class RemoveCurlyBracesFromTemplateInspection : IntentionBasedInspection<KtBlockStringTemplateEntry>(RemoveCurlyBracesFromTemplateIntention())
|
||||
|
||||
public class RemoveCurlyBracesFromTemplateIntention : SelfTargetingOffsetIndependentIntention<KtBlockStringTemplateEntry>(javaClass(), "Remove curly braces") {
|
||||
public class RemoveCurlyBracesFromTemplateIntention : SelfTargetingOffsetIndependentIntention<KtBlockStringTemplateEntry>(KtBlockStringTemplateEntry::class.java, "Remove curly braces") {
|
||||
override fun isApplicableTo(element: KtBlockStringTemplateEntry): Boolean {
|
||||
if (element.getExpression() !is KtNameReferenceExpression) return false
|
||||
if (element.expression !is KtNameReferenceExpression) return false
|
||||
return canPlaceAfterSimpleNameEntry(element.nextSibling)
|
||||
}
|
||||
|
||||
@@ -38,7 +38,7 @@ public class RemoveCurlyBracesFromTemplateIntention : SelfTargetingOffsetIndepen
|
||||
}
|
||||
|
||||
public fun applyTo(element: KtBlockStringTemplateEntry): KtStringTemplateEntryWithExpression {
|
||||
val name = (element.getExpression() as KtNameReferenceExpression).getReferencedName()
|
||||
val name = (element.expression as KtNameReferenceExpression).getReferencedName()
|
||||
val newEntry = KtPsiFactory(element).createSimpleNameStringTemplateEntry(name)
|
||||
return element.replaced(newEntry)
|
||||
}
|
||||
|
||||
+5
-6
@@ -19,20 +19,19 @@ package org.jetbrains.kotlin.idea.intentions
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
|
||||
public class RemoveExplicitLambdaParameterTypesIntention : SelfTargetingIntention<KtLambdaExpression>(javaClass(), "Remove explicit lambda parameter types (may break code)") {
|
||||
public class RemoveExplicitLambdaParameterTypesIntention : SelfTargetingIntention<KtLambdaExpression>(KtLambdaExpression::class.java, "Remove explicit lambda parameter types (may break code)") {
|
||||
override fun isApplicableTo(element: KtLambdaExpression, caretOffset: Int): Boolean {
|
||||
if (element.getValueParameters().none { it.getTypeReference() != null }) return false
|
||||
val arrow = element.getFunctionLiteral().getArrow() ?: return false
|
||||
if (element.valueParameters.none { it.typeReference != null }) return false
|
||||
val arrow = element.functionLiteral.arrow ?: return false
|
||||
return caretOffset <= arrow.endOffset
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtLambdaExpression, editor: Editor) {
|
||||
val oldParameterList = element.getFunctionLiteral().getValueParameterList()!!
|
||||
val oldParameterList = element.functionLiteral.valueParameterList!!
|
||||
|
||||
val parameterString = oldParameterList.getParameters().map { it.getName() }.joinToString(", ")
|
||||
val parameterString = oldParameterList.parameters.map { it.name }.joinToString(", ")
|
||||
val newParameterList = KtPsiFactory(element).createFunctionLiteralParameterList(parameterString)
|
||||
oldParameterList.replace(newParameterList)
|
||||
}
|
||||
|
||||
+1
-1
@@ -44,7 +44,7 @@ public class RemoveExplicitSuperQualifierInspection : IntentionBasedInspection<K
|
||||
get() = ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
||||
}
|
||||
|
||||
public class RemoveExplicitSuperQualifierIntention : SelfTargetingRangeIntention<KtSuperExpression>(javaClass(), "Remove explicit supertype qualification") {
|
||||
public class RemoveExplicitSuperQualifierIntention : SelfTargetingRangeIntention<KtSuperExpression>(KtSuperExpression::class.java, "Remove explicit supertype qualification") {
|
||||
override fun applicabilityRange(element: KtSuperExpression): TextRange? {
|
||||
if (element.superTypeQualifier == null) return null
|
||||
|
||||
|
||||
+12
-12
@@ -39,27 +39,27 @@ public class RemoveExplicitTypeArgumentsInspection : IntentionBasedInspection<Kt
|
||||
get() = ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
||||
}
|
||||
|
||||
public class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentIntention<KtTypeArgumentList>(javaClass(), "Remove explicit type arguments") {
|
||||
public class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndependentIntention<KtTypeArgumentList>(KtTypeArgumentList::class.java, "Remove explicit type arguments") {
|
||||
companion object {
|
||||
public fun isApplicableTo(element: KtTypeArgumentList, approximateFlexible: Boolean): Boolean {
|
||||
val callExpression = element.getParent() as? KtCallExpression ?: return false
|
||||
if (callExpression.getTypeArguments().isEmpty()) return false
|
||||
val callExpression = element.parent as? KtCallExpression ?: return false
|
||||
if (callExpression.typeArguments.isEmpty()) return false
|
||||
|
||||
val resolutionFacade = callExpression.getResolutionFacade()
|
||||
val context = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL)
|
||||
val calleeExpression = callExpression.getCalleeExpression() ?: return false
|
||||
val calleeExpression = callExpression.calleeExpression ?: return false
|
||||
val scope = calleeExpression.getResolutionScope(context, resolutionFacade)
|
||||
val originalCall = callExpression.getResolvedCall(context) ?: return false
|
||||
val untypedCall = CallWithoutTypeArgs(originalCall.getCall())
|
||||
val untypedCall = CallWithoutTypeArgs(originalCall.call)
|
||||
|
||||
// todo Check with expected type for other expressions
|
||||
// If always use expected type from trace there is a problem with nested calls:
|
||||
// the expression type for them can depend on their explicit type arguments (via outer call),
|
||||
// therefore we should resolve outer call with erased type arguments for inner call
|
||||
val parent = callExpression.getParent()
|
||||
val parent = callExpression.parent
|
||||
val expectedTypeIsExplicitInCode = when (parent) {
|
||||
is KtProperty -> parent.getInitializer() == callExpression && parent.getTypeReference() != null
|
||||
is KtDeclarationWithBody -> parent.getBodyExpression() == callExpression
|
||||
is KtProperty -> parent.initializer == callExpression && parent.typeReference != null
|
||||
is KtDeclarationWithBody -> parent.bodyExpression == callExpression
|
||||
is KtReturnExpression -> true
|
||||
else -> false
|
||||
}
|
||||
@@ -73,12 +73,12 @@ public class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndepende
|
||||
val callResolver = resolutionFacade.frontendService<CallResolver>()
|
||||
val resolutionResults = callResolver.resolveFunctionCall(
|
||||
BindingTraceContext(), scope, untypedCall, expectedType, dataFlow, false)
|
||||
if (!resolutionResults.isSingleResult()) {
|
||||
if (!resolutionResults.isSingleResult) {
|
||||
return false
|
||||
}
|
||||
|
||||
val args = originalCall.getTypeArguments()
|
||||
val newArgs = resolutionResults.getResultingCall().getTypeArguments()
|
||||
val args = originalCall.typeArguments
|
||||
val newArgs = resolutionResults.resultingCall.typeArguments
|
||||
|
||||
fun equalTypes(type1: KotlinType, type2: KotlinType): Boolean {
|
||||
return if (approximateFlexible) {
|
||||
@@ -89,7 +89,7 @@ public class RemoveExplicitTypeArgumentsIntention : SelfTargetingOffsetIndepende
|
||||
}
|
||||
}
|
||||
|
||||
return args.size() == newArgs.size() && args.values().zip(newArgs.values()).all { pair -> equalTypes(pair.first, pair.second) }
|
||||
return args.size == newArgs.size && args.values.zip(newArgs.values).all { pair -> equalTypes(pair.first, pair.second) }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,18 +19,18 @@ package org.jetbrains.kotlin.idea.intentions
|
||||
import com.intellij.openapi.editor.Editor
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class RemoveExplicitTypeIntention : SelfTargetingIntention<KtCallableDeclaration>(javaClass(), "Remove explicit type specification") {
|
||||
public class RemoveExplicitTypeIntention : SelfTargetingIntention<KtCallableDeclaration>(KtCallableDeclaration::class.java, "Remove explicit type specification") {
|
||||
override fun isApplicableTo(element: KtCallableDeclaration, caretOffset: Int): Boolean {
|
||||
if (element.getContainingFile() is KtCodeFragment) return false
|
||||
if (element.getTypeReference() == null) return false
|
||||
if (element.containingFile is KtCodeFragment) return false
|
||||
if (element.typeReference == null) return false
|
||||
|
||||
val initializer = (element as? KtWithExpressionInitializer)?.getInitializer()
|
||||
if (initializer != null && initializer.getTextRange().containsOffset(caretOffset)) return false
|
||||
val initializer = (element as? KtWithExpressionInitializer)?.initializer
|
||||
if (initializer != null && initializer.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
return when (element) {
|
||||
is KtProperty -> initializer != null
|
||||
is KtNamedFunction -> !element.hasBlockBody() && initializer != null
|
||||
is KtParameter -> element.isLoopParameter()
|
||||
is KtParameter -> element.isLoopParameter
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,20 +34,20 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
public class RemoveForLoopIndicesInspection : IntentionBasedInspection<KtForExpression>(
|
||||
listOf(IntentionBasedInspection.IntentionData(RemoveForLoopIndicesIntention())),
|
||||
"Index is not used in the loop body",
|
||||
javaClass()
|
||||
KtForExpression::class.java
|
||||
) {
|
||||
override val problemHighlightType: ProblemHighlightType
|
||||
get() = ProblemHighlightType.LIKE_UNUSED_SYMBOL
|
||||
}
|
||||
|
||||
public class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(javaClass(), "Remove indices in 'for' loop") {
|
||||
public class RemoveForLoopIndicesIntention : SelfTargetingRangeIntention<KtForExpression>(KtForExpression::class.java, "Remove indices in 'for' loop") {
|
||||
private val WITH_INDEX_NAME = "withIndex"
|
||||
private val WITH_INDEX_FQ_NAMES = listOf("collections", "sequences", "text", "ranges").map { "kotlin.$it.$WITH_INDEX_NAME" }.toSet()
|
||||
|
||||
override fun applicabilityRange(element: KtForExpression): TextRange? {
|
||||
val loopRange = element.loopRange as? KtDotQualifiedExpression ?: return null
|
||||
val multiParameter = element.destructuringParameter ?: return null
|
||||
if (multiParameter.entries.size() != 2) return null
|
||||
if (multiParameter.entries.size != 2) return null
|
||||
|
||||
val bindingContext = element.analyze(BodyResolveMode.PARTIAL)
|
||||
|
||||
|
||||
+3
-4
@@ -20,13 +20,12 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.openapi.util.TextRange
|
||||
import org.jetbrains.kotlin.psi.KtParenthesizedExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.psiUtil.containsInside
|
||||
|
||||
public class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention<KtParenthesizedExpression>(KtParenthesizedExpression::class.java, "Remove unnecessary parentheses") {
|
||||
override fun applicabilityRange(element: KtParenthesizedExpression): TextRange? {
|
||||
element.getExpression() ?: return null
|
||||
element.expression ?: return null
|
||||
if (!KtPsiUtil.areParenthesesUseless(element)) return null
|
||||
return element.getTextRange()
|
||||
return element.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtParenthesizedExpression, editor: Editor) {
|
||||
@@ -34,6 +33,6 @@ public class RemoveUnnecessaryParenthesesIntention : SelfTargetingRangeIntention
|
||||
}
|
||||
|
||||
fun applyTo(element: KtParenthesizedExpression) {
|
||||
element.replace(element.getExpression()!!)
|
||||
element.replace(element.expression!!)
|
||||
}
|
||||
}
|
||||
|
||||
+16
-16
@@ -39,19 +39,19 @@ public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBa
|
||||
override fun getFamilyName() = "Replace explicit lambda parameter with 'it'"
|
||||
|
||||
override fun isAvailable(project: Project, editor: Editor, element: PsiElement): Boolean {
|
||||
val functionLiteral = targetFunctionLiteral(element, editor.getCaretModel().getOffset()) ?: return false
|
||||
val functionLiteral = targetFunctionLiteral(element, editor.caretModel.offset) ?: return false
|
||||
|
||||
val parameter = functionLiteral.getValueParameters().singleOrNull() ?: return false
|
||||
if (parameter.getTypeReference() != null) return false
|
||||
val parameter = functionLiteral.valueParameters.singleOrNull() ?: return false
|
||||
if (parameter.typeReference != null) return false
|
||||
|
||||
setText("Replace explicit parameter '${parameter.getName()}' with 'it'")
|
||||
text = "Replace explicit parameter '${parameter.name}' with 'it'"
|
||||
return true
|
||||
}
|
||||
|
||||
override fun invoke(project: Project, editor: Editor, element: PsiElement) {
|
||||
val caretOffset = editor.getCaretModel().getOffset()
|
||||
val functionLiteral = targetFunctionLiteral(element, editor.getCaretModel().getOffset())!!
|
||||
val cursorInParameterList = functionLiteral.getValueParameterList()!!.getTextRange().containsOffset(caretOffset)
|
||||
val caretOffset = editor.caretModel.offset
|
||||
val functionLiteral = targetFunctionLiteral(element, editor.caretModel.offset)!!
|
||||
val cursorInParameterList = functionLiteral.valueParameterList!!.textRange.containsOffset(caretOffset)
|
||||
ParamRenamingProcessor(editor, functionLiteral, cursorInParameterList).run()
|
||||
}
|
||||
|
||||
@@ -60,12 +60,12 @@ public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBa
|
||||
if (expression != null) {
|
||||
val target = expression.mainReference.resolveToDescriptors(expression.analyze(BodyResolveMode.PARTIAL))
|
||||
.singleOrNull() as? ParameterDescriptor ?: return null
|
||||
val functionDescriptor = target.getContainingDeclaration() as? AnonymousFunctionDescriptor ?: return null
|
||||
val functionDescriptor = target.containingDeclaration as? AnonymousFunctionDescriptor ?: return null
|
||||
return DescriptorToSourceUtils.descriptorToDeclaration(functionDescriptor) as? KtFunctionLiteral
|
||||
}
|
||||
|
||||
val functionLiteral = element.getParentOfType<KtFunctionLiteral>(true) ?: return null
|
||||
val arrow = functionLiteral.getArrow() ?: return null
|
||||
val arrow = functionLiteral.arrow ?: return null
|
||||
if (caretOffset > arrow.endOffset) return null
|
||||
return functionLiteral
|
||||
}
|
||||
@@ -74,8 +74,8 @@ public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBa
|
||||
val editor: Editor,
|
||||
val functionLiteral: KtFunctionLiteral,
|
||||
val cursorWasInParameterList: Boolean
|
||||
) : RenameProcessor(editor.getProject(),
|
||||
functionLiteral.getValueParameters().single(),
|
||||
) : RenameProcessor(editor.project,
|
||||
functionLiteral.valueParameters.single(),
|
||||
"it",
|
||||
false,
|
||||
false
|
||||
@@ -83,15 +83,15 @@ public class ReplaceExplicitFunctionLiteralParamWithItIntention() : PsiElementBa
|
||||
public override fun performRefactoring(usages: Array<out UsageInfo>) {
|
||||
super.performRefactoring(usages)
|
||||
|
||||
functionLiteral.deleteChildRange(functionLiteral.getValueParameterList(), functionLiteral.getArrow()!!)
|
||||
functionLiteral.deleteChildRange(functionLiteral.valueParameterList, functionLiteral.arrow!!)
|
||||
|
||||
if (cursorWasInParameterList) {
|
||||
editor.getCaretModel().moveToOffset(functionLiteral.getBodyExpression()!!.getTextOffset())
|
||||
editor.caretModel.moveToOffset(functionLiteral.bodyExpression!!.textOffset)
|
||||
}
|
||||
|
||||
val project = functionLiteral.getProject()
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
CodeStyleManager.getInstance(project).adjustLineIndent(functionLiteral.getContainingFile(), functionLiteral.getTextRange())
|
||||
val project = functionLiteral.project
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
CodeStyleManager.getInstance(project).adjustLineIndent(functionLiteral.containingFile, functionLiteral.textRange)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
+12
-10
@@ -21,13 +21,15 @@ import com.intellij.openapi.editor.Editor
|
||||
import com.intellij.psi.PsiDocumentManager
|
||||
import com.intellij.refactoring.rename.inplace.VariableInplaceRenameHandler
|
||||
import org.jetbrains.kotlin.idea.caches.resolve.analyze
|
||||
import org.jetbrains.kotlin.idea.references.KtReference
|
||||
import org.jetbrains.kotlin.idea.references.mainReference
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.KtFunctionLiteral
|
||||
import org.jetbrains.kotlin.psi.KtLambdaExpression
|
||||
import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.resolve.DescriptorToSourceUtils
|
||||
|
||||
public class ReplaceItWithExplicitFunctionLiteralParamIntention() : SelfTargetingOffsetIndependentIntention<KtNameReferenceExpression> (
|
||||
javaClass(), "Replace 'it' with explicit parameter"
|
||||
KtNameReferenceExpression::class.java, "Replace 'it' with explicit parameter"
|
||||
), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtNameReferenceExpression)
|
||||
= isAutoCreatedItUsage(element)
|
||||
@@ -35,17 +37,17 @@ public class ReplaceItWithExplicitFunctionLiteralParamIntention() : SelfTargetin
|
||||
override fun applyTo(element: KtNameReferenceExpression, editor: Editor) {
|
||||
val target = element.mainReference.resolveToDescriptors(element.analyze()).single()
|
||||
|
||||
val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(target.getContainingDeclaration()!!) as KtFunctionLiteral
|
||||
val functionLiteral = DescriptorToSourceUtils.descriptorToDeclaration(target.containingDeclaration!!) as KtFunctionLiteral
|
||||
|
||||
val newExpr = KtPsiFactory(element).createExpression("{ it -> }") as KtLambdaExpression
|
||||
functionLiteral.addRangeAfter(
|
||||
newExpr.getFunctionLiteral().getValueParameterList(),
|
||||
newExpr.getFunctionLiteral().getArrow()!!,
|
||||
functionLiteral.getLBrace())
|
||||
PsiDocumentManager.getInstance(element.getProject()).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
newExpr.functionLiteral.valueParameterList,
|
||||
newExpr.functionLiteral.arrow!!,
|
||||
functionLiteral.lBrace)
|
||||
PsiDocumentManager.getInstance(element.project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
val paramToRename = functionLiteral.getValueParameters().single()
|
||||
editor.getCaretModel().moveToOffset(element.getTextOffset())
|
||||
val paramToRename = functionLiteral.valueParameters.single()
|
||||
editor.caretModel.moveToOffset(element.textOffset)
|
||||
VariableInplaceRenameHandler().doRename(paramToRename, editor, null)
|
||||
}
|
||||
}
|
||||
|
||||
+20
-21
@@ -31,27 +31,26 @@ import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
public class ReplaceWithOperatorAssignmentInspection : IntentionBasedInspection<KtBinaryExpression>(ReplaceWithOperatorAssignmentIntention())
|
||||
|
||||
public class ReplaceWithOperatorAssignmentIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(javaClass(), "Replace with operator-assignment") {
|
||||
|
||||
public class ReplaceWithOperatorAssignmentIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Replace with operator-assignment") {
|
||||
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
||||
if (element.getOperationToken() != KtTokens.EQ) return false
|
||||
val left = element.getLeft() as? KtNameReferenceExpression ?: return false
|
||||
val right = element.getRight() as? KtBinaryExpression ?: return false
|
||||
if (right.getLeft() == null || right.getRight() == null) return false
|
||||
if (element.operationToken != KtTokens.EQ) return false
|
||||
val left = element.left as? KtNameReferenceExpression ?: return false
|
||||
val right = element.right as? KtBinaryExpression ?: return false
|
||||
if (right.left == null || right.right == null) return false
|
||||
|
||||
return checkExpressionRepeat(left, right)
|
||||
}
|
||||
|
||||
private fun checkExpressionRepeat(variableExpression: KtNameReferenceExpression, expression: KtBinaryExpression): Boolean {
|
||||
val context = expression.analyze()
|
||||
val descriptor = context[BindingContext.REFERENCE_TARGET, expression.getOperationReference()]?.getContainingDeclaration()
|
||||
val isPrimitiveOperation = descriptor is ClassDescriptor && KotlinBuiltIns.isPrimitiveType(descriptor.getDefaultType())
|
||||
val descriptor = context[BindingContext.REFERENCE_TARGET, expression.operationReference]?.containingDeclaration
|
||||
val isPrimitiveOperation = descriptor is ClassDescriptor && KotlinBuiltIns.isPrimitiveType(descriptor.defaultType)
|
||||
|
||||
val operationToken = expression.getOperationToken()
|
||||
setText("Replace with ${expression.getOperationReference().getText()}= expression")
|
||||
val operationToken = expression.operationToken
|
||||
text = "Replace with ${expression.operationReference.text}= expression"
|
||||
|
||||
val expressionLeft = expression.getLeft()
|
||||
val expressionRight = expression.getRight()
|
||||
val expressionLeft = expression.left
|
||||
val expressionRight = expression.right
|
||||
return when {
|
||||
variableExpression.matches(expressionLeft) -> {
|
||||
isArithmeticOperation(operationToken)
|
||||
@@ -62,7 +61,7 @@ public class ReplaceWithOperatorAssignmentIntention : SelfTargetingOffsetIndepen
|
||||
}
|
||||
|
||||
expressionLeft is KtBinaryExpression -> {
|
||||
val sameCommutativeOperation = expressionLeft.getOperationToken() == operationToken && isCommutative(operationToken)
|
||||
val sameCommutativeOperation = expressionLeft.operationToken == operationToken && isCommutative(operationToken)
|
||||
isPrimitiveOperation && sameCommutativeOperation && checkExpressionRepeat(variableExpression, expressionLeft)
|
||||
}
|
||||
|
||||
@@ -81,26 +80,26 @@ public class ReplaceWithOperatorAssignmentIntention : SelfTargetingOffsetIndepen
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
val replacement = buildOperatorAssignmentText(
|
||||
element.getLeft() as KtNameReferenceExpression,
|
||||
element.getRight() as KtBinaryExpression,
|
||||
element.left as KtNameReferenceExpression,
|
||||
element.right as KtBinaryExpression,
|
||||
""
|
||||
)
|
||||
element.replace(KtPsiFactory(element).createExpression(replacement))
|
||||
}
|
||||
|
||||
tailrec private fun buildOperatorAssignmentText(variableExpression: KtNameReferenceExpression, expression: KtBinaryExpression, tail: String): String {
|
||||
val operationText = expression.getOperationReference().getText()
|
||||
val variableName = variableExpression.getText()
|
||||
val operationText = expression.operationReference.text
|
||||
val variableName = variableExpression.text
|
||||
|
||||
fun String.appendTail() = if (tail.isEmpty()) this else "$this $tail"
|
||||
|
||||
return when {
|
||||
variableExpression.matches(expression.getLeft()) -> "$variableName $operationText= ${expression.getRight()!!.getText()}".appendTail()
|
||||
variableExpression.matches(expression.left) -> "$variableName $operationText= ${expression.right!!.text}".appendTail()
|
||||
|
||||
variableExpression.matches(expression.getRight()) -> "$variableName $operationText= ${expression.getLeft()!!.getText()}".appendTail()
|
||||
variableExpression.matches(expression.right) -> "$variableName $operationText= ${expression.left!!.text}".appendTail()
|
||||
|
||||
expression.getLeft() is KtBinaryExpression ->
|
||||
buildOperatorAssignmentText(variableExpression, expression.getLeft() as KtBinaryExpression, "$operationText ${expression.getRight()!!.getText()}".appendTail())
|
||||
expression.left is KtBinaryExpression ->
|
||||
buildOperatorAssignmentText(variableExpression, expression.left as KtBinaryExpression, "$operationText ${expression.right!!.text}".appendTail())
|
||||
|
||||
else -> tail
|
||||
}
|
||||
|
||||
+9
-9
@@ -24,22 +24,22 @@ import org.jetbrains.kotlin.psi.KtNameReferenceExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
|
||||
public class ReplaceWithOrdinaryAssignmentIntention : SelfTargetingIntention<KtBinaryExpression>(javaClass(), "Replace with ordinary assignment"), LowPriorityAction {
|
||||
public class ReplaceWithOrdinaryAssignmentIntention : SelfTargetingIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Replace with ordinary assignment"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtBinaryExpression, caretOffset: Int): Boolean {
|
||||
if (element.getOperationToken() !in KtTokens.AUGMENTED_ASSIGNMENTS) return false
|
||||
if (element.getLeft() !is KtNameReferenceExpression) return false
|
||||
if (element.getRight() == null) return false
|
||||
return element.getOperationReference().getTextRange().containsOffset(caretOffset)
|
||||
if (element.operationToken !in KtTokens.AUGMENTED_ASSIGNMENTS) return false
|
||||
if (element.left !is KtNameReferenceExpression) return false
|
||||
if (element.right == null) return false
|
||||
return element.operationReference.textRange.containsOffset(caretOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
val left = element.getLeft()!!
|
||||
val right = element.getRight()!!
|
||||
val left = element.left!!
|
||||
val right = element.right!!
|
||||
val factory = KtPsiFactory(element)
|
||||
|
||||
val assignOpText = element.getOperationReference().getText()
|
||||
val assignOpText = element.operationReference.text
|
||||
assert(assignOpText.endsWith("="))
|
||||
val operationText = assignOpText.substring(0, assignOpText.length() - 1)
|
||||
val operationText = assignOpText.substring(0, assignOpText.length - 1)
|
||||
|
||||
element.replace(factory.createExpressionByPattern("$0 = $0 $operationText $1", left, right))
|
||||
}
|
||||
|
||||
+12
-12
@@ -30,30 +30,30 @@ import org.jetbrains.kotlin.resolve.DelegatingBindingTrace
|
||||
|
||||
public class SimplifyBooleanWithConstantsInspection : IntentionBasedInspection<KtBinaryExpression>(SimplifyBooleanWithConstantsIntention())
|
||||
|
||||
public class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(javaClass(), "Simplify boolean expression") {
|
||||
public class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndependentIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Simplify boolean expression") {
|
||||
|
||||
override fun isApplicableTo(element: KtBinaryExpression): Boolean {
|
||||
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, javaClass<KtBinaryExpression>()) ?: element
|
||||
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, KtBinaryExpression::class.java) ?: element
|
||||
return areThereExpressionsToBeSimplified(topBinary)
|
||||
}
|
||||
|
||||
private fun areThereExpressionsToBeSimplified(element: KtExpression?) : Boolean {
|
||||
if (element == null) return false
|
||||
when (element) {
|
||||
is KtParenthesizedExpression -> return areThereExpressionsToBeSimplified(element.getExpression())
|
||||
is KtParenthesizedExpression -> return areThereExpressionsToBeSimplified(element.expression)
|
||||
|
||||
is KtBinaryExpression -> {
|
||||
val op = element.getOperationToken()
|
||||
val op = element.operationToken
|
||||
if ((op == KtTokens.ANDAND || op == KtTokens.OROR) &&
|
||||
(areThereExpressionsToBeSimplified(element.getLeft()) ||
|
||||
areThereExpressionsToBeSimplified(element.getRight()))) return true
|
||||
(areThereExpressionsToBeSimplified(element.left) ||
|
||||
areThereExpressionsToBeSimplified(element.right))) return true
|
||||
}
|
||||
}
|
||||
return element.canBeReducedToBooleanConstant(null)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, javaClass<KtBinaryExpression>()) ?: element
|
||||
val topBinary = PsiTreeUtil.getTopmostParentOfType(element, KtBinaryExpression::class.java) ?: element
|
||||
val simplified = toSimplifiedExpression(topBinary)
|
||||
topBinary.replace(KtPsiUtil.safeDeparenthesize(simplified))
|
||||
}
|
||||
@@ -71,7 +71,7 @@ public class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndepend
|
||||
}
|
||||
|
||||
expression is KtParenthesizedExpression -> {
|
||||
val expr = expression.getExpression()
|
||||
val expr = expression.expression
|
||||
if (expr != null) {
|
||||
val simplified = toSimplifiedExpression(expr)
|
||||
return if (simplified is KtBinaryExpression) {
|
||||
@@ -86,9 +86,9 @@ public class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndepend
|
||||
}
|
||||
|
||||
expression is KtBinaryExpression -> {
|
||||
val left = expression.getLeft()
|
||||
val right = expression.getRight()
|
||||
val op = expression.getOperationToken()
|
||||
val left = expression.left
|
||||
val right = expression.right
|
||||
val op = expression.operationToken
|
||||
if (left != null && right != null && (op == KtTokens.ANDAND || op == KtTokens.OROR)) {
|
||||
val simpleLeft = simplifyExpression(left)
|
||||
val simpleRight = simplifyExpression(right)
|
||||
@@ -102,7 +102,7 @@ public class SimplifyBooleanWithConstantsIntention : SelfTargetingOffsetIndepend
|
||||
simpleRight.canBeReducedToFalse() -> toSimplifiedBooleanBinaryExpressionWithConstantOperand(false, simpleLeft, op)
|
||||
|
||||
else -> {
|
||||
val opText = expression.getOperationReference().getText()
|
||||
val opText = expression.operationReference.text
|
||||
psiFactory.createExpressionByPattern("$0 $opText $1", simpleLeft, simpleRight)
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class SimplifyNegatedBinaryExpressionInspection : IntentionBasedInspection<KtPrefixExpression>(SimplifyNegatedBinaryExpressionIntention())
|
||||
|
||||
public class SimplifyNegatedBinaryExpressionIntention : SelfTargetingRangeIntention<KtPrefixExpression>(javaClass(), "Simplify negated binary expression") {
|
||||
public class SimplifyNegatedBinaryExpressionIntention : SelfTargetingRangeIntention<KtPrefixExpression>(KtPrefixExpression::class.java, "Simplify negated binary expression") {
|
||||
|
||||
private fun IElementType.negate(): KtSingleValueToken? = when (this) {
|
||||
KtTokens.IN_KEYWORD -> KtTokens.NOT_IN
|
||||
@@ -48,23 +48,23 @@ public class SimplifyNegatedBinaryExpressionIntention : SelfTargetingRangeIntent
|
||||
}
|
||||
|
||||
override fun applicabilityRange(element: KtPrefixExpression): TextRange? {
|
||||
return if (isApplicableTo(element)) element.getOperationReference().getTextRange() else null
|
||||
return if (isApplicableTo(element)) element.operationReference.textRange else null
|
||||
}
|
||||
|
||||
public fun isApplicableTo(element: KtPrefixExpression): Boolean {
|
||||
if (element.getOperationToken() != KtTokens.EXCL) return false
|
||||
if (element.operationToken != KtTokens.EXCL) return false
|
||||
|
||||
val expression = KtPsiUtil.deparenthesize(element.getBaseExpression()) as? KtOperationExpression ?: return false
|
||||
val expression = KtPsiUtil.deparenthesize(element.baseExpression) as? KtOperationExpression ?: return false
|
||||
when (expression) {
|
||||
is KtIsExpression -> { if (expression.getTypeReference() == null) return false }
|
||||
is KtBinaryExpression -> { if (expression.getLeft() == null || expression.getRight() == null) return false }
|
||||
is KtIsExpression -> { if (expression.typeReference == null) return false }
|
||||
is KtBinaryExpression -> { if (expression.left == null || expression.right == null) return false }
|
||||
else -> return false
|
||||
}
|
||||
|
||||
val operation = expression.getOperationReference().getReferencedNameElementType() as? KtSingleValueToken ?: return false
|
||||
val operation = expression.operationReference.getReferencedNameElementType() as? KtSingleValueToken ?: return false
|
||||
val negatedOperation = operation.negate() ?: return false
|
||||
|
||||
setText("Simplify negated '${operation.getValue()}' expression to '${negatedOperation.getValue()}'")
|
||||
text = "Simplify negated '${operation.value}' expression to '${negatedOperation.value}'"
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -73,13 +73,13 @@ public class SimplifyNegatedBinaryExpressionIntention : SelfTargetingRangeIntent
|
||||
}
|
||||
|
||||
public fun applyTo(element: KtPrefixExpression) {
|
||||
val expression = KtPsiUtil.deparenthesize(element.getBaseExpression())!!
|
||||
val operation = (expression as KtOperationExpression).getOperationReference().getReferencedNameElementType().negate()!!.getValue()
|
||||
val expression = KtPsiUtil.deparenthesize(element.baseExpression)!!
|
||||
val operation = (expression as KtOperationExpression).operationReference.getReferencedNameElementType().negate()!!.value
|
||||
|
||||
val psiFactory = KtPsiFactory(expression)
|
||||
val newExpression = when (expression) {
|
||||
is KtIsExpression -> psiFactory.createExpressionByPattern("$0 $1 $2", expression.getLeftHandSide(), operation, expression.getTypeReference()!!)
|
||||
is KtBinaryExpression -> psiFactory.createExpressionByPattern("$0 $1 $2", expression.getLeft()!!, operation, expression.getRight()!!)
|
||||
is KtIsExpression -> psiFactory.createExpressionByPattern("$0 $1 $2", expression.leftHandSide, operation, expression.typeReference!!)
|
||||
is KtBinaryExpression -> psiFactory.createExpressionByPattern("$0 $1 $2", expression.left!!, operation, expression.right!!)
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
element.replace(newExpression)
|
||||
|
||||
+14
-14
@@ -27,40 +27,40 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.resolve.BindingContext
|
||||
|
||||
public class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaExpression>(javaClass(), "Specify explicit lambda signature"), LowPriorityAction {
|
||||
public class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<KtLambdaExpression>(KtLambdaExpression::class.java, "Specify explicit lambda signature"), LowPriorityAction {
|
||||
|
||||
override fun isApplicableTo(element: KtLambdaExpression, caretOffset: Int): Boolean {
|
||||
val arrow = element.getFunctionLiteral().getArrow()
|
||||
val arrow = element.functionLiteral.arrow
|
||||
if (arrow != null) {
|
||||
if (caretOffset > arrow.endOffset) return false
|
||||
if (element.getValueParameters().all { it.getTypeReference() != null }) return false
|
||||
if (element.valueParameters.all { it.typeReference != null }) return false
|
||||
}
|
||||
else {
|
||||
if (!element.getLeftCurlyBrace().getTextRange().containsOffset(caretOffset)) return false
|
||||
if (!element.leftCurlyBrace.textRange.containsOffset(caretOffset)) return false
|
||||
}
|
||||
|
||||
val functionDescriptor = element.analyze()[BindingContext.FUNCTION, element.getFunctionLiteral()] ?: return false
|
||||
return functionDescriptor.getValueParameters().none { it.getType().isError() }
|
||||
val functionDescriptor = element.analyze()[BindingContext.FUNCTION, element.functionLiteral] ?: return false
|
||||
return functionDescriptor.valueParameters.none { it.type.isError }
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtLambdaExpression, editor: Editor) {
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
val functionLiteral = element.getFunctionLiteral()
|
||||
val functionLiteral = element.functionLiteral
|
||||
val functionDescriptor = element.analyze()[BindingContext.FUNCTION, functionLiteral]!!
|
||||
|
||||
val parameterString = functionDescriptor.getValueParameters()
|
||||
.map { "${it.getName()}: ${IdeDescriptorRenderers.SOURCE_CODE.renderType(it.getType())}" }
|
||||
val parameterString = functionDescriptor.valueParameters
|
||||
.map { "${it.name}: ${IdeDescriptorRenderers.SOURCE_CODE.renderType(it.type)}" }
|
||||
.joinToString(", ")
|
||||
|
||||
val newParameterList = psiFactory.createFunctionLiteralParameterList(parameterString)
|
||||
val oldParameterList = functionLiteral.getValueParameterList()
|
||||
val oldParameterList = functionLiteral.valueParameterList
|
||||
if (oldParameterList != null) {
|
||||
oldParameterList.replace(newParameterList)
|
||||
}
|
||||
else {
|
||||
val openBraceElement = functionLiteral.getLBrace()
|
||||
val nextSibling = openBraceElement.getNextSibling()
|
||||
val addNewline = nextSibling is PsiWhiteSpace && nextSibling.getText()?.contains("\n") ?: false
|
||||
val openBraceElement = functionLiteral.lBrace
|
||||
val nextSibling = openBraceElement.nextSibling
|
||||
val addNewline = nextSibling is PsiWhiteSpace && nextSibling.text?.contains("\n") ?: false
|
||||
val (whitespace, arrow) = psiFactory.createWhitespaceAndArrow()
|
||||
functionLiteral.addRangeAfter(whitespace, arrow, openBraceElement)
|
||||
functionLiteral.addAfter(newParameterList, openBraceElement)
|
||||
@@ -68,6 +68,6 @@ public class SpecifyExplicitLambdaSignatureIntention : SelfTargetingIntention<Kt
|
||||
functionLiteral.addAfter(psiFactory.createNewLine(), openBraceElement)
|
||||
}
|
||||
}
|
||||
ShortenReferences.DEFAULT.process(element.getValueParameters())
|
||||
ShortenReferences.DEFAULT.process(element.valueParameters)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,21 +34,21 @@ import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.kotlin.types.TypeUtils
|
||||
import java.util.*
|
||||
|
||||
public class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableDeclaration>(javaClass(), "Specify type explicitly"), LowPriorityAction {
|
||||
public class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableDeclaration>(KtCallableDeclaration::class.java, "Specify type explicitly"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtCallableDeclaration, caretOffset: Int): Boolean {
|
||||
if (element.getContainingFile() is KtCodeFragment) return false
|
||||
if (element.containingFile is KtCodeFragment) return false
|
||||
if (element is KtFunctionLiteral) return false // TODO: should JetFunctionLiteral be JetCallableDeclaration at all?
|
||||
if (element is KtConstructor<*>) return false
|
||||
if (element.getTypeReference() != null) return false
|
||||
if (element.typeReference != null) return false
|
||||
|
||||
if (getTypeForDeclaration(element).isError()) return false
|
||||
if (getTypeForDeclaration(element).isError) return false
|
||||
|
||||
val initializer = (element as? KtWithExpressionInitializer)?.getInitializer()
|
||||
if (initializer != null && initializer.getTextRange().containsOffset(caretOffset)) return false
|
||||
val initializer = (element as? KtWithExpressionInitializer)?.initializer
|
||||
if (initializer != null && initializer.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
if (element is KtNamedFunction && element.hasBlockBody()) return false
|
||||
|
||||
setText(if (element is KtFunction) "Specify return type explicitly" else "Specify type explicitly")
|
||||
text = if (element is KtFunction) "Specify return type explicitly" else "Specify type explicitly"
|
||||
|
||||
return true
|
||||
}
|
||||
@@ -61,12 +61,12 @@ public class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableD
|
||||
companion object {
|
||||
public fun getTypeForDeclaration(declaration: KtCallableDeclaration): KotlinType {
|
||||
val descriptor = declaration.analyze()[BindingContext.DECLARATION_TO_DESCRIPTOR, declaration]
|
||||
val type = (descriptor as? CallableDescriptor)?.getReturnType()
|
||||
val type = (descriptor as? CallableDescriptor)?.returnType
|
||||
return type ?: ErrorUtils.createErrorType("null type")
|
||||
}
|
||||
|
||||
public fun createTypeExpressionForTemplate(exprType: KotlinType): Expression {
|
||||
val descriptor = exprType.getConstructor().getDeclarationDescriptor()
|
||||
val descriptor = exprType.constructor.declarationDescriptor
|
||||
val isAnonymous = descriptor != null && DescriptorUtils.isAnonymousObject(descriptor)
|
||||
|
||||
val allSupertypes = TypeUtils.getAllSupertypes(exprType)
|
||||
@@ -91,8 +91,8 @@ public class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableD
|
||||
public fun createTypeReferencePostprocessor(declaration: KtCallableDeclaration): TemplateEditingAdapter {
|
||||
return object : TemplateEditingAdapter() {
|
||||
override fun templateFinished(template: Template?, brokenOff: Boolean) {
|
||||
val typeRef = declaration.getTypeReference()
|
||||
if (typeRef != null && typeRef.isValid()) {
|
||||
val typeRef = declaration.typeReference
|
||||
if (typeRef != null && typeRef.isValid) {
|
||||
ShortenReferences.DEFAULT.process(typeRef)
|
||||
}
|
||||
}
|
||||
@@ -100,21 +100,21 @@ public class SpecifyTypeExplicitlyIntention : SelfTargetingIntention<KtCallableD
|
||||
}
|
||||
|
||||
private fun addTypeAnnotationWithTemplate(editor: Editor, declaration: KtCallableDeclaration, exprType: KotlinType) {
|
||||
assert(!exprType.isError()) { "Unexpected error type, should have been checked before: " + declaration.getElementTextWithContext() + ", type = " + exprType }
|
||||
assert(!exprType.isError) { "Unexpected error type, should have been checked before: " + declaration.getElementTextWithContext() + ", type = " + exprType }
|
||||
|
||||
val project = declaration.getProject()
|
||||
val project = declaration.project
|
||||
val expression = createTypeExpressionForTemplate(exprType)
|
||||
|
||||
declaration.setType(KotlinBuiltIns.FQ_NAMES.any.asString())
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments()
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
val newTypeRef = declaration.getTypeReference()!!
|
||||
val newTypeRef = declaration.typeReference!!
|
||||
val builder = TemplateBuilderImpl(newTypeRef)
|
||||
builder.replaceElement(newTypeRef, expression)
|
||||
|
||||
editor.getCaretModel().moveToOffset(newTypeRef.getNode().getStartOffset())
|
||||
editor.caretModel.moveToOffset(newTypeRef.node.startOffset)
|
||||
|
||||
TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), createTypeReferencePostprocessor(declaration))
|
||||
}
|
||||
|
||||
@@ -29,11 +29,11 @@ import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType
|
||||
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class SplitIfIntention : SelfTargetingIntention<KtExpression>(javaClass(), "Split if into 2 if's") {
|
||||
public class SplitIfIntention : SelfTargetingIntention<KtExpression>(KtExpression::class.java, "Split if into 2 if's") {
|
||||
override fun isApplicableTo(element: KtExpression, caretOffset: Int): Boolean {
|
||||
return when (element) {
|
||||
is KtOperationReferenceExpression -> isOperatorValid(element)
|
||||
is KtIfExpression -> getFirstValidOperator(element) != null && element.getIfKeyword().getTextRange().containsOffset(caretOffset)
|
||||
is KtIfExpression -> getFirstValidOperator(element) != null && element.ifKeyword.textRange.containsOffset(caretOffset)
|
||||
else -> false
|
||||
}
|
||||
}
|
||||
@@ -48,11 +48,11 @@ public class SplitIfIntention : SelfTargetingIntention<KtExpression>(javaClass()
|
||||
|
||||
val commentSaver = CommentSaver(ifExpression!!)
|
||||
|
||||
val expression = operator.getParent() as KtBinaryExpression
|
||||
val rightExpression = KtPsiUtil.safeDeparenthesize(getRight(expression, ifExpression.getCondition()!!, commentSaver))
|
||||
val leftExpression = KtPsiUtil.safeDeparenthesize(expression.getLeft()!!)
|
||||
val thenBranch = ifExpression.getThen()!!
|
||||
val elseBranch = ifExpression.getElse()
|
||||
val expression = operator.parent as KtBinaryExpression
|
||||
val rightExpression = KtPsiUtil.safeDeparenthesize(getRight(expression, ifExpression.condition!!, commentSaver))
|
||||
val leftExpression = KtPsiUtil.safeDeparenthesize(expression.left!!)
|
||||
val thenBranch = ifExpression.then!!
|
||||
val elseBranch = ifExpression.`else`
|
||||
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
|
||||
@@ -62,7 +62,7 @@ public class SplitIfIntention : SelfTargetingIntention<KtExpression>(javaClass()
|
||||
KtTokens.ANDAND -> psiFactory.createIf(leftExpression, psiFactory.createSingleStatementBlock(innerIf), elseBranch)
|
||||
|
||||
KtTokens.OROR -> {
|
||||
val container = ifExpression.getParent()
|
||||
val container = ifExpression.parent
|
||||
|
||||
if (container is KtBlockExpression && elseBranch == null && thenBranch.lastBlockStatementOrThis().isExitStatement()) { // special case
|
||||
val secondIf = container.addAfter(innerIf, ifExpression)
|
||||
@@ -86,9 +86,9 @@ public class SplitIfIntention : SelfTargetingIntention<KtExpression>(javaClass()
|
||||
private fun getRight(element: KtBinaryExpression, condition: KtExpression, commentSaver: CommentSaver): KtExpression {
|
||||
//gets the textOffset of the right side of the JetBinaryExpression in context to condition
|
||||
val conditionRange = condition.range
|
||||
val startOffset = element.getRight()!!.startOffset - conditionRange.start
|
||||
val startOffset = element.right!!.startOffset - conditionRange.start
|
||||
val endOffset = conditionRange.length
|
||||
val rightString = condition.getText().substring(startOffset, endOffset)
|
||||
val rightString = condition.text.substring(startOffset, endOffset)
|
||||
|
||||
val expression = KtPsiFactory(element).createExpression(rightString)
|
||||
commentSaver.elementCreatedByText(expression, condition, TextRange(startOffset, endOffset))
|
||||
@@ -96,8 +96,8 @@ public class SplitIfIntention : SelfTargetingIntention<KtExpression>(javaClass()
|
||||
}
|
||||
|
||||
private fun getFirstValidOperator(element: KtIfExpression): KtOperationReferenceExpression? {
|
||||
val condition = element.getCondition() ?: return null
|
||||
return PsiTreeUtil.findChildrenOfType(condition, javaClass<KtOperationReferenceExpression>())
|
||||
val condition = element.condition ?: return null
|
||||
return PsiTreeUtil.findChildrenOfType(condition, KtOperationReferenceExpression::class.java)
|
||||
.firstOrNull { isOperatorValid(it) }
|
||||
}
|
||||
|
||||
@@ -105,21 +105,21 @@ public class SplitIfIntention : SelfTargetingIntention<KtExpression>(javaClass()
|
||||
val operator = element.getReferencedNameElementType()
|
||||
if (operator != KtTokens.ANDAND && operator != KtTokens.OROR) return false
|
||||
|
||||
var expression = element.getParent() as? KtBinaryExpression ?: return false
|
||||
var expression = element.parent as? KtBinaryExpression ?: return false
|
||||
|
||||
if (expression.getRight() == null || expression.getLeft() == null) return false
|
||||
if (expression.right == null || expression.left == null) return false
|
||||
|
||||
while (true) {
|
||||
expression = expression.getParent() as? KtBinaryExpression ?: break
|
||||
if (expression.getOperationToken() != operator) return false
|
||||
expression = expression.parent as? KtBinaryExpression ?: break
|
||||
if (expression.operationToken != operator) return false
|
||||
}
|
||||
|
||||
val ifExpression = expression.getParent()?.getParent() as? KtIfExpression ?: return false
|
||||
val ifExpression = expression.parent?.parent as? KtIfExpression ?: return false
|
||||
|
||||
if (ifExpression.getCondition() == null) return false
|
||||
if (!PsiTreeUtil.isAncestor(ifExpression.getCondition(), element, false)) return false
|
||||
if (ifExpression.condition == null) return false
|
||||
if (!PsiTreeUtil.isAncestor(ifExpression.condition, element, false)) return false
|
||||
|
||||
if (ifExpression.getThen() == null) return false
|
||||
if (ifExpression.then == null) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
import org.jetbrains.kotlin.idea.core.copied
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
public class SwapBinaryExpressionIntention : SelfTargetingIntention<KtBinaryExpression>(javaClass(), "Flip binary expression"), LowPriorityAction {
|
||||
public class SwapBinaryExpressionIntention : SelfTargetingIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Flip binary expression"), LowPriorityAction {
|
||||
companion object {
|
||||
private val SUPPORTED_OPERATIONS = setOf(PLUS, MUL, OROR, ANDAND, EQEQ, EXCLEQ, EQEQEQ, EXCLEQEQEQ, GT, LT, GTEQ, LTEQ)
|
||||
|
||||
@@ -36,18 +36,18 @@ public class SwapBinaryExpressionIntention : SelfTargetingIntention<KtBinaryExpr
|
||||
}
|
||||
|
||||
override fun isApplicableTo(element: KtBinaryExpression, caretOffset: Int): Boolean {
|
||||
val opRef = element.getOperationReference()
|
||||
if (!opRef.getTextRange().containsOffset(caretOffset)) return false
|
||||
val opRef = element.operationReference
|
||||
if (!opRef.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
if (leftSubject(element) == null || rightSubject(element) == null) {
|
||||
return false
|
||||
}
|
||||
|
||||
val operationToken = element.getOperationToken()
|
||||
val operationTokenText = opRef.getText()
|
||||
val operationToken = element.operationToken
|
||||
val operationTokenText = opRef.text
|
||||
if (operationToken in SUPPORTED_OPERATIONS
|
||||
|| operationToken == IDENTIFIER && operationTokenText in SUPPORTED_OPERATION_NAMES) {
|
||||
setText("Flip '$operationTokenText'")
|
||||
text = "Flip '$operationTokenText'"
|
||||
return true
|
||||
}
|
||||
return false
|
||||
@@ -55,7 +55,7 @@ public class SwapBinaryExpressionIntention : SelfTargetingIntention<KtBinaryExpr
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
// Have to use text here to preserve names like "plus"
|
||||
val operator = element.getOperationReference().getText()!!
|
||||
val operator = element.operationReference.text!!
|
||||
val convertedOperator = when (operator) {
|
||||
">" -> "<"
|
||||
"<" -> ">"
|
||||
@@ -69,15 +69,15 @@ public class SwapBinaryExpressionIntention : SelfTargetingIntention<KtBinaryExpr
|
||||
val leftCopy = left.copied()
|
||||
left.replace(rightCopy)
|
||||
right.replace(leftCopy)
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $convertedOperator $1" , element.getLeft()!!, element.getRight()!!))
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $convertedOperator $1", element.left!!, element.right!!))
|
||||
}
|
||||
|
||||
private fun leftSubject(element: KtBinaryExpression): KtExpression? {
|
||||
return firstDescendantOfTighterPrecedence(element.getLeft(), PsiPrecedences.getPrecedence(element), KtBinaryExpression::getRight)
|
||||
return firstDescendantOfTighterPrecedence(element.left, PsiPrecedences.getPrecedence(element), KtBinaryExpression::getRight)
|
||||
}
|
||||
|
||||
private fun rightSubject(element: KtBinaryExpression): KtExpression? {
|
||||
return firstDescendantOfTighterPrecedence(element.getRight(), PsiPrecedences.getPrecedence(element), KtBinaryExpression::getLeft)
|
||||
return firstDescendantOfTighterPrecedence(element.right, PsiPrecedences.getPrecedence(element), KtBinaryExpression::getLeft)
|
||||
}
|
||||
|
||||
private fun firstDescendantOfTighterPrecedence(expression: KtExpression?, precedence: Int, getChild: KtBinaryExpression.() -> KtExpression?): KtExpression? {
|
||||
|
||||
@@ -23,16 +23,16 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
|
||||
public class ToInfixCallIntention : SelfTargetingIntention<KtCallExpression>(javaClass(), "Replace with infix function call") {
|
||||
public class ToInfixCallIntention : SelfTargetingIntention<KtCallExpression>(KtCallExpression::class.java, "Replace with infix function call") {
|
||||
override fun isApplicableTo(element: KtCallExpression, caretOffset: Int): Boolean {
|
||||
val calleeExpr = element.getCalleeExpression() as? KtNameReferenceExpression ?: return false
|
||||
if (!calleeExpr.getTextRange().containsOffset(caretOffset)) return false
|
||||
val calleeExpr = element.calleeExpression as? KtNameReferenceExpression ?: return false
|
||||
if (!calleeExpr.textRange.containsOffset(caretOffset)) return false
|
||||
|
||||
val dotQualified = element.getParent() as? KtDotQualifiedExpression ?: return false
|
||||
val dotQualified = element.parent as? KtDotQualifiedExpression ?: return false
|
||||
|
||||
if (element.getTypeArgumentList() != null) return false
|
||||
if (element.typeArgumentList != null) return false
|
||||
|
||||
val argument = element.getValueArguments().singleOrNull() ?: return false
|
||||
val argument = element.valueArguments.singleOrNull() ?: return false
|
||||
if (argument.isNamed()) return false
|
||||
if (argument.getArgumentExpression() == null) return false
|
||||
|
||||
@@ -48,10 +48,10 @@ public class ToInfixCallIntention : SelfTargetingIntention<KtCallExpression>(jav
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtCallExpression, editor: Editor) {
|
||||
val dotQualified = element.getParent() as KtDotQualifiedExpression
|
||||
val receiver = dotQualified.getReceiverExpression()
|
||||
val argument = element.getValueArguments().single().getArgumentExpression()!!
|
||||
val name = element.getCalleeExpression()!!.getText()
|
||||
val dotQualified = element.parent as KtDotQualifiedExpression
|
||||
val receiver = dotQualified.receiverExpression
|
||||
val argument = element.valueArguments.single().getArgumentExpression()!!
|
||||
val name = element.calleeExpression!!.text
|
||||
|
||||
val newCall = KtPsiFactory(element).createExpressionByPattern("$0 $name $1", receiver, argument)
|
||||
dotQualified.replace(newCall)
|
||||
|
||||
@@ -55,7 +55,7 @@ import org.jetbrains.kotlin.types.TypeUtils
|
||||
|
||||
class UsePropertyAccessSyntaxInspection : IntentionBasedInspection<KtCallExpression>(UsePropertyAccessSyntaxIntention()), CleanupLocalInspectionTool
|
||||
|
||||
class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention<KtCallExpression>(javaClass(), "Use property access syntax") {
|
||||
class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention<KtCallExpression>(KtCallExpression::class.java, "Use property access syntax") {
|
||||
override fun isApplicableTo(element: KtCallExpression): Boolean {
|
||||
return detectPropertyNameToUse(element) != null
|
||||
}
|
||||
@@ -65,8 +65,8 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
||||
}
|
||||
|
||||
public fun applyTo(element: KtCallExpression, propertyName: Name): KtExpression {
|
||||
val arguments = element.getValueArguments()
|
||||
return when (arguments.size()) {
|
||||
val arguments = element.valueArguments
|
||||
return when (arguments.size) {
|
||||
0 -> replaceWithPropertyGet(element, propertyName)
|
||||
1 -> replaceWithPropertySet(element, propertyName, arguments.single())
|
||||
else -> error("More than one argument in call to accessor")
|
||||
@@ -74,16 +74,16 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
||||
}
|
||||
|
||||
public fun detectPropertyNameToUse(callExpression: KtCallExpression): Name? {
|
||||
if (callExpression.getQualifiedExpressionForSelector()?.getReceiverExpression() is KtSuperExpression) return null // cannot call extensions on "super"
|
||||
if (callExpression.getQualifiedExpressionForSelector()?.receiverExpression is KtSuperExpression) return null // cannot call extensions on "super"
|
||||
|
||||
val callee = callExpression.getCalleeExpression() as? KtNameReferenceExpression ?: return null
|
||||
val callee = callExpression.calleeExpression as? KtNameReferenceExpression ?: return null
|
||||
|
||||
val resolutionFacade = callExpression.getResolutionFacade()
|
||||
val bindingContext = resolutionFacade.analyze(callExpression, BodyResolveMode.PARTIAL)
|
||||
val resolvedCall = callExpression.getResolvedCall(bindingContext) ?: return null
|
||||
if (!resolvedCall.isReallySuccess()) return null
|
||||
|
||||
val function = resolvedCall.getResultingDescriptor() as? FunctionDescriptor ?: return null
|
||||
val function = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null
|
||||
val resolutionScope = callExpression.getResolutionScope(bindingContext, resolutionFacade)
|
||||
val property = findSyntheticProperty(function, resolutionScope) ?: return null
|
||||
|
||||
@@ -93,7 +93,7 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
||||
|
||||
if (!checkWillResolveToProperty(resolvedCall, property, bindingContext, resolutionScope, dataFlowInfo, expectedType, resolutionFacade)) return null
|
||||
|
||||
val isSetUsage = callExpression.valueArguments.size() == 1
|
||||
val isSetUsage = callExpression.valueArguments.size == 1
|
||||
if (isSetUsage && property.type != function.valueParameters.single().type) {
|
||||
val qualifiedExpressionCopy = qualifiedExpression.copied()
|
||||
val callExpressionCopy = ((qualifiedExpressionCopy as? KtQualifiedExpression)?.selectorExpression ?: qualifiedExpressionCopy) as KtCallExpression
|
||||
@@ -144,7 +144,7 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
||||
private fun findSyntheticProperty(function: FunctionDescriptor, resolutionScope: LexicalScope): SyntheticJavaPropertyDescriptor? {
|
||||
SyntheticJavaPropertyDescriptor.findByGetterOrSetter(function, resolutionScope)?.let { return it }
|
||||
|
||||
for (overridden in function.getOverriddenDescriptors()) {
|
||||
for (overridden in function.overriddenDescriptors) {
|
||||
findSyntheticProperty(overridden, resolutionScope)?.let { return it }
|
||||
}
|
||||
|
||||
@@ -167,7 +167,7 @@ class UsePropertyAccessSyntaxIntention : SelfTargetingOffsetIndependentIntention
|
||||
}
|
||||
val newExpression = KtPsiFactory(callExpression).createExpressionByPattern(
|
||||
pattern,
|
||||
qualifiedExpression.getReceiverExpression(),
|
||||
qualifiedExpression.receiverExpression,
|
||||
propertyName,
|
||||
argument.getArgumentExpression()!!
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
|
||||
fun KtCallableDeclaration.setType(type: KotlinType, shortenReferences: Boolean = true) {
|
||||
if (type.isError()) return
|
||||
if (type.isError) return
|
||||
setType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type), shortenReferences)
|
||||
}
|
||||
|
||||
@@ -49,18 +49,18 @@ fun KtCallableDeclaration.setType(typeString: String, shortenReferences: Boolean
|
||||
}
|
||||
|
||||
fun KtCallableDeclaration.setReceiverType(type: KotlinType) {
|
||||
if (type.isError()) return
|
||||
val typeReference = KtPsiFactory(getProject()).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
|
||||
if (type.isError) return
|
||||
val typeReference = KtPsiFactory(project).createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type))
|
||||
setReceiverTypeReference(typeReference)
|
||||
ShortenReferences.DEFAULT.process(getReceiverTypeReference()!!)
|
||||
ShortenReferences.DEFAULT.process(receiverTypeReference!!)
|
||||
}
|
||||
|
||||
fun KtContainerNode.description(): String? {
|
||||
when (getNode().getElementType()) {
|
||||
when (node.elementType) {
|
||||
KtNodeTypes.THEN -> return "if"
|
||||
KtNodeTypes.ELSE -> return "else"
|
||||
KtNodeTypes.BODY -> {
|
||||
when (getParent()) {
|
||||
when (parent) {
|
||||
is KtWhileExpression -> return "while"
|
||||
is KtDoWhileExpression -> return "do...while"
|
||||
is KtForExpression -> return "for"
|
||||
@@ -79,14 +79,14 @@ fun isAutoCreatedItUsage(expression: KtNameReferenceExpression): Boolean {
|
||||
|
||||
// returns assignment which replaces initializer
|
||||
fun splitPropertyDeclaration(property: KtProperty): KtBinaryExpression {
|
||||
val parent = property.getParent()!!
|
||||
val parent = property.parent!!
|
||||
|
||||
val initializer = property.getInitializer()!!
|
||||
val initializer = property.initializer!!
|
||||
|
||||
val explicitTypeToSet = if (property.getTypeReference() != null) null else initializer.analyze().getType(initializer)
|
||||
val explicitTypeToSet = if (property.typeReference != null) null else initializer.analyze().getType(initializer)
|
||||
|
||||
val psiFactory = KtPsiFactory(property)
|
||||
var assignment = psiFactory.createExpressionByPattern("$0 = $1", property.getNameAsName()!!, initializer)
|
||||
var assignment = psiFactory.createExpressionByPattern("$0 = $1", property.nameAsName!!, initializer)
|
||||
|
||||
assignment = parent.addAfter(assignment, property) as KtBinaryExpression
|
||||
parent.addAfter(psiFactory.createNewLine(), property)
|
||||
@@ -101,10 +101,10 @@ fun splitPropertyDeclaration(property: KtProperty): KtBinaryExpression {
|
||||
}
|
||||
|
||||
val KtQualifiedExpression.callExpression: KtCallExpression?
|
||||
get() = getSelectorExpression() as? KtCallExpression
|
||||
get() = selectorExpression as? KtCallExpression
|
||||
|
||||
val KtQualifiedExpression.calleeName: String?
|
||||
get() = (callExpression?.getCalleeExpression() as? KtNameReferenceExpression)?.getText()
|
||||
get() = (callExpression?.calleeExpression as? KtNameReferenceExpression)?.text
|
||||
|
||||
fun KtQualifiedExpression.toResolvedCall(bodyResolveMode: BodyResolveMode): ResolvedCall<out CallableDescriptor>? {
|
||||
val callExpression = callExpression ?: return null
|
||||
@@ -120,7 +120,7 @@ fun KtExpression.isExitStatement(): Boolean {
|
||||
|
||||
// returns false for call of super, static method or method from package
|
||||
fun KtQualifiedExpression.isReceiverExpressionWithValue(): Boolean {
|
||||
val receiver = getReceiverExpression()
|
||||
val receiver = receiverExpression
|
||||
if (receiver is KtSuperExpression) return false
|
||||
return analyze().getType(receiver) != null
|
||||
}
|
||||
@@ -135,8 +135,8 @@ private fun KtExpression.specialNegation(): KtExpression? {
|
||||
val factory = KtPsiFactory(this)
|
||||
when (this) {
|
||||
is KtPrefixExpression -> {
|
||||
if (getOperationReference().getReferencedName() == "!") {
|
||||
val baseExpression = getBaseExpression()
|
||||
if (operationReference.getReferencedName() == "!") {
|
||||
val baseExpression = baseExpression
|
||||
if (baseExpression != null) {
|
||||
val context = baseExpression.analyzeAndGetResult().bindingContext
|
||||
val type = context.getType(baseExpression)
|
||||
@@ -148,15 +148,15 @@ private fun KtExpression.specialNegation(): KtExpression? {
|
||||
}
|
||||
|
||||
is KtBinaryExpression -> {
|
||||
val operator = getOperationToken()
|
||||
val operator = operationToken
|
||||
if (operator !in NEGATABLE_OPERATORS) return null
|
||||
val left = getLeft() ?: return null
|
||||
val right = getRight() ?: return null
|
||||
val left = left ?: return null
|
||||
val right = right ?: return null
|
||||
return factory.createExpressionByPattern("$0 $1 $2", left, getNegatedOperatorText(operator), right)
|
||||
}
|
||||
|
||||
is KtConstantExpression -> {
|
||||
return when (getText()) {
|
||||
return when (text) {
|
||||
"true" -> factory.createExpression("false")
|
||||
"false" -> factory.createExpression("true")
|
||||
else -> null
|
||||
@@ -172,18 +172,18 @@ private val NEGATABLE_OPERATORS = setOf(KtTokens.EQEQ, KtTokens.EXCLEQ, KtTokens
|
||||
|
||||
private fun getNegatedOperatorText(token: IElementType): String {
|
||||
return when(token) {
|
||||
KtTokens.EQEQ -> KtTokens.EXCLEQ.getValue()
|
||||
KtTokens.EXCLEQ -> KtTokens.EQEQ.getValue()
|
||||
KtTokens.EQEQEQ -> KtTokens.EXCLEQEQEQ.getValue()
|
||||
KtTokens.EXCLEQEQEQ -> KtTokens.EQEQEQ.getValue()
|
||||
KtTokens.IS_KEYWORD -> KtTokens.NOT_IS.getValue()
|
||||
KtTokens.NOT_IS -> KtTokens.IS_KEYWORD.getValue()
|
||||
KtTokens.IN_KEYWORD -> KtTokens.NOT_IN.getValue()
|
||||
KtTokens.NOT_IN -> KtTokens.IN_KEYWORD.getValue()
|
||||
KtTokens.LT -> KtTokens.GTEQ.getValue()
|
||||
KtTokens.LTEQ -> KtTokens.GT.getValue()
|
||||
KtTokens.GT -> KtTokens.LTEQ.getValue()
|
||||
KtTokens.GTEQ -> KtTokens.LT.getValue()
|
||||
KtTokens.EQEQ -> KtTokens.EXCLEQ.value
|
||||
KtTokens.EXCLEQ -> KtTokens.EQEQ.value
|
||||
KtTokens.EQEQEQ -> KtTokens.EXCLEQEQEQ.value
|
||||
KtTokens.EXCLEQEQEQ -> KtTokens.EQEQEQ.value
|
||||
KtTokens.IS_KEYWORD -> KtTokens.NOT_IS.value
|
||||
KtTokens.NOT_IS -> KtTokens.IS_KEYWORD.value
|
||||
KtTokens.IN_KEYWORD -> KtTokens.NOT_IN.value
|
||||
KtTokens.NOT_IN -> KtTokens.IN_KEYWORD.value
|
||||
KtTokens.LT -> KtTokens.GTEQ.value
|
||||
KtTokens.LTEQ -> KtTokens.GT.value
|
||||
KtTokens.GT -> KtTokens.LTEQ.value
|
||||
KtTokens.GTEQ -> KtTokens.LT.value
|
||||
else -> throw IllegalArgumentException("The token $token does not have a negated equivalent.")
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -24,14 +24,14 @@ import org.jetbrains.kotlin.utils.addToStdlib.check
|
||||
object BranchedFoldingUtils {
|
||||
public fun getFoldableBranchedAssignment(branch: KtExpression?): KtBinaryExpression? {
|
||||
fun checkAssignment(expression: KtBinaryExpression): Boolean {
|
||||
if (expression.getOperationToken() !in KtTokens.ALL_ASSIGNMENTS) return false
|
||||
if (expression.operationToken !in KtTokens.ALL_ASSIGNMENTS) return false
|
||||
|
||||
val left = expression.getLeft() as? KtNameReferenceExpression ?: return false
|
||||
if (expression.getRight() == null) return false
|
||||
val left = expression.left as? KtNameReferenceExpression ?: return false
|
||||
if (expression.right == null) return false
|
||||
|
||||
val parent = expression.getParent()
|
||||
val parent = expression.parent
|
||||
if (parent is KtBlockExpression) {
|
||||
return !KtPsiUtil.checkVariableDeclarationInBlock(parent, left.getText())
|
||||
return !KtPsiUtil.checkVariableDeclarationInBlock(parent, left.text)
|
||||
}
|
||||
|
||||
return true
|
||||
@@ -40,10 +40,10 @@ object BranchedFoldingUtils {
|
||||
}
|
||||
|
||||
public fun getFoldableBranchedReturn(branch: KtExpression?): KtReturnExpression? {
|
||||
return (branch?.lastBlockStatementOrThis() as? KtReturnExpression)?.check { it.getReturnedExpression() != null }
|
||||
return (branch?.lastBlockStatementOrThis() as? KtReturnExpression)?.check { it.returnedExpression != null }
|
||||
}
|
||||
|
||||
public fun checkAssignmentsMatch(a1: KtBinaryExpression, a2: KtBinaryExpression): Boolean {
|
||||
return a1.getLeft()?.getText() == a2.getLeft()?.getText() && a1.getOperationToken() == a2.getOperationToken()
|
||||
return a1.left?.text == a2.left?.text && a1.operationToken == a2.operationToken
|
||||
}
|
||||
}
|
||||
|
||||
+12
-12
@@ -23,14 +23,14 @@ import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||
|
||||
public object BranchedUnfoldingUtils {
|
||||
public fun unfoldAssignmentToIf(assignment: KtBinaryExpression, editor: Editor) {
|
||||
val op = assignment.getOperationReference().getText()
|
||||
val left = assignment.getLeft()!!
|
||||
val ifExpression = assignment.getRight() as KtIfExpression
|
||||
val op = assignment.operationReference.text
|
||||
val left = assignment.left!!
|
||||
val ifExpression = assignment.right as KtIfExpression
|
||||
|
||||
val newIfExpression = ifExpression.copied()
|
||||
|
||||
val thenExpr = newIfExpression.getThen()!!.lastBlockStatementOrThis()
|
||||
val elseExpr = newIfExpression.getElse()!!.lastBlockStatementOrThis()
|
||||
val thenExpr = newIfExpression.then!!.lastBlockStatementOrThis()
|
||||
val elseExpr = newIfExpression.`else`!!.lastBlockStatementOrThis()
|
||||
|
||||
val psiFactory = KtPsiFactory(assignment)
|
||||
thenExpr.replace(psiFactory.createExpressionByPattern("$0 $1 $2", left, op, thenExpr))
|
||||
@@ -38,23 +38,23 @@ public object BranchedUnfoldingUtils {
|
||||
|
||||
val resultIf = assignment.replace(newIfExpression)
|
||||
|
||||
editor.getCaretModel().moveToOffset(resultIf.getTextOffset())
|
||||
editor.caretModel.moveToOffset(resultIf.textOffset)
|
||||
}
|
||||
|
||||
public fun unfoldAssignmentToWhen(assignment: KtBinaryExpression, editor: Editor) {
|
||||
val op = assignment.getOperationReference().getText()
|
||||
val left = assignment.getLeft()!!
|
||||
val whenExpression = assignment.getRight() as KtWhenExpression
|
||||
val op = assignment.operationReference.text
|
||||
val left = assignment.left!!
|
||||
val whenExpression = assignment.right as KtWhenExpression
|
||||
|
||||
val newWhenExpression = whenExpression.copied()
|
||||
|
||||
for (entry in newWhenExpression.getEntries()) {
|
||||
val expr = entry.getExpression()!!.lastBlockStatementOrThis()
|
||||
for (entry in newWhenExpression.entries) {
|
||||
val expr = entry.expression!!.lastBlockStatementOrThis()
|
||||
expr.replace(KtPsiFactory(assignment).createExpressionByPattern("$0 $1 $2", left, op, expr))
|
||||
}
|
||||
|
||||
val resultWhen = assignment.replace(newWhenExpression)
|
||||
|
||||
editor.getCaretModel().moveToOffset(resultWhen.getTextOffset())
|
||||
editor.caretModel.moveToOffset(resultWhen.textOffset)
|
||||
}
|
||||
}
|
||||
|
||||
+17
-17
@@ -38,11 +38,11 @@ val NULL_PTR_EXCEPTION_FQ = "java.lang.NullPointerException"
|
||||
val KOTLIN_NULL_PTR_EXCEPTION_FQ = "kotlin.KotlinNullPointerException"
|
||||
|
||||
fun KtBinaryExpression.expressionComparedToNull(): KtExpression? {
|
||||
val operationToken = this.getOperationToken()
|
||||
val operationToken = this.operationToken
|
||||
if (operationToken != KtTokens.EQEQ && operationToken != KtTokens.EXCLEQ) return null
|
||||
|
||||
val right = this.getRight() ?: return null
|
||||
val left = this.getLeft() ?: return null
|
||||
val right = this.right ?: return null
|
||||
val left = this.left ?: return null
|
||||
|
||||
val rightIsNull = right.isNullExpression()
|
||||
val leftIsNull = left.isNullExpression()
|
||||
@@ -53,31 +53,31 @@ fun KtBinaryExpression.expressionComparedToNull(): KtExpression? {
|
||||
fun KtExpression.unwrapBlockOrParenthesis(): KtExpression {
|
||||
val innerExpression = KtPsiUtil.safeDeparenthesize(this)
|
||||
if (innerExpression is KtBlockExpression) {
|
||||
val statement = innerExpression.getStatements().singleOrNull() ?: return this
|
||||
val statement = innerExpression.statements.singleOrNull() ?: return this
|
||||
return KtPsiUtil.safeDeparenthesize(statement)
|
||||
}
|
||||
return innerExpression
|
||||
}
|
||||
|
||||
fun KtExpression?.isNullExpression(): Boolean = this?.unwrapBlockOrParenthesis()?.getNode()?.getElementType() == KtNodeTypes.NULL
|
||||
fun KtExpression?.isNullExpression(): Boolean = this?.unwrapBlockOrParenthesis()?.node?.elementType == KtNodeTypes.NULL
|
||||
|
||||
fun KtExpression?.isNullExpressionOrEmptyBlock(): Boolean = this.isNullExpression() || this is KtBlockExpression && this.getStatements().isEmpty()
|
||||
fun KtExpression?.isNullExpressionOrEmptyBlock(): Boolean = this.isNullExpression() || this is KtBlockExpression && this.statements.isEmpty()
|
||||
|
||||
fun KtThrowExpression.throwsNullPointerExceptionWithNoArguments(): Boolean {
|
||||
val thrownExpression = this.getThrownExpression()
|
||||
val thrownExpression = this.thrownExpression
|
||||
if (thrownExpression !is KtCallExpression) return false
|
||||
|
||||
val context = this.analyze(BodyResolveMode.PARTIAL)
|
||||
val nameExpression = thrownExpression.calleeExpression as? KtNameReferenceExpression ?: return false
|
||||
val descriptor = context[BindingContext.REFERENCE_TARGET, nameExpression]
|
||||
val declDescriptor = descriptor?.getContainingDeclaration() ?: return false
|
||||
val declDescriptor = descriptor?.containingDeclaration ?: return false
|
||||
|
||||
val exceptionName = DescriptorUtils.getFqName(declDescriptor).asString()
|
||||
return (exceptionName == NULL_PTR_EXCEPTION_FQ || exceptionName == KOTLIN_NULL_PTR_EXCEPTION_FQ) && thrownExpression.getValueArguments().isEmpty()
|
||||
return (exceptionName == NULL_PTR_EXCEPTION_FQ || exceptionName == KOTLIN_NULL_PTR_EXCEPTION_FQ) && thrownExpression.valueArguments.isEmpty()
|
||||
}
|
||||
|
||||
fun KtExpression.evaluatesTo(other: KtExpression): Boolean {
|
||||
return this.unwrapBlockOrParenthesis().getText() == other.getText()
|
||||
return this.unwrapBlockOrParenthesis().text == other.text
|
||||
}
|
||||
|
||||
fun KtExpression.convertToIfNotNullExpression(conditionLhs: KtExpression, thenClause: KtExpression, elseClause: KtExpression?): KtIfExpression {
|
||||
@@ -95,8 +95,8 @@ fun KtExpression.convertToIfStatement(condition: KtExpression, thenClause: KtExp
|
||||
}
|
||||
|
||||
fun KtIfExpression.introduceValueForCondition(occurrenceInThenClause: KtExpression, editor: Editor) {
|
||||
val project = this.getProject()
|
||||
val occurrenceInConditional = (this.getCondition() as KtBinaryExpression).getLeft()!!
|
||||
val project = this.project
|
||||
val occurrenceInConditional = (this.condition as KtBinaryExpression).left!!
|
||||
KotlinIntroduceVariableHandler.doRefactoring(project,
|
||||
editor,
|
||||
occurrenceInConditional,
|
||||
@@ -114,21 +114,21 @@ fun KtNameReferenceExpression.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(e
|
||||
val scope = LocalSearchScope(enclosingElement!!)
|
||||
|
||||
val references = ReferencesSearch.search(declaration, scope).findAll()
|
||||
if (references.size() == 1) {
|
||||
KotlinInlineValHandler().inlineElement(this.getProject(), editor, declaration)
|
||||
if (references.size == 1) {
|
||||
KotlinInlineValHandler().inlineElement(this.project, editor, declaration)
|
||||
}
|
||||
}
|
||||
|
||||
fun KtSafeQualifiedExpression.inlineReceiverIfApplicableWithPrompt(editor: Editor) {
|
||||
(this.getReceiverExpression() as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
(this.receiverExpression as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
}
|
||||
|
||||
fun KtBinaryExpression.inlineLeftSideIfApplicableWithPrompt(editor: Editor) {
|
||||
(this.getLeft() as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
(this.left as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
}
|
||||
|
||||
fun KtPostfixExpression.inlineBaseExpressionIfApplicableWithPrompt(editor: Editor) {
|
||||
(this.getBaseExpression() as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
(this.baseExpression as? KtNameReferenceExpression)?.inlineIfDeclaredLocallyAndOnlyUsedOnceWithPrompt(editor)
|
||||
}
|
||||
|
||||
fun KtExpression.isStableVariable(): Boolean {
|
||||
|
||||
+25
-25
@@ -25,21 +25,21 @@ fun KtWhenCondition.toExpression(subject: KtExpression?): KtExpression {
|
||||
val factory = KtPsiFactory(this)
|
||||
when (this) {
|
||||
is KtWhenConditionIsPattern -> {
|
||||
val op = if (isNegated()) "!is" else "is"
|
||||
return factory.createExpressionByPattern("$0 $op $1", subject ?: "_", getTypeReference() ?: "")
|
||||
val op = if (isNegated) "!is" else "is"
|
||||
return factory.createExpressionByPattern("$0 $op $1", subject ?: "_", typeReference ?: "")
|
||||
}
|
||||
|
||||
is KtWhenConditionInRange -> {
|
||||
val op = getOperationReference().getText()
|
||||
return factory.createExpressionByPattern("$0 $op $1", subject ?: "_", getRangeExpression() ?: "")
|
||||
val op = operationReference.text
|
||||
return factory.createExpressionByPattern("$0 $op $1", subject ?: "_", rangeExpression ?: "")
|
||||
}
|
||||
|
||||
is KtWhenConditionWithExpression -> {
|
||||
return if (subject != null) {
|
||||
factory.createExpressionByPattern("$0 == $1", subject, getExpression() ?: "")
|
||||
factory.createExpressionByPattern("$0 == $1", subject, expression ?: "")
|
||||
}
|
||||
else {
|
||||
getExpression()!!
|
||||
expression!!
|
||||
}
|
||||
}
|
||||
|
||||
@@ -48,17 +48,17 @@ fun KtWhenCondition.toExpression(subject: KtExpression?): KtExpression {
|
||||
}
|
||||
|
||||
public fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
||||
if (getSubjectExpression() != null) return null
|
||||
if (subjectExpression != null) return null
|
||||
|
||||
var lastCandidate: KtExpression? = null
|
||||
for (entry in getEntries()) {
|
||||
val conditions = entry.getConditions()
|
||||
if (!entry.isElse() && conditions.isEmpty()) return null
|
||||
for (entry in entries) {
|
||||
val conditions = entry.conditions
|
||||
if (!entry.isElse && conditions.isEmpty()) return null
|
||||
|
||||
for (condition in conditions) {
|
||||
if (condition !is KtWhenConditionWithExpression) return null
|
||||
|
||||
val candidate = condition.getExpression()?.getWhenConditionSubjectCandidate() as? KtNameReferenceExpression ?: return null
|
||||
val candidate = condition.expression?.getWhenConditionSubjectCandidate() as? KtNameReferenceExpression ?: return null
|
||||
|
||||
if (lastCandidate == null) {
|
||||
lastCandidate = candidate
|
||||
@@ -75,14 +75,14 @@ public fun KtWhenExpression.getSubjectToIntroduce(): KtExpression? {
|
||||
|
||||
private fun KtExpression?.getWhenConditionSubjectCandidate(): KtExpression? {
|
||||
return when(this) {
|
||||
is KtIsExpression -> getLeftHandSide()
|
||||
is KtIsExpression -> leftHandSide
|
||||
|
||||
is KtBinaryExpression -> {
|
||||
val lhs = getLeft()
|
||||
val op = getOperationToken()
|
||||
val lhs = left
|
||||
val op = operationToken
|
||||
when (op) {
|
||||
KtTokens.IN_KEYWORD, KtTokens.NOT_IN -> lhs
|
||||
KtTokens.EQEQ -> lhs as? KtNameReferenceExpression ?: getRight()
|
||||
KtTokens.EQEQ -> lhs as? KtNameReferenceExpression ?: right
|
||||
KtTokens.OROR -> {
|
||||
val leftCandidate = lhs.getWhenConditionSubjectCandidate()
|
||||
val rightCandidate = right.getWhenConditionSubjectCandidate()
|
||||
@@ -103,17 +103,17 @@ public fun KtWhenExpression.introduceSubject(): KtWhenExpression {
|
||||
val whenExpression = KtPsiFactory(this).buildExpression {
|
||||
appendFixedText("when(").appendExpression(subject).appendFixedText("){\n")
|
||||
|
||||
for (entry in getEntries()) {
|
||||
val branchExpression = entry.getExpression()
|
||||
for (entry in entries) {
|
||||
val branchExpression = entry.expression
|
||||
|
||||
if (entry.isElse()) {
|
||||
if (entry.isElse) {
|
||||
appendFixedText("else")
|
||||
}
|
||||
else {
|
||||
for ((i, condition) in entry.getConditions().withIndex()) {
|
||||
for ((i, condition) in entry.conditions.withIndex()) {
|
||||
if (i > 0) appendFixedText(",")
|
||||
|
||||
val conditionExpression = (condition as KtWhenConditionWithExpression).getExpression()
|
||||
val conditionExpression = (condition as KtWhenConditionWithExpression).expression
|
||||
appendConditionWithSubjectRemoved(conditionExpression, subject)
|
||||
}
|
||||
}
|
||||
@@ -132,17 +132,17 @@ public fun KtWhenExpression.introduceSubject(): KtWhenExpression {
|
||||
private fun BuilderByPattern<KtExpression>.appendConditionWithSubjectRemoved(conditionExpression: KtExpression?, subject: KtExpression) {
|
||||
when (conditionExpression) {
|
||||
is KtIsExpression -> {
|
||||
if (conditionExpression.isNegated()) {
|
||||
if (conditionExpression.isNegated) {
|
||||
appendFixedText("!")
|
||||
}
|
||||
appendFixedText("is ")
|
||||
appendNonFormattedText(conditionExpression.getTypeReference()?.getText() ?: "")
|
||||
appendNonFormattedText(conditionExpression.typeReference?.text ?: "")
|
||||
}
|
||||
|
||||
is KtBinaryExpression -> {
|
||||
val lhs = conditionExpression.getLeft()
|
||||
val rhs = conditionExpression.getRight()
|
||||
val op = conditionExpression.getOperationToken()
|
||||
val lhs = conditionExpression.left
|
||||
val rhs = conditionExpression.right
|
||||
val op = conditionExpression.operationToken
|
||||
when (op) {
|
||||
KtTokens.IN_KEYWORD -> appendFixedText("in ").appendExpression(rhs)
|
||||
KtTokens.NOT_IN -> appendFixedText("!in ").appendExpression(rhs)
|
||||
|
||||
+11
-11
@@ -39,17 +39,17 @@ import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
import org.jetbrains.kotlin.psi.KtThrowExpression
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
|
||||
public class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpression>(javaClass(), "Replace '!!' expression with 'if' expression"), LowPriorityAction {
|
||||
public class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfixExpression>(KtPostfixExpression::class.java, "Replace '!!' expression with 'if' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtPostfixExpression): TextRange? {
|
||||
return if (element.getOperationToken() == KtTokens.EXCLEXCL && element.getBaseExpression() != null)
|
||||
element.getOperationReference().getTextRange()
|
||||
return if (element.operationToken == KtTokens.EXCLEXCL && element.baseExpression != null)
|
||||
element.operationReference.textRange
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtPostfixExpression, editor: Editor) {
|
||||
val base = KtPsiUtil.safeDeparenthesize(element.getBaseExpression()!!)
|
||||
val expressionText = formatForUseInExceptionArgument(base.getText()!!)
|
||||
val base = KtPsiUtil.safeDeparenthesize(element.baseExpression!!)
|
||||
val expressionText = formatForUseInExceptionArgument(base.text!!)
|
||||
|
||||
val defaultException = KtPsiFactory(element).createExpression("throw NullPointerException()")
|
||||
|
||||
@@ -62,25 +62,25 @@ public class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfix
|
||||
element.convertToIfNotNullExpression(base, base, defaultException)
|
||||
|
||||
val thrownExpression =
|
||||
((if (isStatement) ifStatement.getThen() else ifStatement.getElse()) as KtThrowExpression).getThrownExpression()!!
|
||||
((if (isStatement) ifStatement.then else ifStatement.`else`) as KtThrowExpression).thrownExpression!!
|
||||
|
||||
val message = escapeJava("Expression '$expressionText' must not be null")
|
||||
val nullPtrExceptionText = "NullPointerException(\"$message\")"
|
||||
val kotlinNullPtrExceptionText = "KotlinNullPointerException()"
|
||||
|
||||
val exceptionLookupExpression = ChooseStringExpression(listOf(nullPtrExceptionText, kotlinNullPtrExceptionText))
|
||||
val project = element.getProject()
|
||||
val project = element.project
|
||||
val builder = TemplateBuilderImpl(thrownExpression)
|
||||
builder.replaceElement(thrownExpression, exceptionLookupExpression);
|
||||
|
||||
PsiDocumentManager.getInstance(project).commitAllDocuments();
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument());
|
||||
editor.getCaretModel().moveToOffset(thrownExpression.getNode()!!.getStartOffset());
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document);
|
||||
editor.caretModel.moveToOffset(thrownExpression.node!!.startOffset);
|
||||
|
||||
TemplateManager.getInstance(project).startTemplate(editor, builder.buildInlineTemplate(), object: TemplateEditingAdapter() {
|
||||
override fun templateFinished(template: Template?, brokenOff: Boolean) {
|
||||
if (!isStable && !isStatement) {
|
||||
ifStatement.introduceValueForCondition(ifStatement.getThen()!!, editor)
|
||||
ifStatement.introduceValueForCondition(ifStatement.then!!, editor)
|
||||
}
|
||||
}
|
||||
})
|
||||
@@ -88,7 +88,7 @@ public class DoubleBangToIfThenIntention : SelfTargetingRangeIntention<KtPostfix
|
||||
|
||||
private fun formatForUseInExceptionArgument(expressionText: String): String {
|
||||
val lines = expressionText.split('\n')
|
||||
return if (lines.size() > 1)
|
||||
return if (lines.size > 1)
|
||||
lines.first().trim() + " ..."
|
||||
else
|
||||
expressionText.trim()
|
||||
|
||||
+7
-7
@@ -26,23 +26,23 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
import org.jetbrains.kotlin.psi.buildExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class EliminateWhenSubjectIntention : SelfTargetingIntention<KtWhenExpression>(javaClass(), "Eliminate argument of 'when'"), LowPriorityAction {
|
||||
public class EliminateWhenSubjectIntention : SelfTargetingIntention<KtWhenExpression>(KtWhenExpression::class.java, "Eliminate argument of 'when'"), LowPriorityAction {
|
||||
override fun isApplicableTo(element: KtWhenExpression, caretOffset: Int): Boolean {
|
||||
if (element.getSubjectExpression() !is KtNameReferenceExpression) return false
|
||||
val lBrace = element.getOpenBrace() ?: return false
|
||||
if (element.subjectExpression !is KtNameReferenceExpression) return false
|
||||
val lBrace = element.openBrace ?: return false
|
||||
return caretOffset <= lBrace.startOffset
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
val subject = element.getSubjectExpression()!!
|
||||
val subject = element.subjectExpression!!
|
||||
|
||||
val whenExpression = KtPsiFactory(element).buildExpression {
|
||||
appendFixedText("when {\n")
|
||||
|
||||
for (entry in element.getEntries()) {
|
||||
val branchExpression = entry.getExpression()
|
||||
for (entry in element.entries) {
|
||||
val branchExpression = entry.expression
|
||||
|
||||
if (entry.isElse()) {
|
||||
if (entry.isElse) {
|
||||
appendFixedText("else")
|
||||
}
|
||||
else {
|
||||
|
||||
+6
-6
@@ -27,24 +27,24 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.KtBinaryExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiUtil
|
||||
|
||||
public class ElvisToIfThenIntention : SelfTargetingRangeIntention<KtBinaryExpression>(javaClass(), "Replace elvis expression with 'if' expression"), LowPriorityAction {
|
||||
public class ElvisToIfThenIntention : SelfTargetingRangeIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Replace elvis expression with 'if' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtBinaryExpression): TextRange? {
|
||||
return if (element.getOperationToken() == KtTokens.ELVIS && element.getLeft() != null && element.getRight() != null)
|
||||
element.getOperationReference().getTextRange()
|
||||
return if (element.operationToken == KtTokens.ELVIS && element.left != null && element.right != null)
|
||||
element.operationReference.textRange
|
||||
else
|
||||
null
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
val left = KtPsiUtil.safeDeparenthesize(element.getLeft()!!)
|
||||
val right = KtPsiUtil.safeDeparenthesize(element.getRight()!!)
|
||||
val left = KtPsiUtil.safeDeparenthesize(element.left!!)
|
||||
val right = KtPsiUtil.safeDeparenthesize(element.right!!)
|
||||
|
||||
val leftIsStable = left.isStableVariable()
|
||||
|
||||
val ifStatement = element.convertToIfNotNullExpression(left, left, right)
|
||||
|
||||
if (!leftIsStable) {
|
||||
ifStatement.introduceValueForCondition(ifStatement.getThen()!!, editor)
|
||||
ifStatement.introduceValueForCondition(ifStatement.then!!, editor)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+15
-15
@@ -25,29 +25,29 @@ import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class FlattenWhenIntention : SelfTargetingIntention<KtWhenExpression>(javaClass(), "Flatten 'when' expression") {
|
||||
public class FlattenWhenIntention : SelfTargetingIntention<KtWhenExpression>(KtWhenExpression::class.java, "Flatten 'when' expression") {
|
||||
override fun isApplicableTo(element: KtWhenExpression, caretOffset: Int): Boolean {
|
||||
val subject = element.getSubjectExpression()
|
||||
val subject = element.subjectExpression
|
||||
if (subject != null && subject !is KtNameReferenceExpression) return false
|
||||
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(element)) return false
|
||||
|
||||
val elseEntry = element.getEntries().singleOrNull { it.isElse() } ?: return false
|
||||
val elseEntry = element.entries.singleOrNull { it.isElse } ?: return false
|
||||
|
||||
val innerWhen = elseEntry.getExpression() as? KtWhenExpression ?: return false
|
||||
val innerWhen = elseEntry.expression as? KtWhenExpression ?: return false
|
||||
|
||||
if (!subject.matches(innerWhen.getSubjectExpression())) return false
|
||||
if (!subject.matches(innerWhen.subjectExpression)) return false
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(innerWhen)) return false
|
||||
|
||||
return elseEntry.startOffset <= caretOffset && caretOffset <= innerWhen.getWhenKeyword().endOffset
|
||||
return elseEntry.startOffset <= caretOffset && caretOffset <= innerWhen.whenKeyword.endOffset
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
val subjectExpression = element.getSubjectExpression()
|
||||
val nestedWhen = element.getElseExpression() as KtWhenExpression
|
||||
val subjectExpression = element.subjectExpression
|
||||
val nestedWhen = element.elseExpression as KtWhenExpression
|
||||
|
||||
val outerEntries = element.getEntries()
|
||||
val innerEntries = nestedWhen.getEntries()
|
||||
val outerEntries = element.entries
|
||||
val innerEntries = nestedWhen.entries
|
||||
|
||||
val whenExpression = KtPsiFactory(element).buildExpression {
|
||||
appendFixedText("when")
|
||||
@@ -57,12 +57,12 @@ public class FlattenWhenIntention : SelfTargetingIntention<KtWhenExpression>(jav
|
||||
appendFixedText("{\n")
|
||||
|
||||
for (entry in outerEntries) {
|
||||
if (entry.isElse()) continue
|
||||
appendNonFormattedText(entry.getText())
|
||||
if (entry.isElse) continue
|
||||
appendNonFormattedText(entry.text)
|
||||
appendFixedText("\n")
|
||||
}
|
||||
for (entry in innerEntries) {
|
||||
appendNonFormattedText(entry.getText())
|
||||
appendNonFormattedText(entry.text)
|
||||
appendFixedText("\n")
|
||||
}
|
||||
|
||||
@@ -71,7 +71,7 @@ public class FlattenWhenIntention : SelfTargetingIntention<KtWhenExpression>(jav
|
||||
|
||||
val newWhen = element.replaced(whenExpression)
|
||||
|
||||
val firstNewEntry = newWhen.getEntries()[outerEntries.size() - 1]
|
||||
editor.moveCaret(firstNewEntry.getTextOffset())
|
||||
val firstNewEntry = newWhen.entries[outerEntries.size - 1]
|
||||
editor.moveCaret(firstNewEntry.textOffset)
|
||||
}
|
||||
}
|
||||
|
||||
+10
-10
@@ -24,23 +24,23 @@ import org.jetbrains.kotlin.psi.KtIfExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
|
||||
public class FoldIfToAssignmentIntention : SelfTargetingRangeIntention<KtIfExpression>(javaClass(), "Replace 'if' expression with assignment") {
|
||||
public class FoldIfToAssignmentIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' expression with assignment") {
|
||||
override fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||
val thenAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.getThen()) ?: return null
|
||||
val elseAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.getElse()) ?: return null
|
||||
val thenAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.then) ?: return null
|
||||
val elseAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.`else`) ?: return null
|
||||
if (!BranchedFoldingUtils.checkAssignmentsMatch(thenAssignment, elseAssignment)) return null
|
||||
return element.getIfKeyword().getTextRange()
|
||||
return element.ifKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
var thenAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.getThen()!!)!!
|
||||
val elseAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.getElse()!!)!!
|
||||
var thenAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.then!!)!!
|
||||
val elseAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.`else`!!)!!
|
||||
|
||||
val op = thenAssignment.getOperationReference().getText()
|
||||
val leftText = thenAssignment.getLeft()!!.getText()
|
||||
val op = thenAssignment.operationReference.text
|
||||
val leftText = thenAssignment.left!!.text
|
||||
|
||||
thenAssignment.replace(thenAssignment.getRight()!!)
|
||||
elseAssignment.replace(elseAssignment.getRight()!!)
|
||||
thenAssignment.replace(thenAssignment.right!!)
|
||||
elseAssignment.replace(elseAssignment.right!!)
|
||||
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $1 $2", leftText, op, element))
|
||||
}
|
||||
|
||||
+10
-10
@@ -22,30 +22,30 @@ import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class FoldIfToReturnAsymmetricallyIntention : SelfTargetingRangeIntention<KtIfExpression>(javaClass(), "Replace 'if' expression with return") {
|
||||
public class FoldIfToReturnAsymmetricallyIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' expression with return") {
|
||||
override fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.getThen()) == null || element.getElse() != null) {
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.then) == null || element.`else` != null) {
|
||||
return null
|
||||
}
|
||||
|
||||
val nextElement = KtPsiUtil.skipTrailingWhitespacesAndComments(element) as? KtReturnExpression
|
||||
if (nextElement?.getReturnedExpression() == null) return null
|
||||
return element.getIfKeyword().getTextRange()
|
||||
if (nextElement?.returnedExpression == null) return null
|
||||
return element.ifKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
val condition = element.getCondition()!!
|
||||
val thenBranch = element.getThen()!!
|
||||
val condition = element.condition!!
|
||||
val thenBranch = element.then!!
|
||||
val elseBranch = KtPsiUtil.skipTrailingWhitespacesAndComments(element) as KtReturnExpression
|
||||
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
var newIfExpression = psiFactory.createIf(condition, thenBranch, elseBranch)
|
||||
|
||||
val thenReturn = BranchedFoldingUtils.getFoldableBranchedReturn(newIfExpression.getThen()!!)!!
|
||||
val elseReturn = BranchedFoldingUtils.getFoldableBranchedReturn(newIfExpression.getElse()!!)!!
|
||||
val thenReturn = BranchedFoldingUtils.getFoldableBranchedReturn(newIfExpression.then!!)!!
|
||||
val elseReturn = BranchedFoldingUtils.getFoldableBranchedReturn(newIfExpression.`else`!!)!!
|
||||
|
||||
thenReturn.replace(thenReturn.getReturnedExpression()!!)
|
||||
elseReturn.replace(elseReturn.getReturnedExpression()!!)
|
||||
thenReturn.replace(thenReturn.returnedExpression!!)
|
||||
elseReturn.replace(elseReturn.returnedExpression!!)
|
||||
|
||||
element.replace(psiFactory.createExpressionByPattern("return $0", newIfExpression))
|
||||
elseBranch.delete()
|
||||
|
||||
+8
-8
@@ -24,19 +24,19 @@ import org.jetbrains.kotlin.psi.KtIfExpression
|
||||
import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
|
||||
public class FoldIfToReturnIntention : SelfTargetingRangeIntention<KtIfExpression>(javaClass(), "Replace 'if' expression with return") {
|
||||
public class FoldIfToReturnIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' expression with return") {
|
||||
override fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.getThen()) == null) return null
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.getElse()) == null) return null
|
||||
return element.getIfKeyword().getTextRange()
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.then) == null) return null
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(element.`else`) == null) return null
|
||||
return element.ifKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
val thenReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.getThen()!!)!!
|
||||
val elseReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.getElse()!!)!!
|
||||
val thenReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.then!!)!!
|
||||
val elseReturn = BranchedFoldingUtils.getFoldableBranchedReturn(element.`else`!!)!!
|
||||
|
||||
thenReturn.replace(thenReturn.getReturnedExpression()!!)
|
||||
elseReturn.replace(elseReturn.getReturnedExpression()!!)
|
||||
thenReturn.replace(thenReturn.returnedExpression!!)
|
||||
elseReturn.replace(elseReturn.returnedExpression!!)
|
||||
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("return $0", element))
|
||||
}
|
||||
|
||||
+13
-13
@@ -23,44 +23,44 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFold
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.*
|
||||
|
||||
public class FoldWhenToAssignmentIntention : SelfTargetingRangeIntention<KtWhenExpression>(javaClass(), "Replace 'when' expression with assignment") {
|
||||
public class FoldWhenToAssignmentIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenExpression::class.java, "Replace 'when' expression with assignment") {
|
||||
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(element)) return null
|
||||
|
||||
val entries = element.getEntries()
|
||||
val entries = element.entries
|
||||
|
||||
if (entries.isEmpty()) return null
|
||||
|
||||
val assignments = ArrayList<KtBinaryExpression>()
|
||||
for (entry in entries) {
|
||||
val assignment = BranchedFoldingUtils.getFoldableBranchedAssignment(entry.getExpression()) ?: return null
|
||||
val assignment = BranchedFoldingUtils.getFoldableBranchedAssignment(entry.expression) ?: return null
|
||||
assignments.add(assignment)
|
||||
}
|
||||
|
||||
assert(!assignments.isEmpty())
|
||||
|
||||
val firstAssignment = assignments.get(0)
|
||||
val firstAssignment = assignments.first()
|
||||
for (assignment in assignments) {
|
||||
if (!BranchedFoldingUtils.checkAssignmentsMatch(assignment, firstAssignment)) return null
|
||||
}
|
||||
|
||||
return element.getWhenKeyword().getTextRange()
|
||||
return element.whenKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
assert(!element.getEntries().isEmpty())
|
||||
assert(!element.entries.isEmpty())
|
||||
|
||||
val firstAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.getEntries().get(0).getExpression()!!)!!
|
||||
val firstAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(element.entries.first().expression!!)!!
|
||||
|
||||
val op = firstAssignment.getOperationReference().getText()
|
||||
val lhs = firstAssignment.getLeft() as KtNameReferenceExpression
|
||||
val op = firstAssignment.operationReference.text
|
||||
val lhs = firstAssignment.left as KtNameReferenceExpression
|
||||
|
||||
val assignment = KtPsiFactory(element).createExpressionByPattern("$0 $1 $2", lhs, op, element)
|
||||
val newWhenExpression = (assignment as KtBinaryExpression).getRight() as KtWhenExpression
|
||||
val newWhenExpression = (assignment as KtBinaryExpression).right as KtWhenExpression
|
||||
|
||||
for (entry in newWhenExpression.getEntries()) {
|
||||
val currAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(entry.getExpression()!!)!!
|
||||
val currRhs = currAssignment.getRight()!!
|
||||
for (entry in newWhenExpression.entries) {
|
||||
val currAssignment = BranchedFoldingUtils.getFoldableBranchedAssignment(entry.expression!!)!!
|
||||
val currRhs = currAssignment.right!!
|
||||
currAssignment.replace(currRhs)
|
||||
}
|
||||
|
||||
|
||||
+9
-9
@@ -22,30 +22,30 @@ import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.BranchedFoldingUtils
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class FoldWhenToReturnIntention : SelfTargetingRangeIntention<KtWhenExpression>(javaClass(), "Replace 'when' expression with return") {
|
||||
public class FoldWhenToReturnIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenExpression::class.java, "Replace 'when' expression with return") {
|
||||
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(element)) return null
|
||||
|
||||
val entries = element.getEntries()
|
||||
val entries = element.entries
|
||||
|
||||
if (entries.isEmpty()) return null
|
||||
|
||||
for (entry in entries) {
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(entry.getExpression()) == null) return null
|
||||
if (BranchedFoldingUtils.getFoldableBranchedReturn(entry.expression) == null) return null
|
||||
}
|
||||
|
||||
return element.getWhenKeyword().getTextRange()
|
||||
return element.whenKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
assert(!element.getEntries().isEmpty())
|
||||
assert(!element.entries.isEmpty())
|
||||
|
||||
val newReturnExpression = KtPsiFactory(element).createExpressionByPattern("return $0", element) as KtReturnExpression
|
||||
val newWhenExpression = newReturnExpression.getReturnedExpression() as KtWhenExpression
|
||||
val newWhenExpression = newReturnExpression.returnedExpression as KtWhenExpression
|
||||
|
||||
for (entry in newWhenExpression.getEntries()) {
|
||||
val currReturn = BranchedFoldingUtils.getFoldableBranchedReturn(entry.getExpression()!!)!!
|
||||
val currExpr = currReturn.getReturnedExpression()!!
|
||||
for (entry in newWhenExpression.entries) {
|
||||
val currReturn = BranchedFoldingUtils.getFoldableBranchedReturn(entry.expression!!)!!
|
||||
val currExpr = currReturn.returnedExpression!!
|
||||
currReturn.replace(currExpr)
|
||||
}
|
||||
|
||||
|
||||
+7
-7
@@ -27,15 +27,15 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
|
||||
public class IfThenToDoubleBangIntention : SelfTargetingRangeIntention<KtIfExpression>(javaClass(), "Replace 'if' expression with '!!' expression") {
|
||||
public class IfThenToDoubleBangIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' expression with '!!' expression") {
|
||||
override fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||
val condition = element.getCondition() as? KtBinaryExpression ?: return null
|
||||
val thenClause = element.getThen() ?: return null
|
||||
val elseClause = element.getElse()
|
||||
val condition = element.condition as? KtBinaryExpression ?: return null
|
||||
val thenClause = element.then ?: return null
|
||||
val elseClause = element.`else`
|
||||
|
||||
val expression = condition.expressionComparedToNull() ?: return null
|
||||
|
||||
val token = condition.getOperationToken()
|
||||
val token = condition.operationToken
|
||||
|
||||
val throwExpression: KtThrowExpression
|
||||
val matchingClause: KtExpression?
|
||||
@@ -62,12 +62,12 @@ public class IfThenToDoubleBangIntention : SelfTargetingRangeIntention<KtIfExpre
|
||||
}
|
||||
|
||||
setText(text)
|
||||
val rParen = element.getRightParenthesis() ?: return null
|
||||
val rParen = element.rightParenthesis ?: return null
|
||||
return TextRange(element.startOffset, rParen.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
val condition = element.getCondition() as KtBinaryExpression
|
||||
val condition = element.condition as KtBinaryExpression
|
||||
val expression = condition.expressionComparedToNull()!!
|
||||
val result = element.replace(KtPsiFactory(element).createExpressionByPattern("$0!!", expression)) as KtPostfixExpression
|
||||
|
||||
|
||||
+10
-10
@@ -27,17 +27,17 @@ import org.jetbrains.kotlin.idea.core.replaced
|
||||
|
||||
public class IfThenToElvisInspection : IntentionBasedInspection<KtIfExpression>(IfThenToElvisIntention())
|
||||
|
||||
public class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<KtIfExpression>(javaClass(), "Replace 'if' expression with elvis expression") {
|
||||
public class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' expression with elvis expression") {
|
||||
|
||||
override fun isApplicableTo(element: KtIfExpression): Boolean {
|
||||
val condition = element.getCondition() as? KtBinaryExpression ?: return false
|
||||
val thenClause = element.getThen() ?: return false
|
||||
val elseClause = element.getElse() ?: return false
|
||||
val condition = element.condition as? KtBinaryExpression ?: return false
|
||||
val thenClause = element.then ?: return false
|
||||
val elseClause = element.`else` ?: return false
|
||||
|
||||
val expression = condition.expressionComparedToNull() ?: return false
|
||||
if (!expression.isStableVariable()) return false
|
||||
|
||||
return when (condition.getOperationToken()) {
|
||||
return when (condition.operationToken) {
|
||||
KtTokens.EQEQ ->
|
||||
thenClause.isNotNullExpression() && elseClause.evaluatesTo(expression) &&
|
||||
!(thenClause is KtThrowExpression && thenClause.throwsNullPointerExceptionWithNoArguments())
|
||||
@@ -53,7 +53,7 @@ public class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<Kt
|
||||
|
||||
private fun KtExpression.isNotNullExpression(): Boolean {
|
||||
val innerExpression = this.unwrapBlockOrParenthesis()
|
||||
return innerExpression !is KtBlockExpression && innerExpression.getNode().getElementType() != KtNodeTypes.NULL
|
||||
return innerExpression !is KtBlockExpression && innerExpression.node.elementType != KtNodeTypes.NULL
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
@@ -62,15 +62,15 @@ public class IfThenToElvisIntention : SelfTargetingOffsetIndependentIntention<Kt
|
||||
}
|
||||
|
||||
public fun applyTo(element: KtIfExpression): KtBinaryExpression {
|
||||
val condition = element.getCondition() as KtBinaryExpression
|
||||
val condition = element.condition as KtBinaryExpression
|
||||
|
||||
val thenClause = element.getThen()!!
|
||||
val elseClause = element.getElse()!!
|
||||
val thenClause = element.then!!
|
||||
val elseClause = element.`else`!!
|
||||
val thenExpression = thenClause.unwrapBlockOrParenthesis()
|
||||
val elseExpression = elseClause.unwrapBlockOrParenthesis()
|
||||
|
||||
val (left, right) =
|
||||
when(condition.getOperationToken()) {
|
||||
when(condition.operationToken) {
|
||||
KtTokens.EQEQ -> Pair(elseExpression, thenExpression)
|
||||
KtTokens.EXCLEQ -> Pair(thenExpression, elseExpression)
|
||||
else -> throw IllegalArgumentException()
|
||||
|
||||
+11
-11
@@ -26,17 +26,17 @@ import org.jetbrains.kotlin.idea.core.replaced
|
||||
|
||||
public class IfThenToSafeAccessInspection : IntentionBasedInspection<KtIfExpression>(IfThenToSafeAccessIntention())
|
||||
|
||||
public class IfThenToSafeAccessIntention : SelfTargetingOffsetIndependentIntention<KtIfExpression>(javaClass(), "Replace 'if' expression with safe access expression") {
|
||||
public class IfThenToSafeAccessIntention : SelfTargetingOffsetIndependentIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' expression with safe access expression") {
|
||||
|
||||
override fun isApplicableTo(element: KtIfExpression): Boolean {
|
||||
val condition = element.getCondition() as? KtBinaryExpression ?: return false
|
||||
val thenClause = element.getThen()
|
||||
val elseClause = element.getElse()
|
||||
val condition = element.condition as? KtBinaryExpression ?: return false
|
||||
val thenClause = element.then
|
||||
val elseClause = element.`else`
|
||||
|
||||
val receiverExpression = condition.expressionComparedToNull() ?: return false
|
||||
if (!receiverExpression.isStableVariable()) return false
|
||||
|
||||
return when (condition.getOperationToken()) {
|
||||
return when (condition.operationToken) {
|
||||
KtTokens.EQEQ ->
|
||||
thenClause?.isNullExpressionOrEmptyBlock() ?: true &&
|
||||
elseClause != null && clauseContainsAppropriateDotQualifiedExpression(elseClause, receiverExpression)
|
||||
@@ -56,14 +56,14 @@ public class IfThenToSafeAccessIntention : SelfTargetingOffsetIndependentIntenti
|
||||
}
|
||||
|
||||
public fun applyTo(element: KtIfExpression): KtSafeQualifiedExpression {
|
||||
val condition = element.getCondition() as KtBinaryExpression
|
||||
val condition = element.condition as KtBinaryExpression
|
||||
val receiverExpression = condition.expressionComparedToNull()!!
|
||||
|
||||
val selectorExpression =
|
||||
when(condition.getOperationToken()) {
|
||||
KtTokens.EQEQ -> findSelectorExpressionInClause(element.getElse()!!, receiverExpression)!!
|
||||
when(condition.operationToken) {
|
||||
KtTokens.EQEQ -> findSelectorExpressionInClause(element.`else`!!, receiverExpression)!!
|
||||
|
||||
KtTokens.EXCLEQ -> findSelectorExpressionInClause(element.getThen()!!, receiverExpression)!!
|
||||
KtTokens.EXCLEQ -> findSelectorExpressionInClause(element.then!!, receiverExpression)!!
|
||||
|
||||
else -> throw IllegalArgumentException()
|
||||
}
|
||||
@@ -78,8 +78,8 @@ public class IfThenToSafeAccessIntention : SelfTargetingOffsetIndependentIntenti
|
||||
private fun findSelectorExpressionInClause(clause: KtExpression, receiverExpression: KtExpression): KtExpression? {
|
||||
val expression = clause.unwrapBlockOrParenthesis() as? KtDotQualifiedExpression ?: return null
|
||||
|
||||
if (expression.getReceiverExpression().getText() != receiverExpression.getText()) return null
|
||||
if (expression.receiverExpression.text != receiverExpression.text) return null
|
||||
|
||||
return expression.getSelectorExpression()
|
||||
return expression.selectorExpression
|
||||
}
|
||||
}
|
||||
|
||||
+9
-9
@@ -25,10 +25,10 @@ import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import java.util.*
|
||||
|
||||
public class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(javaClass(), "Replace 'if' with 'when'") {
|
||||
public class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(KtIfExpression::class.java, "Replace 'if' with 'when'") {
|
||||
override fun applicabilityRange(element: KtIfExpression): TextRange? {
|
||||
if (element.getThen() == null) return null
|
||||
return element.getIfKeyword().getTextRange()
|
||||
if (element.then == null) return null
|
||||
return element.ifKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtIfExpression, editor: Editor) {
|
||||
@@ -37,7 +37,7 @@ public class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(jav
|
||||
|
||||
var ifExpression = element
|
||||
while (true) {
|
||||
val condition = ifExpression.getCondition()
|
||||
val condition = ifExpression.condition
|
||||
val orBranches = ArrayList<KtExpression>()
|
||||
if (condition != null) {
|
||||
orBranches.addOrBranches(condition)
|
||||
@@ -47,11 +47,11 @@ public class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(jav
|
||||
|
||||
appendFixedText("->")
|
||||
|
||||
val thenBranch = ifExpression.getThen()
|
||||
val thenBranch = ifExpression.then
|
||||
appendExpression(thenBranch)
|
||||
appendFixedText("\n")
|
||||
|
||||
val elseBranch = ifExpression.getElse() ?: break
|
||||
val elseBranch = ifExpression.`else` ?: break
|
||||
if (elseBranch is KtIfExpression) {
|
||||
ifExpression = elseBranch
|
||||
}
|
||||
@@ -75,9 +75,9 @@ public class IfToWhenIntention : SelfTargetingRangeIntention<KtIfExpression>(jav
|
||||
}
|
||||
|
||||
private fun MutableList<KtExpression>.addOrBranches(expression: KtExpression): List<KtExpression> {
|
||||
if (expression is KtBinaryExpression && expression.getOperationToken() == KtTokens.OROR) {
|
||||
val left = expression.getLeft()
|
||||
val right = expression.getRight()
|
||||
if (expression is KtBinaryExpression && expression.operationToken == KtTokens.OROR) {
|
||||
val left = expression.left
|
||||
val right = expression.right
|
||||
if (left != null && right != null) {
|
||||
addOrBranches(left)
|
||||
addOrBranches(right)
|
||||
|
||||
+3
-3
@@ -26,11 +26,11 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
|
||||
public class IntroduceWhenSubjectInspection : IntentionBasedInspection<KtWhenExpression>(IntroduceWhenSubjectIntention())
|
||||
|
||||
public class IntroduceWhenSubjectIntention : SelfTargetingRangeIntention<KtWhenExpression>(javaClass(), "Introduce argument to 'when'") {
|
||||
public class IntroduceWhenSubjectIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenExpression::class.java, "Introduce argument to 'when'") {
|
||||
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
|
||||
val subject = element.getSubjectToIntroduce() ?: return null
|
||||
setText("Introduce '${subject.getText()}' as argument to 'when'")
|
||||
return element.getWhenKeyword().getTextRange()
|
||||
text = "Introduce '${subject.text}' as argument to 'when'"
|
||||
return element.whenKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
|
||||
+16
-16
@@ -29,52 +29,52 @@ import org.jetbrains.kotlin.idea.util.psi.patternMatching.toRange
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.psi.psiUtil.*
|
||||
|
||||
public class MergeWhenIntention : SelfTargetingRangeIntention<KtWhenExpression>(javaClass(), "Merge with next 'when'", "Merge 'when' expressions") {
|
||||
public class MergeWhenIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenExpression::class.java, "Merge with next 'when'", "Merge 'when' expressions") {
|
||||
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
|
||||
val next = PsiTreeUtil.skipSiblingsForward(element, javaClass<PsiWhiteSpace>()) as? KtWhenExpression ?: return null
|
||||
val next = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java) as? KtWhenExpression ?: return null
|
||||
|
||||
val subject1 = element.getSubjectExpression()
|
||||
val subject2 = next.getSubjectExpression()
|
||||
val subject1 = element.subjectExpression
|
||||
val subject2 = next.subjectExpression
|
||||
if (!subject1.matches(subject2)) return null
|
||||
if (subject1 != null && !subject1.isStableVariable()) return null
|
||||
|
||||
val entries1 = element.getEntries()
|
||||
val entries2 = next.getEntries()
|
||||
if (entries1.size() != entries2.size()) return null
|
||||
val entries1 = element.entries
|
||||
val entries2 = next.entries
|
||||
if (entries1.size != entries2.size) return null
|
||||
if (!entries1.zip(entries2).all { pair ->
|
||||
conditionsMatch(pair.first, pair.second) && checkBodies(pair.first, pair.second)
|
||||
}) return null
|
||||
|
||||
return element.getWhenKeyword().getTextRange()
|
||||
return element.whenKeyword.textRange
|
||||
}
|
||||
|
||||
private fun conditionsMatch(e1: KtWhenEntry, e2: KtWhenEntry): Boolean =
|
||||
e1.getConditions().toList().toRange().matches(e2.getConditions().toList().toRange())
|
||||
e1.conditions.toList().toRange().matches(e2.conditions.toList().toRange())
|
||||
|
||||
private fun checkBodies(e1: KtWhenEntry, e2: KtWhenEntry): Boolean {
|
||||
val names1 = e1.declarationNames()
|
||||
val names2 = e2.declarationNames()
|
||||
if (names1.any { it in names2 }) return false
|
||||
|
||||
return when (e1.getExpression()?.lastBlockStatementOrThis()) {
|
||||
return when (e1.expression?.lastBlockStatementOrThis()) {
|
||||
is KtReturnExpression, is KtThrowExpression, is KtBreakExpression, is KtContinueExpression -> false
|
||||
else -> true
|
||||
}
|
||||
}
|
||||
|
||||
private fun KtWhenEntry.declarationNames(): Set<String> =
|
||||
getExpression()?.blockExpressionsOrSingle()
|
||||
expression?.blockExpressionsOrSingle()
|
||||
?.filter { it is KtNamedDeclaration }
|
||||
?.mapNotNull { it.getName() }
|
||||
?.mapNotNull { it.name }
|
||||
?.toSet() ?: emptySet()
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
val nextWhen = PsiTreeUtil.skipSiblingsForward(element, javaClass<PsiWhiteSpace>()) as KtWhenExpression
|
||||
for ((entry1, entry2) in element.getEntries().zip(nextWhen.getEntries())) {
|
||||
entry1.getExpression().mergeWith(entry2.getExpression())
|
||||
val nextWhen = PsiTreeUtil.skipSiblingsForward(element, PsiWhiteSpace::class.java) as KtWhenExpression
|
||||
for ((entry1, entry2) in element.entries.zip(nextWhen.entries)) {
|
||||
entry1.expression.mergeWith(entry2.expression)
|
||||
}
|
||||
|
||||
element.getParent().deleteChildRange(element.getNextSibling(), nextWhen)
|
||||
element.parent.deleteChildRange(element.nextSibling, nextWhen)
|
||||
}
|
||||
|
||||
private fun KtExpression?.mergeWith(that: KtExpression?): KtExpression? = when {
|
||||
|
||||
+6
-6
@@ -27,15 +27,15 @@ import org.jetbrains.kotlin.idea.intentions.branchedTransformations.isStableVari
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsStatement
|
||||
|
||||
public class SafeAccessToIfThenIntention : SelfTargetingRangeIntention<KtSafeQualifiedExpression>(javaClass(), "Replace safe access expression with 'if' expression"), LowPriorityAction {
|
||||
public class SafeAccessToIfThenIntention : SelfTargetingRangeIntention<KtSafeQualifiedExpression>(KtSafeQualifiedExpression::class.java, "Replace safe access expression with 'if' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtSafeQualifiedExpression): TextRange? {
|
||||
if (element.getSelectorExpression() == null) return null
|
||||
return element.getOperationTokenNode().getTextRange()
|
||||
if (element.selectorExpression == null) return null
|
||||
return element.operationTokenNode.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtSafeQualifiedExpression, editor: Editor) {
|
||||
val receiver = KtPsiUtil.safeDeparenthesize(element.getReceiverExpression())
|
||||
val selector = element.getSelectorExpression()!!
|
||||
val receiver = KtPsiUtil.safeDeparenthesize(element.receiverExpression)
|
||||
val selector = element.selectorExpression!!
|
||||
|
||||
val receiverIsStable = receiver.isStableVariable()
|
||||
|
||||
@@ -46,7 +46,7 @@ public class SafeAccessToIfThenIntention : SelfTargetingRangeIntention<KtSafeQua
|
||||
val ifExpression = element.convertToIfNotNullExpression(receiver, dotQualified, elseClause)
|
||||
|
||||
if (!receiverIsStable) {
|
||||
val valueToExtract = (ifExpression.getThen() as KtDotQualifiedExpression).getReceiverExpression()
|
||||
val valueToExtract = (ifExpression.then as KtDotQualifiedExpression).receiverExpression
|
||||
ifExpression.introduceValueForCondition(valueToExtract, editor)
|
||||
}
|
||||
}
|
||||
|
||||
+5
-5
@@ -27,12 +27,12 @@ import org.jetbrains.kotlin.psi.KtIfExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class UnfoldAssignmentToIfIntention : SelfTargetingRangeIntention<KtBinaryExpression>(javaClass(), "Replace assignment with 'if' expression"), LowPriorityAction {
|
||||
public class UnfoldAssignmentToIfIntention : SelfTargetingRangeIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Replace assignment with 'if' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtBinaryExpression): TextRange? {
|
||||
if (element.getOperationToken() !in KtTokens.ALL_ASSIGNMENTS) return null
|
||||
if (element.getLeft() == null) return null
|
||||
val right = element.getRight() as? KtIfExpression ?: return null
|
||||
return TextRange(element.startOffset, right.getIfKeyword().endOffset)
|
||||
if (element.operationToken !in KtTokens.ALL_ASSIGNMENTS) return null
|
||||
if (element.left == null) return null
|
||||
val right = element.right as? KtIfExpression ?: return null
|
||||
return TextRange(element.startOffset, right.ifKeyword.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
|
||||
+6
-6
@@ -28,14 +28,14 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class UnfoldAssignmentToWhenIntention : SelfTargetingRangeIntention<KtBinaryExpression>(javaClass(), "Replace assignment with 'when' expression" ), LowPriorityAction {
|
||||
public class UnfoldAssignmentToWhenIntention : SelfTargetingRangeIntention<KtBinaryExpression>(KtBinaryExpression::class.java, "Replace assignment with 'when' expression" ), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtBinaryExpression): TextRange? {
|
||||
if (element.getOperationToken() !in KtTokens.ALL_ASSIGNMENTS) return null
|
||||
if (element.getLeft() == null) return null
|
||||
val right = element.getRight() as? KtWhenExpression ?: return null
|
||||
if (element.operationToken !in KtTokens.ALL_ASSIGNMENTS) return null
|
||||
if (element.left == null) return null
|
||||
val right = element.right as? KtWhenExpression ?: return null
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(right)) return null
|
||||
if (right.getEntries().any { it.getExpression() == null }) return null
|
||||
return TextRange(element.startOffset, right.getWhenKeyword().endOffset)
|
||||
if (right.entries.any { it.expression == null }) return null
|
||||
return TextRange(element.startOffset, right.whenKeyword.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtBinaryExpression, editor: Editor) {
|
||||
|
||||
+4
-4
@@ -27,11 +27,11 @@ import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class UnfoldPropertyToIfIntention : SelfTargetingRangeIntention<KtProperty>(javaClass(), "Replace property initializer with 'if' expression"), LowPriorityAction {
|
||||
public class UnfoldPropertyToIfIntention : SelfTargetingRangeIntention<KtProperty>(KtProperty::class.java, "Replace property initializer with 'if' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtProperty): TextRange? {
|
||||
if (!element.isLocal()) return null
|
||||
val initializer = element.getInitializer() as? KtIfExpression ?: return null
|
||||
return TextRange(element.startOffset, initializer.getIfKeyword().endOffset)
|
||||
if (!element.isLocal) return null
|
||||
val initializer = element.initializer as? KtIfExpression ?: return null
|
||||
return TextRange(element.startOffset, initializer.ifKeyword.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtProperty, editor: Editor) {
|
||||
|
||||
+5
-5
@@ -28,13 +28,13 @@ import org.jetbrains.kotlin.psi.KtWhenExpression
|
||||
import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class UnfoldPropertyToWhenIntention : SelfTargetingRangeIntention<KtProperty>(javaClass(), "Replace property initializer with 'when' expression"), LowPriorityAction {
|
||||
public class UnfoldPropertyToWhenIntention : SelfTargetingRangeIntention<KtProperty>(KtProperty::class.java, "Replace property initializer with 'when' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtProperty): TextRange? {
|
||||
if (!element.isLocal()) return null
|
||||
val initializer = element.getInitializer() as? KtWhenExpression ?: return null
|
||||
if (!element.isLocal) return null
|
||||
val initializer = element.initializer as? KtWhenExpression ?: return null
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(initializer)) return null
|
||||
if (initializer.getEntries().any { it.getExpression() == null }) return null
|
||||
return TextRange(element.startOffset, initializer.getWhenKeyword().endOffset)
|
||||
if (initializer.entries.any { it.expression == null }) return null
|
||||
return TextRange(element.startOffset, initializer.whenKeyword.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtProperty, editor: Editor) {
|
||||
|
||||
+6
-6
@@ -29,17 +29,17 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class UnfoldReturnToIfIntention : SelfTargetingRangeIntention<KtReturnExpression>(javaClass(), "Replace return with 'if' expression"), LowPriorityAction {
|
||||
public class UnfoldReturnToIfIntention : SelfTargetingRangeIntention<KtReturnExpression>(KtReturnExpression::class.java, "Replace return with 'if' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtReturnExpression): TextRange? {
|
||||
val ifExpression = element.getReturnedExpression() as? KtIfExpression ?: return null
|
||||
return TextRange(element.startOffset, ifExpression.getIfKeyword().endOffset)
|
||||
val ifExpression = element.returnedExpression as? KtIfExpression ?: return null
|
||||
return TextRange(element.startOffset, ifExpression.ifKeyword.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtReturnExpression, editor: Editor) {
|
||||
val ifExpression = element.getReturnedExpression() as KtIfExpression
|
||||
val ifExpression = element.returnedExpression as KtIfExpression
|
||||
val newIfExpression = ifExpression.copied()
|
||||
val thenExpr = newIfExpression.getThen()!!.lastBlockStatementOrThis()
|
||||
val elseExpr = newIfExpression.getElse()!!.lastBlockStatementOrThis()
|
||||
val thenExpr = newIfExpression.then!!.lastBlockStatementOrThis()
|
||||
val elseExpr = newIfExpression.`else`!!.lastBlockStatementOrThis()
|
||||
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
thenExpr.replace(psiFactory.createExpressionByPattern("return $0", thenExpr))
|
||||
|
||||
+7
-7
@@ -26,20 +26,20 @@ import org.jetbrains.kotlin.psi.psiUtil.endOffset
|
||||
import org.jetbrains.kotlin.psi.psiUtil.lastBlockStatementOrThis
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class UnfoldReturnToWhenIntention : SelfTargetingRangeIntention<KtReturnExpression>(javaClass(), "Replace return with 'when' expression"), LowPriorityAction {
|
||||
public class UnfoldReturnToWhenIntention : SelfTargetingRangeIntention<KtReturnExpression>(KtReturnExpression::class.java, "Replace return with 'when' expression"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtReturnExpression): TextRange? {
|
||||
val whenExpr = element.getReturnedExpression() as? KtWhenExpression ?: return null
|
||||
val whenExpr = element.returnedExpression as? KtWhenExpression ?: return null
|
||||
if (!KtPsiUtil.checkWhenExpressionHasSingleElse(whenExpr)) return null
|
||||
if (whenExpr.getEntries().any { it.getExpression() == null }) return null
|
||||
return TextRange(element.startOffset, whenExpr.getWhenKeyword().endOffset)
|
||||
if (whenExpr.entries.any { it.expression == null }) return null
|
||||
return TextRange(element.startOffset, whenExpr.whenKeyword.endOffset)
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtReturnExpression, editor: Editor) {
|
||||
val whenExpression = element.getReturnedExpression() as KtWhenExpression
|
||||
val whenExpression = element.returnedExpression as KtWhenExpression
|
||||
val newWhenExpression = whenExpression.copied()
|
||||
|
||||
for (entry in newWhenExpression.getEntries()) {
|
||||
val expr = entry.getExpression()!!.lastBlockStatementOrThis()
|
||||
for (entry in newWhenExpression.entries) {
|
||||
val expr = entry.expression!!.lastBlockStatementOrThis()
|
||||
expr.replace(KtPsiFactory(element).createExpressionByPattern("return $0", expr))
|
||||
}
|
||||
|
||||
|
||||
+8
-8
@@ -23,29 +23,29 @@ import org.jetbrains.kotlin.idea.intentions.SelfTargetingRangeIntention
|
||||
import org.jetbrains.kotlin.idea.intentions.branchedTransformations.combineWhenConditions
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class WhenToIfIntention : SelfTargetingRangeIntention<KtWhenExpression>(javaClass(), "Replace 'when' with 'if'"), LowPriorityAction {
|
||||
public class WhenToIfIntention : SelfTargetingRangeIntention<KtWhenExpression>(KtWhenExpression::class.java, "Replace 'when' with 'if'"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtWhenExpression): TextRange? {
|
||||
val entries = element.getEntries()
|
||||
val entries = element.entries
|
||||
if (entries.isEmpty()) return null
|
||||
val lastEntry = entries.last()
|
||||
if (entries.any { it != lastEntry && it.isElse() }) return null
|
||||
return element.getWhenKeyword().getTextRange()
|
||||
if (entries.any { it != lastEntry && it.isElse }) return null
|
||||
return element.whenKeyword.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtWhenExpression, editor: Editor) {
|
||||
val factory = KtPsiFactory(element)
|
||||
val ifExpression = factory.buildExpression {
|
||||
val entries = element.getEntries()
|
||||
val entries = element.entries
|
||||
for ((i, entry) in entries.withIndex()) {
|
||||
if (i > 0) {
|
||||
appendFixedText("else ")
|
||||
}
|
||||
val branch = entry.getExpression()
|
||||
if (entry.isElse()) {
|
||||
val branch = entry.expression
|
||||
if (entry.isElse) {
|
||||
appendExpression(branch)
|
||||
}
|
||||
else {
|
||||
val condition = factory.combineWhenConditions(entry.getConditions(), element.getSubjectExpression())
|
||||
val condition = factory.combineWhenConditions(entry.conditions, element.subjectExpression)
|
||||
appendFixedText("if (")
|
||||
appendExpression(condition)
|
||||
appendFixedText(")")
|
||||
|
||||
+8
-8
@@ -29,32 +29,32 @@ import org.jetbrains.kotlin.resolve.calls.model.isReallySuccess
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
public class ReplaceCallWithBinaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(javaClass(), "Replace call with binary operator"), HighPriorityAction {
|
||||
public class ReplaceCallWithBinaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, "Replace call with binary operator"), HighPriorityAction {
|
||||
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
|
||||
val operation = operation(element.calleeName) ?: return null
|
||||
|
||||
val resolvedCall = element.toResolvedCall(BodyResolveMode.PARTIAL) ?: return null
|
||||
if (!resolvedCall.isReallySuccess()) return null
|
||||
if (resolvedCall.getCall().getTypeArgumentList() != null) return null
|
||||
val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null
|
||||
if (resolvedCall.call.typeArgumentList != null) return null
|
||||
val argument = resolvedCall.call.valueArguments.singleOrNull() ?: return null
|
||||
if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.index != 0) return null
|
||||
|
||||
if (!element.isReceiverExpressionWithValue()) return null
|
||||
|
||||
setText("Replace with '$operation' operator")
|
||||
return element.callExpression!!.getCalleeExpression()!!.getTextRange()
|
||||
text = "Replace with '$operation' operator"
|
||||
return element.callExpression!!.calleeExpression!!.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) {
|
||||
val operation = operation(element.calleeName)!!
|
||||
val argument = element.callExpression!!.getValueArguments().single().getArgumentExpression()!!
|
||||
val receiver = element.getReceiverExpression()
|
||||
val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!!
|
||||
val receiver = element.receiverExpression
|
||||
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("$0 $operation $1", receiver, argument))
|
||||
}
|
||||
|
||||
private fun operation(functionName: String?): String? {
|
||||
if (functionName == null) return null
|
||||
return OperatorConventions.BINARY_OPERATION_NAMES.inverse()[Name.identifier(functionName)]?.getValue()
|
||||
return OperatorConventions.BINARY_OPERATION_NAMES.inverse()[Name.identifier(functionName)]?.value
|
||||
}
|
||||
}
|
||||
|
||||
+7
-7
@@ -29,28 +29,28 @@ import org.jetbrains.kotlin.psi.KtPsiFactory
|
||||
import org.jetbrains.kotlin.psi.createExpressionByPattern
|
||||
import org.jetbrains.kotlin.types.expressions.OperatorConventions
|
||||
|
||||
public class ReplaceCallWithUnaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(javaClass(), "Replace call with unary operator"), HighPriorityAction {
|
||||
public class ReplaceCallWithUnaryOperatorIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, "Replace call with unary operator"), HighPriorityAction {
|
||||
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
|
||||
val operation = operation(element.calleeName) ?: return null
|
||||
|
||||
val call = element.callExpression ?: return null
|
||||
if (call.getTypeArgumentList() != null) return null
|
||||
if (!call.getValueArguments().isEmpty()) return null
|
||||
if (call.typeArgumentList != null) return null
|
||||
if (!call.valueArguments.isEmpty()) return null
|
||||
|
||||
if (!element.isReceiverExpressionWithValue()) return null
|
||||
|
||||
setText("Replace with '$operation' operator")
|
||||
return call.getCalleeExpression()!!.getTextRange()
|
||||
text = "Replace with '$operation' operator"
|
||||
return call.calleeExpression!!.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) {
|
||||
val operation = operation(element.calleeName)!!
|
||||
val receiver = element.getReceiverExpression()
|
||||
val receiver = element.receiverExpression
|
||||
element.replace(KtPsiFactory(element).createExpressionByPattern("$0$1", operation, receiver))
|
||||
}
|
||||
|
||||
private fun operation(functionName: String?) : String? {
|
||||
if (functionName == null) return null
|
||||
return OperatorConventions.UNARY_OPERATION_NAMES.inverse()[Name.identifier(functionName)]?.getValue()
|
||||
return OperatorConventions.UNARY_OPERATION_NAMES.inverse()[Name.identifier(functionName)]?.value
|
||||
}
|
||||
}
|
||||
|
||||
+11
-11
@@ -28,32 +28,32 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
public class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(javaClass(), "Replace 'contains' call with 'in' operator"), HighPriorityAction {
|
||||
public class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, "Replace 'contains' call with 'in' operator"), HighPriorityAction {
|
||||
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
|
||||
if (element.calleeName != OperatorNameConventions.CONTAINS.asString()) return null
|
||||
|
||||
val resolvedCall = element.toResolvedCall(BodyResolveMode.PARTIAL) ?: return null
|
||||
if (!resolvedCall.isReallySuccess()) return null
|
||||
val argument = resolvedCall.getCall().getValueArguments().singleOrNull() ?: return null
|
||||
val argument = resolvedCall.call.valueArguments.singleOrNull() ?: return null
|
||||
if ((resolvedCall.getArgumentMapping(argument) as ArgumentMatch).valueParameter.index != 0) return null
|
||||
|
||||
val target = resolvedCall.getResultingDescriptor()
|
||||
val returnType = target.getReturnType() ?: return null
|
||||
val target = resolvedCall.resultingDescriptor
|
||||
val returnType = target.returnType ?: return null
|
||||
if (!target.builtIns.isBooleanOrSubtype(returnType)) return null
|
||||
|
||||
if (!element.isReceiverExpressionWithValue()) return null
|
||||
|
||||
return element.callExpression!!.getCalleeExpression()!!.getTextRange()
|
||||
return element.callExpression!!.calleeExpression!!.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) {
|
||||
val argument = element.callExpression!!.getValueArguments().single().getArgumentExpression()!!
|
||||
val receiver = element.getReceiverExpression()
|
||||
val argument = element.callExpression!!.valueArguments.single().getArgumentExpression()!!
|
||||
val receiver = element.receiverExpression
|
||||
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
|
||||
val prefixExpression = element.getParent() as? KtPrefixExpression
|
||||
val expression = if (prefixExpression != null && prefixExpression.getOperationToken() == KtTokens.EXCL) {
|
||||
val prefixExpression = element.parent as? KtPrefixExpression
|
||||
val expression = if (prefixExpression != null && prefixExpression.operationToken == KtTokens.EXCL) {
|
||||
prefixExpression.replace(psiFactory.createExpressionByPattern("$0 !in $1", argument, receiver))
|
||||
}
|
||||
else {
|
||||
@@ -63,10 +63,10 @@ public class ReplaceContainsIntention : SelfTargetingRangeIntention<KtDotQualifi
|
||||
// Append semicolon to previous statement if needed
|
||||
if (argument is KtLambdaExpression) {
|
||||
val previousElement = KtPsiUtil.skipSiblingsBackwardByPredicate(expression) {
|
||||
it.getNode().getElementType() in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
|
||||
it.node.elementType in KtTokens.WHITE_SPACE_OR_COMMENT_BIT_SET
|
||||
}
|
||||
if (previousElement != null && previousElement is KtExpression) {
|
||||
previousElement.getParent()!!.addAfter(psiFactory.createSemicolon(), previousElement)
|
||||
previousElement.parent!!.addAfter(psiFactory.createSemicolon(), previousElement)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+4
-4
@@ -71,9 +71,9 @@ class ReplaceGetOrSetIntention : SelfTargetingRangeIntention<KtDotQualifiedExpre
|
||||
val target = resolvedCall.resultingDescriptor as? FunctionDescriptor ?: return null
|
||||
if (!target.isValidOperator() || target.name !in operatorNames) return null
|
||||
|
||||
if (callExpression.getTypeArgumentList() != null) return null
|
||||
if (callExpression.typeArgumentList != null) return null
|
||||
|
||||
val arguments = callExpression.getValueArguments()
|
||||
val arguments = callExpression.valueArguments
|
||||
if (arguments.isEmpty()) return null
|
||||
if (arguments.any { it.isNamed() }) return null
|
||||
|
||||
@@ -83,7 +83,7 @@ class ReplaceGetOrSetIntention : SelfTargetingRangeIntention<KtDotQualifiedExpre
|
||||
|
||||
text = "Replace '${target.name.asString()}' call with indexing operator"
|
||||
|
||||
return callExpression.getCalleeExpression()!!.getTextRange()
|
||||
return callExpression.calleeExpression!!.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) {
|
||||
@@ -96,7 +96,7 @@ class ReplaceGetOrSetIntention : SelfTargetingRangeIntention<KtDotQualifiedExpre
|
||||
assert(allArguments.isNotEmpty())
|
||||
|
||||
val expression = KtPsiFactory(element).buildExpression {
|
||||
appendExpression(element.getReceiverExpression())
|
||||
appendExpression(element.receiverExpression)
|
||||
|
||||
appendFixedText("[")
|
||||
|
||||
|
||||
+4
-4
@@ -26,16 +26,16 @@ import org.jetbrains.kotlin.psi.KtCallExpression
|
||||
import org.jetbrains.kotlin.psi.KtDotQualifiedExpression
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
public class ReplaceInvokeIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(javaClass(), "Replace 'invoke' with direct call"), HighPriorityAction {
|
||||
public class ReplaceInvokeIntention : SelfTargetingRangeIntention<KtDotQualifiedExpression>(KtDotQualifiedExpression::class.java, "Replace 'invoke' with direct call"), HighPriorityAction {
|
||||
override fun applicabilityRange(element: KtDotQualifiedExpression): TextRange? {
|
||||
if (element.calleeName != OperatorNameConventions.INVOKE.asString()) return null
|
||||
return element.callExpression!!.getCalleeExpression()!!.getTextRange()
|
||||
return element.callExpression!!.calleeExpression!!.textRange
|
||||
}
|
||||
|
||||
override fun applyTo(element: KtDotQualifiedExpression, editor: Editor) {
|
||||
val receiver = element.getReceiverExpression()
|
||||
val receiver = element.receiverExpression
|
||||
val callExpression = element.callExpression!!.copy() as KtCallExpression
|
||||
callExpression.getCalleeExpression()!!.replace(receiver)
|
||||
callExpression.calleeExpression!!.replace(receiver)
|
||||
element.replace(callExpression)
|
||||
}
|
||||
}
|
||||
|
||||
+32
-32
@@ -29,31 +29,31 @@ import org.jetbrains.kotlin.idea.quickfix.moveCaret
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.psi.*
|
||||
|
||||
public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(javaClass(), "Convert member to extension"), LowPriorityAction {
|
||||
public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtCallableDeclaration>(KtCallableDeclaration::class.java, "Convert member to extension"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtCallableDeclaration): TextRange? {
|
||||
val classBody = element.getParent() as? KtClassBody ?: return null
|
||||
if (classBody.getParent() !is KtClass) return null
|
||||
if (element.getReceiverTypeReference() != null) return null
|
||||
val classBody = element.parent as? KtClassBody ?: return null
|
||||
if (classBody.parent !is KtClass) return null
|
||||
if (element.receiverTypeReference != null) return null
|
||||
if (element.hasModifier(KtTokens.OVERRIDE_KEYWORD)) return null
|
||||
when (element) {
|
||||
is KtProperty -> if (element.hasInitializer()) return null
|
||||
is KtSecondaryConstructor -> return null
|
||||
}
|
||||
return (element.getNameIdentifier() ?: return null).getTextRange()
|
||||
return (element.nameIdentifier ?: return null).textRange
|
||||
}
|
||||
|
||||
//TODO: local class
|
||||
|
||||
override fun applyTo(element: KtCallableDeclaration, editor: Editor) {
|
||||
val descriptor = element.resolveToDescriptor()
|
||||
val containingClass = descriptor.getContainingDeclaration() as ClassDescriptor
|
||||
val containingClass = descriptor.containingDeclaration as ClassDescriptor
|
||||
|
||||
val file = element.getContainingKtFile()
|
||||
val outermostParent = KtPsiUtil.getOutermostParent(element, file, false)
|
||||
|
||||
val typeParameterList = newTypeParameterList(element)
|
||||
|
||||
val project = element.getProject()
|
||||
val project = element.project
|
||||
val psiFactory = KtPsiFactory(element)
|
||||
|
||||
val extension = file.addAfter(element, outermostParent) as KtCallableDeclaration
|
||||
@@ -61,27 +61,27 @@ public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtC
|
||||
file.addAfter(psiFactory.createNewLine(), outermostParent)
|
||||
element.delete()
|
||||
|
||||
extension.setReceiverType(containingClass.getDefaultType())
|
||||
extension.setReceiverType(containingClass.defaultType)
|
||||
|
||||
if (typeParameterList != null) {
|
||||
if (extension.getTypeParameterList() != null) {
|
||||
extension.getTypeParameterList()!!.replace(typeParameterList)
|
||||
if (extension.typeParameterList != null) {
|
||||
extension.typeParameterList!!.replace(typeParameterList)
|
||||
}
|
||||
else {
|
||||
extension.addBefore(typeParameterList, extension.getReceiverTypeReference())
|
||||
extension.addBefore(psiFactory.createWhiteSpace(), extension.getReceiverTypeReference())
|
||||
extension.addBefore(typeParameterList, extension.receiverTypeReference)
|
||||
extension.addBefore(psiFactory.createWhiteSpace(), extension.receiverTypeReference)
|
||||
}
|
||||
}
|
||||
|
||||
extension.getModifierList()?.getModifier(KtTokens.PROTECTED_KEYWORD)?.delete()
|
||||
extension.getModifierList()?.getModifier(KtTokens.ABSTRACT_KEYWORD)?.delete()
|
||||
extension.modifierList?.getModifier(KtTokens.PROTECTED_KEYWORD)?.delete()
|
||||
extension.modifierList?.getModifier(KtTokens.ABSTRACT_KEYWORD)?.delete()
|
||||
|
||||
var bodyToSelect: KtExpression? = null
|
||||
|
||||
fun selectBody(declaration: KtDeclarationWithBody) {
|
||||
if (bodyToSelect == null) {
|
||||
val body = declaration.getBodyExpression()
|
||||
bodyToSelect = if (body is KtBlockExpression) body.getStatements().single() else body
|
||||
val body = declaration.bodyExpression
|
||||
bodyToSelect = if (body is KtBlockExpression) body.statements.single() else body
|
||||
}
|
||||
}
|
||||
|
||||
@@ -96,12 +96,12 @@ public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtC
|
||||
|
||||
is KtProperty -> {
|
||||
val templateProperty = psiFactory.createDeclaration<KtProperty>("var v: Any\nget()=$THROW_UNSUPPORTED_OPERATION_EXCEPTION\nset(value){$THROW_UNSUPPORTED_OPERATION_EXCEPTION}")
|
||||
val templateGetter = templateProperty.getGetter()!!
|
||||
val templateSetter = templateProperty.getSetter()!!
|
||||
val templateGetter = templateProperty.getter!!
|
||||
val templateSetter = templateProperty.setter!!
|
||||
|
||||
var getter = extension.getGetter()
|
||||
var getter = extension.getter
|
||||
if (getter == null) {
|
||||
getter = extension.addAfter(templateGetter, extension.getTypeReference()) as KtPropertyAccessor
|
||||
getter = extension.addAfter(templateGetter, extension.typeReference) as KtPropertyAccessor
|
||||
extension.addBefore(psiFactory.createNewLine(), getter)
|
||||
selectBody(getter)
|
||||
}
|
||||
@@ -110,8 +110,8 @@ public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtC
|
||||
selectBody(getter)
|
||||
}
|
||||
|
||||
if (extension.isVar()) {
|
||||
var setter = extension.getSetter()
|
||||
if (extension.isVar) {
|
||||
var setter = extension.setter
|
||||
if (setter == null) {
|
||||
setter = extension.addAfter(templateSetter, getter) as KtPropertyAccessor
|
||||
extension.addBefore(psiFactory.createNewLine(), setter)
|
||||
@@ -125,15 +125,15 @@ public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtC
|
||||
}
|
||||
}
|
||||
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.getDocument())
|
||||
PsiDocumentManager.getInstance(project).doPostponedOperationsAndUnblockDocument(editor.document)
|
||||
|
||||
if (bodyToSelect != null) {
|
||||
val range = bodyToSelect!!.getTextRange()
|
||||
editor.moveCaret(range.getStartOffset(), ScrollType.CENTER)
|
||||
editor.getSelectionModel().setSelection(range.getStartOffset(), range.getEndOffset())
|
||||
val range = bodyToSelect!!.textRange
|
||||
editor.moveCaret(range.startOffset, ScrollType.CENTER)
|
||||
editor.selectionModel.setSelection(range.startOffset, range.endOffset)
|
||||
}
|
||||
else {
|
||||
editor.moveCaret(extension.getTextOffset(), ScrollType.CENTER)
|
||||
editor.moveCaret(extension.textOffset, ScrollType.CENTER)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,11 +141,11 @@ public class ConvertMemberToExtensionIntention : SelfTargetingRangeIntention<KtC
|
||||
private val THROW_UNSUPPORTED_OPERATION_EXCEPTION = "throw UnsupportedOperationException()"
|
||||
|
||||
private fun newTypeParameterList(member: KtCallableDeclaration): KtTypeParameterList? {
|
||||
val classElement = member.getParent().getParent() as KtClass
|
||||
val classParams = classElement.getTypeParameters()
|
||||
val classElement = member.parent.parent as KtClass
|
||||
val classParams = classElement.typeParameters
|
||||
if (classParams.isEmpty()) return null
|
||||
val allTypeParameters = classParams + member.getTypeParameters()
|
||||
val text = allTypeParameters.map { it.getText() }.joinToString(",", "<", ">")
|
||||
return KtPsiFactory(member).createDeclaration<KtFunction>("fun $text foo()").getTypeParameterList()
|
||||
val allTypeParameters = classParams + member.typeParameters
|
||||
val text = allTypeParameters.map { it.text }.joinToString(",", "<", ">")
|
||||
return KtPsiFactory(member).createDeclaration<KtFunction>("fun $text foo()").typeParameterList
|
||||
}
|
||||
}
|
||||
|
||||
+3
-3
@@ -24,10 +24,10 @@ import org.jetbrains.kotlin.idea.intentions.splitPropertyDeclaration
|
||||
import org.jetbrains.kotlin.psi.KtProperty
|
||||
import org.jetbrains.kotlin.psi.psiUtil.startOffset
|
||||
|
||||
public class SplitPropertyDeclarationIntention : SelfTargetingRangeIntention<KtProperty>(javaClass(), "Split property declaration"), LowPriorityAction {
|
||||
public class SplitPropertyDeclarationIntention : SelfTargetingRangeIntention<KtProperty>(KtProperty::class.java, "Split property declaration"), LowPriorityAction {
|
||||
override fun applicabilityRange(element: KtProperty): TextRange? {
|
||||
if (!element.isLocal()) return null
|
||||
val initializer = element.getInitializer() ?: return null
|
||||
if (!element.isLocal) return null
|
||||
val initializer = element.initializer ?: return null
|
||||
return TextRange(element.startOffset, initializer.startOffset)
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user