From bb8c3495b8e8b0b1b97a9afad433b0ae05f7d099 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Wed, 23 May 2018 12:02:00 +0300 Subject: [PATCH] Reformat & cleanup: CodeInliner --- .../kotlin/idea/codeInliner/CodeInliner.kt | 136 ++++++++++-------- 1 file changed, 75 insertions(+), 61 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt index 1a94e9695e4..491edec64e9 100644 --- a/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt +++ b/idea/src/org/jetbrains/kotlin/idea/codeInliner/CodeInliner.kt @@ -40,7 +40,6 @@ import org.jetbrains.kotlin.resolve.bindingContextUtil.isUsedAsExpression import org.jetbrains.kotlin.resolve.calls.callUtil.getResolvedCall import org.jetbrains.kotlin.resolve.calls.model.* import org.jetbrains.kotlin.resolve.descriptorUtil.isExtension -import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.scopes.LexicalScope import org.jetbrains.kotlin.resolve.scopes.receivers.ImplicitReceiver import org.jetbrains.kotlin.types.KotlinType @@ -49,12 +48,12 @@ import org.jetbrains.kotlin.utils.addIfNotNull import java.util.* class CodeInliner( - private val nameExpression: KtSimpleNameExpression, - private val bindingContext: BindingContext, - private val resolvedCall: ResolvedCall, - private val callElement: TCallElement, - private val inlineSetter: Boolean, - codeToInline: CodeToInline + private val nameExpression: KtSimpleNameExpression, + private val bindingContext: BindingContext, + private val resolvedCall: ResolvedCall, + private val callElement: TCallElement, + private val inlineSetter: Boolean, + codeToInline: CodeToInline ) { private val codeToInline = codeToInline.toMutable() private val project = nameExpression.project @@ -66,8 +65,8 @@ class CodeInliner( val qualifiedElement = if (callElement is KtExpression) callElement.getQualifiedExpressionForSelectorOrThis() else callElement val assignment = (qualifiedElement as? KtExpression) - ?.getAssignmentByLHS() - ?.takeIf { it.operationToken == KtTokens.EQ } + ?.getAssignmentByLHS() + ?.takeIf { it.operationToken == KtTokens.EQ } val callableForParameters = if (assignment != null && descriptor is PropertyDescriptor) descriptor.setter?.takeIf { inlineSetter && it.hasBody() } ?: descriptor else @@ -114,8 +113,7 @@ class CodeInliner( if (elementToBeReplaced is KtSafeQualifiedExpression) { wrapCodeForSafeCall(receiver!!, receiverType, elementToBeReplaced) - } - else if (callElement is KtBinaryExpression && callElement.operationToken == KtTokens.IDENTIFIER) { + } else if (callElement is KtBinaryExpression && callElement.operationToken == KtTokens.IDENTIFIER) { keepInfixFormIfPossible() } @@ -129,13 +127,19 @@ class CodeInliner( for ((parameter, value, valueType) in introduceValuesForParameters) { val usagesReplaced = codeToInline.collectDescendantsOfType { it[PARAMETER_VALUE_KEY] == parameter } - codeToInline.introduceValue(value, valueType, usagesReplaced, elementToBeReplaced, nameSuggestion = parameter.name.asString()) + codeToInline.introduceValue( + value, + valueType, + usagesReplaced, + elementToBeReplaced, + nameSuggestion = parameter.name.asString() + ) } } codeToInline.fqNamesToImport - .flatMap { file.resolveImportReference(it) } - .forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) } + .flatMap { file.resolveImportReference(it) } + .forEach { ImportInsertHelper.getInstance(project).importDescriptor(file, it) } val replacementPerformer = when (elementToBeReplaced) { is KtExpression -> ExpressionReplacementPerformer(codeToInline, elementToBeReplaced) @@ -152,8 +156,10 @@ class CodeInliner( }) } - private fun renameDuplicates(declarations: List, - lexicalScope: LexicalScope) { + private fun renameDuplicates( + declarations: List, + lexicalScope: LexicalScope + ) { val validator = CollectingNameValidator { !it.nameHasConflictsInScope(lexicalScope) } for (declaration in declarations) { @@ -201,9 +207,10 @@ class CodeInliner( } private data class IntroduceValueForParameter( - val parameter: ValueParameterDescriptor, - val value: KtExpression, - val valueType: KotlinType?) + val parameter: ValueParameterDescriptor, + val value: KtExpression, + val valueType: KotlinType? + ) private fun processTypeParameterUsages() { val typeParameters = resolvedCall.resultingDescriptor.original.typeParameters @@ -221,10 +228,9 @@ class CodeInliner( val type = resolvedCall.typeArguments[typeParameter]!! val typeElement = if (explicitTypeArgs != null) { // we use explicit type arguments if available to avoid shortening - val _typeElement = explicitTypeArgs[index].typeReference?.typeElement ?: continue - _typeElement.marked(USER_CODE_KEY) - } - else { + val explicitArgTypeElement = explicitTypeArgs[index].typeReference?.typeElement ?: continue + explicitArgTypeElement.marked(USER_CODE_KEY) + } else { psiFactory.createType(IdeDescriptorRenderers.SOURCE_CODE.renderType(type)).typeElement!! } @@ -235,16 +241,16 @@ class CodeInliner( if (parent is KtClassLiteralExpression && typeClassifier != null) { // for class literal ("X::class") we need type arguments only for kotlin.Array val arguments = - if (typeElement is KtUserType && KotlinBuiltIns.isArray(type)) typeElement.typeArgumentList?.text.orEmpty() - else "" - codeToInline.replaceExpression(usage, psiFactory.createExpression( + if (typeElement is KtUserType && KotlinBuiltIns.isArray(type)) typeElement.typeArgumentList?.text.orEmpty() + else "" + codeToInline.replaceExpression( + usage, psiFactory.createExpression( IdeDescriptorRenderers.SOURCE_CODE.renderClassifierName(typeClassifier) + arguments - )) - } - else if (parent is KtUserType) { + ) + ) + } else if (parent is KtUserType) { parent.replace(typeElement) - } - else { + } else { //TODO: tests for this? codeToInline.replaceExpression(usage, psiFactory.createExpression(typeElement.text)) } @@ -270,8 +276,7 @@ class CodeInliner( if (expressionToBeReplaced.isUsedAsExpression(bindingContext)) { val thisReplaced = codeToInline.collectDescendantsOfType { it[RECEIVER_VALUE_KEY] } codeToInline.introduceValue(receiver, receiverType, thisReplaced, expressionToBeReplaced, safeCall = true) - } - else { + } else { val ifExpression = psiFactory.buildExpression { appendFixedText("if (") appendExpression(receiver) @@ -311,13 +316,21 @@ class CodeInliner( return when (this) { is KtSimpleNameExpression -> false is KtQualifiedExpression -> receiverExpression.shouldKeepValue(usageCount) || selectorExpression.shouldKeepValue(usageCount) - is KtUnaryExpression -> operationToken in setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) || baseExpression.shouldKeepValue(usageCount) + is KtUnaryExpression -> operationToken in setOf(KtTokens.PLUSPLUS, KtTokens.MINUSMINUS) || baseExpression.shouldKeepValue( + usageCount + ) is KtStringTemplateExpression -> entries.any { if (sideEffectOnly) it.expression.shouldKeepValue(usageCount) else it is KtStringTemplateEntryWithExpression } is KtThisExpression, is KtSuperExpression, is KtConstantExpression -> false is KtParenthesizedExpression -> expression.shouldKeepValue(usageCount) - is KtArrayAccessExpression -> if (sideEffectOnly) arrayExpression.shouldKeepValue(usageCount) || indexExpressions.any { it.shouldKeepValue(usageCount) } else true + is KtArrayAccessExpression -> if (sideEffectOnly) arrayExpression.shouldKeepValue(usageCount) || indexExpressions.any { + it.shouldKeepValue( + usageCount + ) + } else true is KtBinaryExpression -> if (sideEffectOnly) left.shouldKeepValue(usageCount) || right.shouldKeepValue(usageCount) else true - is KtIfExpression -> if (sideEffectOnly) condition.shouldKeepValue(usageCount) || then.shouldKeepValue(usageCount) || `else`.shouldKeepValue(usageCount) else true + is KtIfExpression -> if (sideEffectOnly) condition.shouldKeepValue(usageCount) || then.shouldKeepValue(usageCount) || `else`.shouldKeepValue( + usageCount + ) else true is KtBinaryExpressionWithTypeRHS -> true null -> false else -> true @@ -325,17 +338,18 @@ class CodeInliner( } private class Argument( - val expression: KtExpression, - val expressionType: KotlinType?, - val isNamed: Boolean = false, - val isDefaultValue: Boolean = false) + val expression: KtExpression, + val expressionType: KotlinType?, + val isNamed: Boolean = false, + val isDefaultValue: Boolean = false + ) private fun argumentForParameter(parameter: ValueParameterDescriptor, callableDescriptor: CallableDescriptor): Argument? { if (callableDescriptor is PropertySetterDescriptor) { val valueAssigned = (callElement as? KtExpression) - ?.getQualifiedExpressionForSelectorOrThis() - ?.getAssignmentByLHS() - ?.right ?: return null + ?.getQualifiedExpressionForSelectorOrThis() + ?.getAssignmentByLHS() + ?.right ?: return null return Argument(valueAssigned, bindingContext.getType(valueAssigned)) } @@ -419,8 +433,7 @@ class CodeInliner( val shortenFilter = { element: PsiElement -> if (element[USER_CODE_KEY]) { ShortenReferences.FilterResult.SKIP - } - else { + } else { val thisReceiver = (element as? KtQualifiedExpression)?.receiverExpression as? KtThisExpression if (thisReceiver != null && thisReceiver[USER_CODE_KEY]) // don't remove explicit 'this' coming from user's code ShortenReferences.FilterResult.GO_INSIDE @@ -430,7 +443,7 @@ class CodeInliner( } val newElements = elements.map { - ShortenReferences({ ShortenReferences.Options(removeThis = true) }).process(it, shortenFilter) + ShortenReferences { ShortenReferences.Options(removeThis = true) }.process(it, shortenFilter) } newElements.forEach { @@ -556,8 +569,7 @@ class CodeInliner( val list = parent as KtValueArgumentList if (arguments.isEmpty()) { list.removeArgument(this) - } - else { + } else { var anchor = this for (argument in arguments) { anchor = list.addArgumentAfter(argument, anchor) @@ -569,7 +581,7 @@ class CodeInliner( private fun restoreFunctionLiteralArguments(expression: KtElement) { val callExpressions = ArrayList() - expression.forEachDescendantOfType(fun (expr) { + expression.forEachDescendantOfType(fun(expr) { if (!expr[WAS_FUNCTION_LITERAL_ARGUMENT_KEY]) return assert(expr.unpackFunctionLiteral() != null) @@ -592,24 +604,26 @@ class CodeInliner( callExpressions.forEach { it.moveFunctionLiteralOutsideParentheses() } } - private operator fun PsiElement.get(key: Key): T? = getCopyableUserData(key) + private operator fun PsiElement.get(key: Key): T? = getCopyableUserData(key) private operator fun PsiElement.get(key: Key): Boolean = getCopyableUserData(key) != null - private fun KtElement.clear(key: Key) = putCopyableUserData(key, null) - private fun KtElement.put(key: Key, value: T) = putCopyableUserData(key, value) + private fun KtElement.clear(key: Key) = putCopyableUserData(key, null) + private fun KtElement.put(key: Key, value: T) = putCopyableUserData(key, value) private fun KtElement.mark(key: Key) = putCopyableUserData(key, Unit) - private fun T.marked(key: Key): T { + private fun T.marked(key: Key): T { putCopyableUserData(key, Unit) return this } - // keys below are used on expressions - private val USER_CODE_KEY = Key("USER_CODE") - private val PARAMETER_VALUE_KEY = Key("PARAMETER_VALUE") - private val RECEIVER_VALUE_KEY = Key("RECEIVER_VALUE") - private val WAS_FUNCTION_LITERAL_ARGUMENT_KEY = Key("WAS_FUNCTION_LITERAL_ARGUMENT") + companion object { + // keys below are used on expressions + private val USER_CODE_KEY = Key("USER_CODE") + private val PARAMETER_VALUE_KEY = Key("PARAMETER_VALUE") + private val RECEIVER_VALUE_KEY = Key("RECEIVER_VALUE") + private val WAS_FUNCTION_LITERAL_ARGUMENT_KEY = Key("WAS_FUNCTION_LITERAL_ARGUMENT") - // these keys are used on KtValueArgument - private val MAKE_ARGUMENT_NAMED_KEY = Key("MAKE_ARGUMENT_NAMED") - private val DEFAULT_PARAMETER_VALUE_KEY = Key("DEFAULT_PARAMETER_VALUE") + // these keys are used on KtValueArgument + private val MAKE_ARGUMENT_NAMED_KEY = Key("MAKE_ARGUMENT_NAMED") + private val DEFAULT_PARAMETER_VALUE_KEY = Key("DEFAULT_PARAMETER_VALUE") + } }