Reformat & cleanup: psiModificationUtils, especially PsiElement.replaced

This commit is contained in:
Mikhail Glukhikh
2018-08-03 16:03:41 +03:00
parent 1d2438e04e
commit 07ff2bff33
@@ -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()
} }