Minor: refactoring codeInliner package

This commit is contained in:
Dmitry Gridin
2019-03-27 16:15:25 +07:00
parent 16ae313b22
commit c343876f7c
7 changed files with 127 additions and 129 deletions
@@ -45,8 +45,7 @@ class ClassUsageReplacementStrategy(
constructorReplacementStrategy?.createReplacer(usage)?.let { return it } constructorReplacementStrategy?.createReplacer(usage)?.let { return it }
val parent = usage.parent when (val parent = usage.parent) {
when (parent) {
is KtUserType -> { is KtUserType -> {
if (typeReplacement == null) return null if (typeReplacement == null) return null
return { return {
@@ -91,8 +90,7 @@ class ClassUsageReplacementStrategy(
val result = if (expressionToReplace != newExpression) { val result = if (expressionToReplace != newExpression) {
expressionToReplace.replaced(newExpression) expressionToReplace.replaced(newExpression)
} } else {
else {
expressionToReplace expressionToReplace
} }
@@ -354,12 +354,11 @@ class CodeInliner<TCallElement : KtElement>(
return Argument(valueAssigned, bindingContext.getType(valueAssigned)) return Argument(valueAssigned, bindingContext.getType(valueAssigned))
} }
val resolvedArgument = resolvedCall.valueArguments[parameter]!! when (val resolvedArgument = resolvedCall.valueArguments[parameter] ?: return null) {
when (resolvedArgument) {
is ExpressionValueArgument -> { is ExpressionValueArgument -> {
val valueArgument = resolvedArgument.valueArgument!! val valueArgument = resolvedArgument.valueArgument
val expression = valueArgument.getArgumentExpression()!! val expression = valueArgument?.getArgumentExpression()
expression.mark(USER_CODE_KEY) expression?.mark(USER_CODE_KEY) ?: return null
if (valueArgument is LambdaArgument) { if (valueArgument is LambdaArgument) {
expression.mark(WAS_FUNCTION_LITERAL_ARGUMENT_KEY) expression.mark(WAS_FUNCTION_LITERAL_ARGUMENT_KEY)
} }
@@ -447,9 +446,9 @@ class CodeInliner<TCallElement : KtElement>(
ShortenReferences { ShortenReferences.Options(removeThis = true) }.process(it, shortenFilter) ShortenReferences { ShortenReferences.Options(removeThis = true) }.process(it, shortenFilter)
} }
newElements.forEach { newElements.forEach { element ->
// clean up user data // clean up user data
it.forEachDescendantOfType<KtExpression> { element.forEachDescendantOfType<KtExpression> {
it.clear(USER_CODE_KEY) it.clear(USER_CODE_KEY)
it.clear(CodeToInline.PARAMETER_USAGE_KEY) it.clear(CodeToInline.PARAMETER_USAGE_KEY)
it.clear(CodeToInline.TYPE_PARAMETER_USAGE_KEY) it.clear(CodeToInline.TYPE_PARAMETER_USAGE_KEY)
@@ -457,7 +456,7 @@ class CodeInliner<TCallElement : KtElement>(
it.clear(RECEIVER_VALUE_KEY) it.clear(RECEIVER_VALUE_KEY)
it.clear(WAS_FUNCTION_LITERAL_ARGUMENT_KEY) it.clear(WAS_FUNCTION_LITERAL_ARGUMENT_KEY)
} }
it.forEachDescendantOfType<KtValueArgument> { element.forEachDescendantOfType<KtValueArgument> {
it.clear(MAKE_ARGUMENT_NAMED_KEY) it.clear(MAKE_ARGUMENT_NAMED_KEY)
it.clear(DEFAULT_PARAMETER_VALUE_KEY) it.clear(DEFAULT_PARAMETER_VALUE_KEY)
} }
@@ -130,7 +130,11 @@ class CodeToInlineBuilder(
} }
} }
private fun insertExplicitTypeArguments(codeToInline: MutableCodeToInline, bindingContext: BindingContext, analyze: () -> BindingContext): BindingContext { private fun insertExplicitTypeArguments(
codeToInline: MutableCodeToInline,
bindingContext: BindingContext,
analyze: () -> BindingContext
): BindingContext {
val typeArgsToAdd = ArrayList<Pair<KtCallExpression, KtTypeArgumentList>>() val typeArgsToAdd = ArrayList<Pair<KtCallExpression, KtTypeArgumentList>>()
codeToInline.forEachDescendantOfType<KtCallExpression> { codeToInline.forEachDescendantOfType<KtCallExpression> {
if (InsertExplicitTypeArgumentsIntention.isApplicableTo(it, bindingContext)) { if (InsertExplicitTypeArgumentsIntention.isApplicableTo(it, bindingContext)) {
@@ -162,8 +166,7 @@ class CodeToInlineBuilder(
if (expression.getReceiverExpression() == null) { if (expression.getReceiverExpression() == null) {
if (target is ValueParameterDescriptor && target.containingDeclaration == targetCallable) { if (target is ValueParameterDescriptor && target.containingDeclaration == targetCallable) {
expression.putCopyableUserData(CodeToInline.PARAMETER_USAGE_KEY, target.name) expression.putCopyableUserData(CodeToInline.PARAMETER_USAGE_KEY, target.name)
} } else if (target is TypeParameterDescriptor && target.containingDeclaration == targetCallable) {
else if (target is TypeParameterDescriptor && target.containingDeclaration == targetCallable) {
expression.putCopyableUserData(CodeToInline.TYPE_PARAMETER_USAGE_KEY, target.name) expression.putCopyableUserData(CodeToInline.TYPE_PARAMETER_USAGE_KEY, target.name)
} }
@@ -187,9 +190,13 @@ class CodeToInlineBuilder(
// add receivers in reverse order because arguments of a call were processed after the callee's name // add receivers in reverse order because arguments of a call were processed after the callee's name
for ((expr, receiverExpression) in receiversToAdd.asReversed()) { for ((expr, receiverExpression) in receiversToAdd.asReversed()) {
val expressionToReplace = expr.parent as? KtCallExpression ?: expr val expressionToReplace = expr.parent as? KtCallExpression ?: expr
codeToInline.replaceExpression(expressionToReplace, codeToInline.replaceExpression(
psiFactory.createExpressionByPattern("$0.$1", receiverExpression, expressionToReplace, expressionToReplace,
reformat = reformat)) psiFactory.createExpressionByPattern(
"$0.$1", receiverExpression, expressionToReplace,
reformat = reformat
)
)
} }
} }
} }
@@ -95,10 +95,10 @@ internal fun MutableCodeToInline.toNonMutable(): CodeToInline {
} }
internal inline fun <reified T : PsiElement> MutableCodeToInline.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> { internal inline fun <reified T : PsiElement> MutableCodeToInline.collectDescendantsOfType(noinline predicate: (T) -> Boolean = { true }): List<T> {
return expressions.flatMap { it.collectDescendantsOfType<T>({ true }, predicate) } return expressions.flatMap { it.collectDescendantsOfType({ true }, predicate) }
} }
internal inline fun <reified T : PsiElement> MutableCodeToInline.forEachDescendantOfType(noinline action: (T) -> Unit) { internal inline fun <reified T : PsiElement> MutableCodeToInline.forEachDescendantOfType(noinline action: (T) -> Unit) {
expressions.forEach { it.forEachDescendantOfType<T>(action) } expressions.forEach { it.forEachDescendantOfType(action) }
} }
@@ -63,7 +63,7 @@ internal class AnnotationEntryReplacementPerformer(
assert(range.first is KtAnnotationEntry) assert(range.first is KtAnnotationEntry)
val annotationEntry = range.first as KtAnnotationEntry val annotationEntry = range.first as KtAnnotationEntry
val text = annotationEntry.valueArguments.single().getArgumentExpression()!!.text val text = annotationEntry.valueArguments.single().getArgumentExpression()!!.text
return annotationEntry.replaced(psiFactory.createAnnotationEntry("@" + text)) return annotationEntry.replaced(psiFactory.createAnnotationEntry("@$text"))
} }
} }
@@ -77,7 +77,8 @@ internal class ExpressionReplacementPerformer(
return if (parent is KtStringTemplateEntryWithExpression return if (parent is KtStringTemplateEntryWithExpression
// Do not mix raw and non-raw templates // Do not mix raw and non-raw templates
&& parent.parent.firstChild.text == templateExpression.firstChild.text) { && parent.parent.firstChild.text == templateExpression.firstChild.text
) {
val entriesToAdd = templateExpression.entries val entriesToAdd = templateExpression.entries
val grandParentTemplateExpression = parent.parent as KtStringTemplateExpression val grandParentTemplateExpression = parent.parent as KtStringTemplateExpression
@@ -87,17 +88,16 @@ internal class ExpressionReplacementPerformer(
val nextElement = parent.nextSibling val nextElement = parent.nextSibling
if (lastNewEntry is KtSimpleNameStringTemplateEntry && if (lastNewEntry is KtSimpleNameStringTemplateEntry &&
lastNewEntry.expression != null && lastNewEntry.expression != null &&
!canPlaceAfterSimpleNameEntry(nextElement)) { !canPlaceAfterSimpleNameEntry(nextElement)
) {
lastNewEntry.replace(KtPsiFactory(this).createBlockStringTemplateEntry(lastNewEntry.expression!!)) lastNewEntry.replace(KtPsiFactory(this).createBlockStringTemplateEntry(lastNewEntry.expression!!))
} }
grandParentTemplateExpression grandParentTemplateExpression
} } else null
else null
parent.delete() parent.delete()
result result
} } else {
else {
replaced(templateExpression) replaced(templateExpression)
} }
} }
@@ -129,8 +129,7 @@ internal class ExpressionReplacementPerformer(
if (canDropElementToBeReplaced) { if (canDropElementToBeReplaced) {
stub.delete() stub.delete()
null null
} } else {
else {
stub.replaced(psiFactory.createExpression("Unit")) stub.replaced(psiFactory.createExpression("Unit"))
} }
} }
@@ -141,17 +140,14 @@ internal class ExpressionReplacementPerformer(
var range = if (replaced != null) { var range = if (replaced != null) {
if (insertedStatements.isEmpty()) { if (insertedStatements.isEmpty()) {
PsiChildRange.singleElement(replaced) PsiChildRange.singleElement(replaced)
} } else {
else {
val statement = insertedStatements.first() val statement = insertedStatements.first()
PsiChildRange(statement, replaced.parentsWithSelf.first { it.parent == statement.parent }) PsiChildRange(statement, replaced.parentsWithSelf.first { it.parent == statement.parent })
} }
} } else {
else {
if (insertedStatements.isEmpty()) { if (insertedStatements.isEmpty()) {
PsiChildRange.EMPTY PsiChildRange.EMPTY
} } else {
else {
PsiChildRange(insertedStatements.first(), insertedStatements.last()) PsiChildRange(insertedStatements.first(), insertedStatements.last())
} }
} }
@@ -160,8 +156,7 @@ internal class ExpressionReplacementPerformer(
listener?.attach() listener?.attach()
try { try {
range = postProcessing(range) range = postProcessing(range)
} } finally {
finally {
listener?.detach() listener?.detach()
} }
@@ -231,7 +226,7 @@ internal class ExpressionReplacementPerformer(
private fun <TElement : KtElement> withElementToBeReplacedPreserved(action: () -> TElement): TElement { private fun <TElement : KtElement> withElementToBeReplacedPreserved(action: () -> TElement): TElement {
elementToBeReplaced.putCopyableUserData(ELEMENT_TO_BE_REPLACED_KEY, Unit) elementToBeReplaced.putCopyableUserData(ELEMENT_TO_BE_REPLACED_KEY, Unit)
val result = action() val result = action()
elementToBeReplaced = result.findDescendantOfType<KtExpression> { it.getCopyableUserData(ELEMENT_TO_BE_REPLACED_KEY) != null }!! elementToBeReplaced = result.findDescendantOfType { it.getCopyableUserData(ELEMENT_TO_BE_REPLACED_KEY) != null }!!
elementToBeReplaced.putCopyableUserData(ELEMENT_TO_BE_REPLACED_KEY, null) elementToBeReplaced.putCopyableUserData(ELEMENT_TO_BE_REPLACED_KEY, null)
return result return result
} }
@@ -97,7 +97,7 @@ fun UsageReplacementStrategy.replaceUsages(
if (processUsages(usagesToProcess, targetDeclaration, importsToDelete)) break if (processUsages(usagesToProcess, targetDeclaration, importsToDelete)) break
// some usages may get invalidated we need to find them in the tree // some usages may get invalidated we need to find them in the tree
usagesToProcess = file.collectDescendantsOfType<KtSimpleNameExpression> { it.getCopyableUserData(KEY) != null } usagesToProcess = file.collectDescendantsOfType { it.getCopyableUserData(KEY) != null }
} }
file.forEachDescendantOfType<KtSimpleNameExpression> { it.putCopyableUserData(KEY, null) } file.forEachDescendantOfType<KtSimpleNameExpression> { it.putCopyableUserData(KEY, null) }
@@ -138,17 +138,18 @@ private fun UsageReplacementStrategy.processUsages(
} }
createReplacer(usage)?.invoke() createReplacer(usage)?.invoke()
} } catch (e: Throwable) {
catch (e: Throwable) {
LOG.error(e) LOG.error(e)
} }
} }
return !invalidUsagesFound return !invalidUsagesFound
} }
private fun UsageReplacementStrategy.specialUsageProcessing(usage: KtSimpleNameExpression, targetDeclaration: KtNamedDeclaration?): Boolean { private fun UsageReplacementStrategy.specialUsageProcessing(
val usageParent = usage.parent usage: KtSimpleNameExpression,
when (usageParent) { targetDeclaration: KtNamedDeclaration?
): Boolean {
when (val usageParent = usage.parent) {
is KtCallableReferenceExpression -> { is KtCallableReferenceExpression -> {
val grandParent = usageParent.parent val grandParent = usageParent.parent
ConvertReferenceToLambdaIntention().applyTo(usageParent, null) ConvertReferenceToLambdaIntention().applyTo(usageParent, null)
@@ -100,12 +100,10 @@ internal fun MutableCodeToInline.introduceValue(
} }
replaceUsages(name) replaceUsages(name)
} } else {
else {
statementsBefore.add(0, value) statementsBefore.add(0, value)
} }
} } else {
else {
val useIt = !isNameUsed("it") val useIt = !isNameUsed("it")
val name = if (useIt) Name.identifier("it") else suggestName { !isNameUsed(it) } val name = if (useIt) Name.identifier("it") else suggestName { !isNameUsed(it) }
replaceUsages(name) replaceUsages(name)