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