Reformat & cleanup: psiModificationUtils, especially PsiElement.replaced
This commit is contained in:
@@ -46,13 +46,9 @@ import org.jetbrains.kotlin.types.isError
|
|||||||
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
import org.jetbrains.kotlin.utils.KotlinExceptionWithAttachments
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
inline fun <reified T : PsiElement> PsiElement.replaced(newElement: T): T {
|
inline fun <reified T : PsiElement> PsiElement.replaced(newElement: T): T {
|
||||||
val result = replace(newElement)
|
val result = replace(newElement)
|
||||||
return if (result is T)
|
return result as? T ?: (result as KtParenthesizedExpression).expression as T
|
||||||
result
|
|
||||||
else
|
|
||||||
(result as KtParenthesizedExpression).expression as T
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
@@ -60,14 +56,14 @@ fun <T : PsiElement> T.copied(): T = copy() as T
|
|||||||
|
|
||||||
fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression {
|
fun KtLambdaArgument.moveInsideParentheses(bindingContext: BindingContext): KtCallExpression {
|
||||||
val ktExpression = this.getArgumentExpression()
|
val ktExpression = this.getArgumentExpression()
|
||||||
?: throw KotlinExceptionWithAttachments("no argument expression for $this")
|
?: throw KotlinExceptionWithAttachments("no argument expression for $this")
|
||||||
.withAttachment("lambdaExpression", this.text)
|
.withAttachment("lambdaExpression", this.text)
|
||||||
return moveInsideParenthesesAndReplaceWith(ktExpression, bindingContext)
|
return moveInsideParenthesesAndReplaceWith(ktExpression, bindingContext)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith(
|
fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith(
|
||||||
replacement: KtExpression,
|
replacement: KtExpression,
|
||||||
bindingContext: BindingContext
|
bindingContext: BindingContext
|
||||||
): KtCallExpression = moveInsideParenthesesAndReplaceWith(replacement, getLambdaArgumentName(bindingContext))
|
): KtCallExpression = moveInsideParenthesesAndReplaceWith(replacement, getLambdaArgumentName(bindingContext))
|
||||||
|
|
||||||
|
|
||||||
@@ -78,8 +74,8 @@ fun KtLambdaArgument.getLambdaArgumentName(bindingContext: BindingContext): Name
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith(
|
fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith(
|
||||||
replacement: KtExpression,
|
replacement: KtExpression,
|
||||||
functionLiteralArgumentName: Name?
|
functionLiteralArgumentName: Name?
|
||||||
): KtCallExpression {
|
): KtCallExpression {
|
||||||
val oldCallExpression = parent as KtCallExpression
|
val oldCallExpression = parent as KtCallExpression
|
||||||
val newCallExpression = oldCallExpression.copy() as KtCallExpression
|
val newCallExpression = oldCallExpression.copy() as KtCallExpression
|
||||||
@@ -88,8 +84,7 @@ fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith(
|
|||||||
|
|
||||||
val argument = if (shouldLambdaParameterBeNamed(newCallExpression.getValueArgumentsInParentheses(), oldCallExpression)) {
|
val argument = if (shouldLambdaParameterBeNamed(newCallExpression.getValueArgumentsInParentheses(), oldCallExpression)) {
|
||||||
psiFactory.createArgument(replacement, functionLiteralArgumentName)
|
psiFactory.createArgument(replacement, functionLiteralArgumentName)
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
psiFactory.createArgument(replacement)
|
psiFactory.createArgument(replacement)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,8 +96,7 @@ fun KtLambdaArgument.moveInsideParenthesesAndReplaceWith(
|
|||||||
(functionLiteralArgument.prevSibling as? PsiWhiteSpace)?.delete()
|
(functionLiteralArgument.prevSibling as? PsiWhiteSpace)?.delete()
|
||||||
if (newCallExpression.valueArgumentList != null) {
|
if (newCallExpression.valueArgumentList != null) {
|
||||||
functionLiteralArgument.delete()
|
functionLiteralArgument.delete()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
functionLiteralArgument.replace(valueArgumentList)
|
functionLiteralArgument.replace(valueArgumentList)
|
||||||
}
|
}
|
||||||
return oldCallExpression.replace(newCallExpression) as KtCallExpression
|
return oldCallExpression.replace(newCallExpression) as KtCallExpression
|
||||||
@@ -117,8 +111,8 @@ fun KtLambdaExpression.moveFunctionLiteralOutsideParenthesesIfPossible() {
|
|||||||
|
|
||||||
private fun shouldLambdaParameterBeNamed(args: List<ValueArgument>, callExpr: KtCallExpression): Boolean {
|
private fun shouldLambdaParameterBeNamed(args: List<ValueArgument>, callExpr: KtCallExpression): Boolean {
|
||||||
if (args.any { it.isNamed() }) return true
|
if (args.any { it.isNamed() }) return true
|
||||||
val calee = (callExpr.calleeExpression?.mainReference?.resolve() as? KtFunction) ?: return true
|
val callee = (callExpr.calleeExpression?.mainReference?.resolve() as? KtFunction) ?: return true
|
||||||
return if (calee.valueParameters.any { it.isVarArg }) true else calee.valueParameters.size - 1 > args.size
|
return if (callee.valueParameters.any { it.isVarArg }) true else callee.valueParameters.size - 1 > args.size
|
||||||
}
|
}
|
||||||
|
|
||||||
fun KtCallExpression.getLastLambdaExpression(): KtLambdaExpression? {
|
fun KtCallExpression.getLastLambdaExpression(): KtLambdaExpression? {
|
||||||
@@ -134,14 +128,15 @@ fun KtCallExpression.canMoveLambdaOutsideParentheses(): Boolean {
|
|||||||
val lambdaArgumentCount = valueArguments.mapNotNull { it.getArgumentExpression()?.unpackFunctionLiteral() }.count()
|
val lambdaArgumentCount = valueArguments.mapNotNull { it.getArgumentExpression()?.unpackFunctionLiteral() }.count()
|
||||||
val bindingContext = analyze(BodyResolveMode.PARTIAL)
|
val bindingContext = analyze(BodyResolveMode.PARTIAL)
|
||||||
val targets = bindingContext[BindingContext.REFERENCE_TARGET, callee]?.let { listOf(it) }
|
val targets = bindingContext[BindingContext.REFERENCE_TARGET, callee]?.let { listOf(it) }
|
||||||
?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, callee]
|
?: bindingContext[BindingContext.AMBIGUOUS_REFERENCE_TARGET, callee]
|
||||||
?: listOf()
|
?: listOf()
|
||||||
val candidates = targets.filterIsInstance<FunctionDescriptor>()
|
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 there are functions among candidates but none of them have last function parameter then not show the intention
|
||||||
if (candidates.isNotEmpty() && candidates.none {
|
if (candidates.isNotEmpty() && candidates.none { candidate ->
|
||||||
val params = it.valueParameters
|
val params = candidate.valueParameters
|
||||||
params.lastOrNull()?.type?.isFunctionType == true && params.count { it.type.isFunctionType } == lambdaArgumentCount
|
params.lastOrNull()?.type?.isFunctionType == true && params.count { it.type.isFunctionType } == lambdaArgumentCount
|
||||||
}) return false
|
}
|
||||||
|
) return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@@ -160,8 +155,7 @@ fun KtCallExpression.moveFunctionLiteralOutsideParentheses() {
|
|||||||
/* we should not remove empty parenthesis when callee is a call too - it won't parse */
|
/* we should not remove empty parenthesis when callee is a call too - it won't parse */
|
||||||
if (argumentList.arguments.size == 1 && calleeExpression !is KtCallExpression) {
|
if (argumentList.arguments.size == 1 && calleeExpression !is KtCallExpression) {
|
||||||
argumentList.delete()
|
argumentList.delete()
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
argumentList.removeArgument(argument)
|
argumentList.removeArgument(argument)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -171,9 +165,8 @@ fun KtBlockExpression.appendElement(element: KtElement, addNewLine: Boolean = fa
|
|||||||
val newLine = KtPsiFactory(this).createNewLine()
|
val newLine = KtPsiFactory(this).createNewLine()
|
||||||
val anchor = if (rBrace == null) {
|
val anchor = if (rBrace == null) {
|
||||||
val lastChild = lastChild
|
val lastChild = lastChild
|
||||||
if (lastChild !is PsiWhiteSpace) addAfter(newLine, lastChild)!! else lastChild
|
lastChild as? PsiWhiteSpace ?: addAfter(newLine, lastChild)!!
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
rBrace.prevSibling!!
|
rBrace.prevSibling!!
|
||||||
}
|
}
|
||||||
val addedElement = addAfter(element, anchor)!! as KtElement
|
val addedElement = addAfter(element, anchor)!! as KtElement
|
||||||
@@ -207,8 +200,7 @@ private fun deleteElementWithDelimiters(element: PsiElement) {
|
|||||||
if (paramBefore != null) {
|
if (paramBefore != null) {
|
||||||
from = paramBefore.nextSibling
|
from = paramBefore.nextSibling
|
||||||
to = element
|
to = element
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
val paramAfter = PsiTreeUtil.getNextSiblingOfType<PsiElement>(element, element.javaClass)
|
val paramAfter = PsiTreeUtil.getNextSiblingOfType<PsiElement>(element, element.javaClass)
|
||||||
|
|
||||||
from = element
|
from = element
|
||||||
@@ -258,22 +250,22 @@ fun KtModifierListOwner.setVisibility(visibilityModifier: KtModifierKeywordToken
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? =
|
fun KtDeclaration.implicitVisibility(): KtModifierKeywordToken? =
|
||||||
when {
|
when {
|
||||||
this is KtConstructor<*> -> {
|
this is KtConstructor<*> -> {
|
||||||
val klass = getContainingClassOrObject()
|
val klass = getContainingClassOrObject()
|
||||||
if (klass is KtClass && (klass.isEnum() || klass.isSealed())) KtTokens.PRIVATE_KEYWORD
|
if (klass is KtClass && (klass.isEnum() || klass.isSealed())) KtTokens.PRIVATE_KEYWORD
|
||||||
else KtTokens.DEFAULT_VISIBILITY_KEYWORD
|
else KtTokens.DEFAULT_VISIBILITY_KEYWORD
|
||||||
}
|
|
||||||
hasModifier(KtTokens.OVERRIDE_KEYWORD) -> {
|
|
||||||
(resolveToDescriptorIfAny() as? CallableMemberDescriptor)
|
|
||||||
?.overriddenDescriptors
|
|
||||||
?.let { OverridingUtil.findMaxVisibility(it) }
|
|
||||||
?.toKeywordToken()
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
KtTokens.DEFAULT_VISIBILITY_KEYWORD
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
hasModifier(KtTokens.OVERRIDE_KEYWORD) -> {
|
||||||
|
(resolveToDescriptorIfAny() as? CallableMemberDescriptor)
|
||||||
|
?.overriddenDescriptors
|
||||||
|
?.let { OverridingUtil.findMaxVisibility(it) }
|
||||||
|
?.toKeywordToken()
|
||||||
|
}
|
||||||
|
else -> {
|
||||||
|
KtTokens.DEFAULT_VISIBILITY_KEYWORD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
fun KtModifierListOwner.canBePrivate() = modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) != true
|
fun KtModifierListOwner.canBePrivate() = modifierList?.hasModifier(KtTokens.ABSTRACT_KEYWORD) != true
|
||||||
|
|
||||||
@@ -336,12 +328,13 @@ fun KtDeclaration.implicitModality(): KtModifierKeywordToken {
|
|||||||
val extensions = DeclarationAttributeAltererExtension.getInstances(this.project)
|
val extensions = DeclarationAttributeAltererExtension.getInstances(this.project)
|
||||||
for (extension in extensions) {
|
for (extension in extensions) {
|
||||||
val newModality = extension.refineDeclarationModality(
|
val newModality = extension.refineDeclarationModality(
|
||||||
this,
|
this,
|
||||||
descriptor as? ClassDescriptor,
|
descriptor as? ClassDescriptor,
|
||||||
containingDescriptor,
|
containingDescriptor,
|
||||||
mapModalityToken(predictedModality),
|
mapModalityToken(predictedModality),
|
||||||
bindingContext,
|
bindingContext,
|
||||||
isImplicitModality = true)
|
isImplicitModality = true
|
||||||
|
)
|
||||||
|
|
||||||
if (newModality != null) {
|
if (newModality != null) {
|
||||||
predictedModality = mapModality(newModality)
|
predictedModality = mapModality(newModality)
|
||||||
@@ -375,7 +368,8 @@ private fun KtDeclaration.predictImplicitModality(): KtModifierKeywordToken {
|
|||||||
if (hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
|
if (hasModifier(KtTokens.OVERRIDE_KEYWORD)) {
|
||||||
if (klass.hasModifier(KtTokens.ABSTRACT_KEYWORD) ||
|
if (klass.hasModifier(KtTokens.ABSTRACT_KEYWORD) ||
|
||||||
klass.hasModifier(KtTokens.OPEN_KEYWORD) ||
|
klass.hasModifier(KtTokens.OPEN_KEYWORD) ||
|
||||||
klass.hasModifier(KtTokens.SEALED_KEYWORD)) {
|
klass.hasModifier(KtTokens.SEALED_KEYWORD)
|
||||||
|
) {
|
||||||
return KtTokens.OPEN_KEYWORD
|
return KtTokens.OPEN_KEYWORD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -412,11 +406,11 @@ fun KtTypeParameterListOwner.addTypeParameter(typeParameter: KtTypeParameter): K
|
|||||||
val list = KtPsiFactory(this).createTypeParameterList("<X>")
|
val list = KtPsiFactory(this).createTypeParameterList("<X>")
|
||||||
list.parameters[0].replace(typeParameter)
|
list.parameters[0].replace(typeParameter)
|
||||||
val leftAnchor = when (this) {
|
val leftAnchor = when (this) {
|
||||||
is KtClass -> nameIdentifier ?: getClassOrInterfaceKeyword()
|
is KtClass -> nameIdentifier ?: getClassOrInterfaceKeyword()
|
||||||
is KtNamedFunction -> funKeyword
|
is KtNamedFunction -> funKeyword
|
||||||
is KtProperty -> valOrVarKeyword
|
is KtProperty -> valOrVarKeyword
|
||||||
else -> null
|
else -> null
|
||||||
} ?: return null
|
} ?: return null
|
||||||
return (addAfter(list, leftAnchor) as KtTypeParameterList).parameters.first()
|
return (addAfter(list, leftAnchor) as KtTypeParameterList).parameters.first()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user