From 4f5d121478907dad26943d1e319ad3be26728207 Mon Sep 17 00:00:00 2001 From: Valentin Kipyatkov Date: Wed, 12 Feb 2020 11:55:47 +0200 Subject: [PATCH] Minor code improvements --- .../kotlin/idea/slicer/InflowSlicer.kt | 75 ++++++++++--------- .../kotlin/idea/slicer/OutflowSlicer.kt | 5 +- 2 files changed, 43 insertions(+), 37 deletions(-) diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt index 5de9219cb4a..4a60c0e541c 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt @@ -53,7 +53,8 @@ class InflowSlicer( override fun processChildren() { if (parentUsage.forcedExpressionMode) { - return processExpression(element) + processExpression(element) + return } when (element) { @@ -67,11 +68,9 @@ class InflowSlicer( private fun processProperty(property: KtProperty) { if (property.hasDelegateExpression()) { - val getter = (property.unsafeResolveToDescriptor() as VariableDescriptorWithAccessors).getter - val delegateGetterResolvedCall = getter?.let { - val bindingContext = property.analyzeWithContent() - bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] - } + val getter = (property.unsafeResolveToDescriptor() as VariableDescriptorWithAccessors).getter ?: return + val bindingContext = property.analyzeWithContent() + val delegateGetterResolvedCall = bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, getter] delegateGetterResolvedCall?.resultingDescriptor?.originalSource?.getPsi()?.passToProcessor() return } @@ -108,36 +107,39 @@ class InflowSlicer( ReferencesSearch.search(function, analysisScope) .filterIsInstance() - .forEach { (it.element.parent as? KtProperty)?.processPropertyAssignments() } + .mapNotNull { it.element.parent as? KtProperty } + .forEach { it.processPropertyAssignments() } } val parameterDescriptor = parameter.resolveToParameterDescriptorIfAny(BodyResolveMode.FULL) ?: return - fun processCall(usageInfo: UsageInfo) { - val refElement = usageInfo.element ?: return - val refParent = refElement.parent - - val argumentExpression = when { - refElement is KtExpression -> { - val callElement = refElement.getParentOfTypeAndBranch { calleeExpression } ?: return - val resolvedCall = callElement.resolveToCall() ?: return - val callParameterDescriptor = resolvedCall.resultingDescriptor.valueParameters[parameterDescriptor.index] - val resolvedArgument = resolvedCall.valueArguments[callParameterDescriptor] ?: return - when (resolvedArgument) { - is DefaultValueArgument -> parameter.defaultValue - is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression() - else -> null - } - } - - refParent is PsiCall -> refParent.argumentList?.expressions?.getOrNull(parameter.parameterIndex()) - - else -> null - } - argumentExpression?.passToProcessorAsValue() - } - if (function is KtFunction) { + fun extractArgumentExpression(refElement: PsiElement): PsiElement? { + val refParent = refElement.parent + return when { + refElement is KtExpression -> { + val callElement = refElement.getParentOfTypeAndBranch { calleeExpression } ?: return null + val resolvedCall = callElement.resolveToCall() ?: return null + val callParameterDescriptor = resolvedCall.resultingDescriptor.valueParameters[parameterDescriptor.index] + val resolvedArgument = resolvedCall.valueArguments[callParameterDescriptor] ?: return null + when (resolvedArgument) { + is DefaultValueArgument -> parameter.defaultValue + is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression() + else -> null + } + } + + refParent is PsiCall -> refParent.argumentList?.expressions?.getOrNull(parameter.parameterIndex()) + + else -> null + } + } + + fun processCall(usageInfo: UsageInfo) { + val refElement = usageInfo.element ?: return + extractArgumentExpression(refElement)?.passToProcessorAsValue() + } + processCalls(function, analysisScope, includeOverriders, ::processCall) } @@ -149,7 +151,7 @@ class InflowSlicer( private fun processExpression(expression: KtExpression) { val lambda = when (expression) { is KtLambdaExpression -> expression.functionLiteral - is KtNamedFunction -> if (expression.name == null) expression else null + is KtNamedFunction -> expression.takeIf { expression.name == null } else -> null } if (lambda != null) { @@ -188,13 +190,16 @@ class InflowSlicer( is MagicInstruction -> when (createdAt.kind) { MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> createdAt.passInputsToProcessor() + MagicKind.BOUND_CALLABLE_REFERENCE, MagicKind.UNBOUND_CALLABLE_REFERENCE -> { - val callableRefExpr = expressionValue.element as? KtCallableReferenceExpression + val callableRefExpr = expressionValue.element as? KtCallableReferenceExpression ?: return + val bindingContext = expression.analyze() + val referencedDescriptor = bindingContext[BindingContext.REFERENCE_TARGET, callableRefExpr.callableReference] ?: return + val referencedDeclaration = (referencedDescriptor as? DeclarationDescriptorWithSource)?.originalSource?.getPsi() ?: return - val referencedDescriptor = expression.analyze()[BindingContext.REFERENCE_TARGET, callableRefExpr.callableReference] ?: return - val referencedDeclaration = (referencedDescriptor as? DeclarationDescriptorWithSource)?.originalSource?.getPsi() ?: return referencedDeclaration.passToProcessor(parentUsage.lambdaLevel - 1) } + else -> return } diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt index 53f0cbed9a7..4f520925ef0 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.idea.slicer import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector +import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector.* import com.intellij.psi.PsiElement import com.intellij.psi.impl.light.LightMemberReference import com.intellij.slicer.SliceUsage @@ -57,7 +58,7 @@ class OutflowSlicer( if (withDereferences) { refExpression.processDereferences() } - if (!withDereferences || KotlinReadWriteAccessDetector.INSTANCE.getExpressionAccess(refExpression) == ReadWriteAccessDetector.Access.Read) { + if (!withDereferences || KotlinReadWriteAccessDetector.INSTANCE.getExpressionAccess(refExpression) == Access.Read) { refExpression.passToProcessor() } } @@ -118,7 +119,7 @@ class OutflowSlicer( val parentCall = getParentOfTypeAndBranch { calleeExpression } ?: return null val callee = parentCall.calleeExpression?.let { KtPsiUtil.safeDeparenthesize(it) } - if (callee == this || callee is KtConstructorCalleeExpression && callee.isAncestor(this, true)) return parentCall + if (callee == this || callee is KtConstructorCalleeExpression && callee.isAncestor(this, strict = true)) return parentCall return null }