diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt index d1131cbb1a6..15906edd759 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt @@ -124,6 +124,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationHighlightingT import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationNavigationTest import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest +import org.jetbrains.kotlin.idea.slicer.AbstractSlicerMultiplatformTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest @@ -872,7 +873,7 @@ fun main(args: Array) { } testClass { - model("slicer", singleClass = true) + model("slicer", excludeDirs = listOf("mpp")) } testClass { @@ -882,6 +883,10 @@ fun main(args: Array) { testClass { model("slicer/inflow", singleClass = true) } + + testClass { + model("slicer/mpp", recursive = false, extension = null) + } } testGroup("idea/idea-fir/tests", "idea/testData") { diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 index d04c5b19c6a..3414ed8fbf0 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as35 @@ -126,6 +126,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest +import org.jetbrains.kotlin.idea.slicer.AbstractSlicerMultiplatformTest import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest @@ -821,7 +822,7 @@ fun main(args: Array) { } testClass { - model("slicer", singleClass = true) + model("slicer", excludeDirs = listOf("mpp")) } testClass { @@ -831,6 +832,10 @@ fun main(args: Array) { testClass { model("slicer/inflow", singleClass = true) } + + testClass { + model("slicer/mpp", recursive = false, extension = null) + } } testGroup("idea/scripting-support/test", "idea/scripting-support/testData") { diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as36 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as36 index cf94e3836ed..5a89897d114 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as36 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as36 @@ -126,6 +126,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest +import org.jetbrains.kotlin.idea.slicer.AbstractSlicerMultiplatformTest import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest @@ -821,7 +822,7 @@ fun main(args: Array) { } testClass { - model("slicer", singleClass = true) + model("slicer", excludeDirs = listOf("mpp")) } testClass { @@ -831,6 +832,10 @@ fun main(args: Array) { testClass { model("slicer/inflow", singleClass = true) } + + testClass { + model("slicer/mpp", recursive = false, extension = null) + } } testGroup("idea/scripting-support/test", "idea/scripting-support/testData") { diff --git a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as40 b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as40 index d04c5b19c6a..3414ed8fbf0 100644 --- a/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as40 +++ b/generators/tests/org/jetbrains/kotlin/generators/tests/GenerateTests.kt.as40 @@ -126,6 +126,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest +import org.jetbrains.kotlin.idea.slicer.AbstractSlicerMultiplatformTest import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest @@ -821,7 +822,7 @@ fun main(args: Array) { } testClass { - model("slicer", singleClass = true) + model("slicer", excludeDirs = listOf("mpp")) } testClass { @@ -831,6 +832,10 @@ fun main(args: Array) { testClass { model("slicer/inflow", singleClass = true) } + + testClass { + model("slicer/mpp", recursive = false, extension = null) + } } testGroup("idea/scripting-support/test", "idea/scripting-support/testData") { diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt index c35e44ee38a..f5c36cbbfc3 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/InflowSlicer.kt @@ -18,7 +18,9 @@ import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ReturnValueInstruction import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder import org.jetbrains.kotlin.cfg.pseudocodeTraverser.traverse +import org.jetbrains.kotlin.descriptors.CallableDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.idea.caches.resolve.* @@ -30,6 +32,8 @@ import org.jetbrains.kotlin.idea.references.ReferenceAccess import org.jetbrains.kotlin.idea.references.readWriteAccessWithFullExpression import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders +import org.jetbrains.kotlin.idea.util.actualsForExpected +import org.jetbrains.kotlin.idea.util.isExpectDeclaration import org.jetbrains.kotlin.lexer.KtTokens import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType @@ -45,23 +49,34 @@ import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.util.OperatorNameConventions class InflowSlicer( - element: KtExpression, + element: KtElement, processor: SliceUsageProcessor, parentUsage: KotlinSliceUsage ) : Slicer(element, processor, parentUsage) { override fun processChildren() { if (parentUsage.forcedExpressionMode) { - processExpression(element) + (element as? KtExpression)?.let { processExpression(it) } return } when (element) { is KtProperty -> processProperty(element) - // for parameter, we include overriders only when the feature is invoked on parameter itself + + // include overriders only when invoked on the parameter declaration is KtParameter -> processParameter(parameter = element, includeOverriders = parentUsage.parent == null) + is KtDeclarationWithBody -> element.processBody() - else -> processExpression(element) + + is KtTypeReference -> { + val parent = element.parent + require(parent is KtCallableDeclaration) + require(element == parent.receiverTypeReference) + // include overriders only when invoked on receiver type in the declaration + processExtensionReceiver(parent, includeOverriders = parentUsage.parent == null) + } + + is KtExpression -> processExpression(element) } } @@ -135,8 +150,9 @@ class InflowSlicer( } fun processCall(usageInfo: UsageInfo) { - val refElement = usageInfo.element ?: return - extractArgumentExpression(refElement)?.passToProcessorAsValue() + usageInfo.element?.let { + extractArgumentExpression(it)?.passToProcessorAsValue() + } } processCalls(function, analysisScope, includeOverriders, ::processCall) @@ -147,6 +163,31 @@ class InflowSlicer( } } + private fun processExtensionReceiver(declaration: KtCallableDeclaration, includeOverriders: Boolean) { + fun extractReceiverExpression(refElement: PsiElement): PsiElement? { + return when (refElement) { + is KtExpression -> { + val resolvedCall = refElement.resolveToCall() ?: return null + //TODO: implicit receiver + val expressionReceiver = resolvedCall.extensionReceiver as? ExpressionReceiver ?: return null + return expressionReceiver.expression + } + + else -> { + (refElement.parent as? PsiCall)?.argumentList?.expressions?.getOrNull(0) + } + } + } + + fun processCall(usageInfo: UsageInfo) { + usageInfo.element?.let { + extractReceiverExpression(it)?.passToProcessorAsValue() + } + } + + processCalls(declaration, analysisScope, includeOverriders, ::processCall) + } + private fun processExpression(expression: KtExpression) { val lambda = when (expression) { is KtLambdaExpression -> expression.functionLiteral @@ -171,18 +212,30 @@ class InflowSlicer( } return } + val accessedDescriptor = createdAt.target.accessedDescriptor ?: return - val accessedDeclaration = accessedDescriptor.originalSource.getPsi() ?: return - if (accessedDescriptor is SyntheticFieldDescriptor) { - val property = accessedDeclaration as? KtProperty ?: return - if (accessedDescriptor.propertyDescriptor.setter?.isDefault != false) { - property.processPropertyAssignments() - } else { - property.setter?.processBackingFieldAssignments() + val accessedDeclaration = accessedDescriptor.originalSource.getPsi() + when (accessedDescriptor) { + is SyntheticFieldDescriptor -> { + val property = accessedDeclaration as? KtProperty ?: return + if (accessedDescriptor.propertyDescriptor.setter?.isDefault != false) { + property.processPropertyAssignments() + } else { + property.setter?.processBackingFieldAssignments() + } + } + + is ReceiverParameterDescriptor -> { + val callable = accessedDescriptor.containingDeclaration as? CallableDescriptor ?: return + val callableDeclaration = callable.originalSource.getPsi() as? KtCallableDeclaration ?: return + //TODO: what about non-extensions? + callableDeclaration.receiverTypeReference?.passToProcessor() + } + + else -> { + accessedDeclaration?.passDeclarationToProcessorWithOverriders() } - return } - accessedDeclaration.passDeclarationToProcessorWithOverriders() } is MergeInstruction -> createdAt.passInputsToProcessor() @@ -287,8 +340,17 @@ class InflowSlicer( private fun PsiElement.passDeclarationToProcessorWithOverriders() { passToProcessor() + HierarchySearchRequest(this, analysisScope) .searchOverriders() .forEach { it.namedUnwrappedElement?.passToProcessor() } + + if (this is KtCallableDeclaration && isExpectDeclaration()) { + resolveToDescriptorIfAny(BodyResolveMode.FULL) + ?.actualsForExpected() + ?.forEach { + (it as? DeclarationDescriptorWithSource)?.originalSource?.getPsi()?.passToProcessor() + } + } } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt index f3ab75ba8b2..99c67489bbf 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceProvider.kt @@ -20,6 +20,7 @@ import com.intellij.codeInsight.Nullability import com.intellij.ide.util.treeView.AbstractTreeStructure import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.psi.PsiElement +import com.intellij.psi.util.parentOfType import com.intellij.slicer.* import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.descriptors.CallableDescriptor @@ -30,6 +31,7 @@ import org.jetbrains.kotlin.idea.references.mainReference import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.psiUtil.isPlainWithEscapes import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf +import org.jetbrains.kotlin.psi2ir.deparenthesize import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.isError @@ -73,26 +75,34 @@ class KotlinSliceProvider : SliceLanguageSupportProvider, SliceUsageTransformer return listOf(KotlinSliceUsage(usage.element, usage.parent, 0, false)) } - override fun getExpressionAtCaret(atCaret: PsiElement, dataFlowToThis: Boolean): KtExpression? { - val element = - atCaret.parentsWithSelf - .firstOrNull { - it is KtProperty || - it is KtParameter || - it is KtDeclarationWithBody || - (it is KtClass && !it.hasExplicitPrimaryConstructor()) || - (it is KtExpression && it !is KtDeclaration) - } - ?.let { KtPsiUtil.safeDeparenthesize(it as KtExpression) } ?: return null + override fun getExpressionAtCaret(atCaret: PsiElement, dataFlowToThis: Boolean): KtElement? { + val element = atCaret.parentsWithSelf + .filterIsInstance() + .firstOrNull(::isSliceElement) + ?.deparenthesize() ?: return null + if (dataFlowToThis) { if (element is KtConstantExpression) return null if (element is KtStringTemplateExpression && element.isPlainWithEscapes()) return null if (element is KtClassLiteralExpression) return null if (element is KtCallableReferenceExpression) return null } + return element } + private fun isSliceElement(element: KtElement): Boolean { + return when { + element is KtProperty -> true + element is KtParameter -> true + element is KtDeclarationWithBody -> true + element is KtClass && !element.hasExplicitPrimaryConstructor() -> true + element is KtExpression && element !is KtDeclaration && element.parentOfType() == null -> true + element is KtTypeReference && element == (element.parent as? KtCallableDeclaration)?.receiverTypeReference -> true + else -> false + } + } + override fun getElementForDescription(element: PsiElement): PsiElement { return (element as? KtSimpleNameExpression)?.mainReference?.resolve() ?: element } diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceUsage.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceUsage.kt index b599342464c..d511e786b19 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceUsage.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/KotlinSliceUsage.kt @@ -21,6 +21,7 @@ import com.intellij.slicer.SliceAnalysisParams import com.intellij.slicer.SliceUsage import com.intellij.usageView.UsageInfo import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor +import org.jetbrains.kotlin.psi.KtElement import org.jetbrains.kotlin.psi.KtExpression open class KotlinSliceUsage : SliceUsage { @@ -58,10 +59,10 @@ open class KotlinSliceUsage : SliceUsage { override fun canBeLeaf() = element != null && lambdaLevel == 0 public override fun processUsagesFlownDownTo(element: PsiElement, uniqueProcessor: SliceUsageProcessor) { - InflowSlicer(element as? KtExpression ?: return, uniqueProcessor, this).processChildren() + InflowSlicer(element as? KtElement ?: return, uniqueProcessor, this).processChildren() } public override fun processUsagesFlownFromThe(element: PsiElement, uniqueProcessor: SliceUsageProcessor) { - OutflowSlicer(element as? KtExpression ?: return, uniqueProcessor, this).processChildren() + OutflowSlicer(element as? KtElement ?: return, uniqueProcessor, this).processChildren() } } \ No newline at end of file diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt index 0f30508e6e2..e59b60b719f 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/OutflowSlicer.kt @@ -12,33 +12,77 @@ import com.intellij.psi.impl.light.LightMemberReference import com.intellij.usageView.UsageInfo import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction +import org.jetbrains.kotlin.cfg.pseudocode.instructions.KtElementInstruction import org.jetbrains.kotlin.cfg.pseudocode.instructions.eval.* import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ReturnValueInstruction +import org.jetbrains.kotlin.descriptors.CallableDescriptor +import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource +import org.jetbrains.kotlin.idea.caches.resolve.getResolutionFacade +import org.jetbrains.kotlin.idea.caches.resolve.resolveToCall +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingElement import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector +import org.jetbrains.kotlin.idea.util.actualsForExpected +import org.jetbrains.kotlin.idea.util.isExpectDeclaration import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType -import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch -import org.jetbrains.kotlin.psi.psiUtil.isAncestor -import org.jetbrains.kotlin.psi.psiUtil.parameterIndex +import org.jetbrains.kotlin.psi.psiUtil.* +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.source.getPsi class OutflowSlicer( - element: KtExpression, + element: KtElement, processor: SliceUsageProcessor, parentUsage: KotlinSliceUsage ) : Slicer(element, processor, parentUsage) { override fun processChildren() { - if (parentUsage.forcedExpressionMode) return processExpression(element) + if (parentUsage.forcedExpressionMode) { + (element as? KtExpression)?.let { processExpression(it) } + return + } when (element) { is KtProperty -> processVariable(element) + is KtParameter -> processVariable(element) + is KtFunction -> processFunction(element) - is KtPropertyAccessor -> if (element.isGetter) processVariable(element.property) - else -> processExpression(element) + + is KtPropertyAccessor -> { + if (element.isGetter) { + processVariable(element.property) + } + } + + is KtTypeReference -> { + val declaration = element.parent + require(declaration is KtCallableDeclaration) + require(element == declaration.receiverTypeReference) + + if (declaration.isExpectDeclaration()) { + declaration.resolveToDescriptorIfAny(BodyResolveMode.FULL) + ?.actualsForExpected() + ?.forEach { + val actualDeclaration = (it as? DeclarationDescriptorWithSource)?.originalSource?.getPsi() + (actualDeclaration as? KtCallableDeclaration)?.receiverTypeReference?.passToProcessor() + } + } + + when (declaration) { + is KtFunction -> { + processExtensionReceiver(declaration, declaration) + } + + is KtProperty -> { + //TODO: process only one of them or both depending on the usage type + declaration.getter?.let { processExtensionReceiver(declaration, it) } + declaration.setter?.let { processExtensionReceiver(declaration, it) } + } + } + } + + is KtExpression -> processExpression(element) } } @@ -65,28 +109,37 @@ class OutflowSlicer( if (variable is KtParameter) { if (!canProcessParameter(variable)) return //TODO - //TODO: expect/actual - val callable = variable.ownerFunction as? KtCallableDeclaration - val parameterIndex = variable.parameterIndex() - callable?.forEachOverridingElement(scope = analysisScope) { _, overridingMember -> - when (overridingMember) { - is KtCallableDeclaration -> { - val parameters = overridingMember.valueParameters - check(parameters.size == callable.valueParameters.size) - parameters[parameterIndex].passToProcessor() - } - is PsiMethod -> { - val parameters = overridingMember.parameterList.parameters - val shift = if (callable.receiverTypeReference != null) 1 else 0 - check(parameters.size == callable.valueParameters.size + shift) - parameters[parameterIndex + shift].passToProcessor() - } - - else -> {} // not supported + if (callable != null) { + if (callable.isExpectDeclaration()) { + variable.resolveToDescriptorIfAny(BodyResolveMode.FULL) + ?.actualsForExpected() + ?.forEach { + (it as? DeclarationDescriptorWithSource)?.originalSource?.getPsi()?.passToProcessor() + } + } + + val parameterIndex = variable.parameterIndex() + callable.forEachOverridingElement(scope = analysisScope) { _, overridingMember -> + when (overridingMember) { + is KtCallableDeclaration -> { + val parameters = overridingMember.valueParameters + check(parameters.size == callable.valueParameters.size) + parameters[parameterIndex].passToProcessor() + } + + is PsiMethod -> { + val parameters = overridingMember.parameterList.parameters + val shift = if (callable.receiverTypeReference != null) 1 else 0 + check(parameters.size == callable.valueParameters.size + shift) + parameters[parameterIndex + shift].passToProcessor() + } + + else -> {} // not supported + } + true } - true } } @@ -113,31 +166,81 @@ class OutflowSlicer( is KtNamedFunction -> function else -> null } ?: return - funExpression as PsiElement funExpression.passToProcessor(parentUsage.lambdaLevel + 1, true) } + private fun processExtensionReceiver(declaration: KtCallableDeclaration, declarationWithBody: KtDeclarationWithBody) { + //TODO: overriders + //TODO: implicit receivers + val resolutionFacade = declaration.getResolutionFacade() + val callableDescriptor = declaration.resolveToDescriptorIfAny(resolutionFacade) as? CallableDescriptor ?: return + val extensionReceiver = callableDescriptor.extensionReceiverParameter ?: return + declarationWithBody.bodyExpression?.forEachDescendantOfType { thisExpression -> + val receiverDescriptor = thisExpression.resolveToCall(resolutionFacade)?.resultingDescriptor + if (receiverDescriptor == extensionReceiver) { + thisExpression.passToProcessor() + } + } + } + private fun processExpression(expression: KtExpression) { - expression.processPseudocodeUsages { pseudoValue, instr -> - when (instr) { - is WriteValueInstruction -> instr.target.accessedDescriptor?.originalSource?.getPsi()?.passToProcessor() - is CallInstruction -> { - if (parentUsage.lambdaLevel > 0 && instr.receiverValues[pseudoValue] != null) { - instr.element.passToProcessor(parentUsage.lambdaLevel - 1) - } else { - instr.arguments[pseudoValue]?.originalSource?.getPsi()?.passToProcessor() + expression.processPseudocodeUsages { pseudoValue, instruction -> + when (instruction) { + is WriteValueInstruction -> { + if (!processIfReceiverValue(instruction, pseudoValue)) { + instruction.target.accessedDescriptor?.originalSource?.getPsi()?.passToProcessor() } } - is ReturnValueInstruction -> instr.subroutine.passToProcessor() - is MagicInstruction -> when (instr.kind) { - MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> instr.outputValue.element?.passToProcessor() - else -> { + + is ReadValueInstruction -> { + processIfReceiverValue(instruction, pseudoValue) + } + + is CallInstruction -> { + if (!processIfReceiverValue(instruction, pseudoValue)) { + instruction.arguments[pseudoValue]?.originalSource?.getPsi()?.passToProcessor() + } + } + + is ReturnValueInstruction -> { + instruction.subroutine.passToProcessor() + } + + is MagicInstruction -> { + when (instruction.kind) { + MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> instruction.outputValue.element?.passToProcessor() + else -> { + } } } } } } + private fun processIfReceiverValue(instruction: KtElementInstruction, pseudoValue: PseudoValue): Boolean { + val receiverValue = (instruction as? InstructionWithReceivers)?.receiverValues?.get(pseudoValue) ?: return false + val resolvedCall = instruction.element.resolveToCall() ?: return true + when (resolvedCall.call.callType) { + Call.CallType.DEFAULT -> { + if (receiverValue == resolvedCall.extensionReceiver) { + val targetDeclaration = resolvedCall.resultingDescriptor.originalSource.getPsi() + (targetDeclaration as? KtCallableDeclaration)?.receiverTypeReference?.passToProcessor() + } + } + + Call.CallType.INVOKE -> { + if (parentUsage.lambdaLevel > 0 && receiverValue == resolvedCall.dispatchReceiver) { + instruction.element.passToProcessor(parentUsage.lambdaLevel - 1) + } + } + + else -> { + //TODO + } + } + return true + } + private fun PsiElement.getCallElementForExactCallee(): PsiElement? { if (this is KtArrayAccessExpression) return this diff --git a/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt b/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt index 7472b93b778..6543e0a7463 100644 --- a/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt +++ b/idea/src/org/jetbrains/kotlin/idea/slicer/Slicer.kt @@ -10,6 +10,7 @@ import com.intellij.psi.PsiMethod import com.intellij.psi.search.SearchScope import com.intellij.slicer.JavaSliceUsage import com.intellij.usageView.UsageInfo +import com.intellij.util.containers.addIfNotNull import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.pseudocode.getContainingPseudocode @@ -17,21 +18,22 @@ import org.jetbrains.kotlin.descriptors.CallableMemberDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent -import org.jetbrains.kotlin.idea.caches.resolve.unsafeResolveToDescriptor +import org.jetbrains.kotlin.idea.caches.resolve.resolveToDescriptorIfAny import org.jetbrains.kotlin.idea.core.getDeepestSuperDeclarations import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor import org.jetbrains.kotlin.idea.findUsages.processAllExactUsages import org.jetbrains.kotlin.idea.findUsages.processAllUsages +import org.jetbrains.kotlin.idea.util.expectedDescriptor import org.jetbrains.kotlin.psi.* -import org.jetbrains.kotlin.psi.psiUtil.contains import org.jetbrains.kotlin.resolve.DescriptorUtils +import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.source.getPsi import java.util.* abstract class Slicer( - protected val element: KtExpression, + protected val element: KtElement, protected val processor: SliceUsageProcessor, protected val parentUsage: KotlinSliceUsage ) { @@ -62,22 +64,43 @@ abstract class Slicer( } protected fun processCalls( - function: KtFunction, + callable: KtCallableDeclaration, scope: SearchScope, includeOverriders: Boolean, usageProcessor: (UsageInfo) -> Unit ) { - val options = KotlinFunctionFindUsagesOptions(project).apply { - isSearchForTextOccurrences = false - isSkipImportStatements = true - searchScope = scope + val options = when (callable) { + is KtFunction -> { + KotlinFunctionFindUsagesOptions(project).apply { + isSearchForTextOccurrences = false + isSkipImportStatements = true + searchScope = scope + } + } + + is KtProperty -> { + KotlinPropertyFindUsagesOptions(project).apply { + isSearchForTextOccurrences = false + isSkipImportStatements = true + searchScope = scope + } + } + + else -> return } - val descriptor = function.unsafeResolveToDescriptor() as? CallableMemberDescriptor ?: return - val superDescriptors = if (includeOverriders) + val descriptor = callable.resolveToDescriptorIfAny(BodyResolveMode.FULL) as? CallableMemberDescriptor ?: return + val superDescriptors = if (includeOverriders) { descriptor.getDeepestSuperDeclarations() - else - listOf(descriptor) + DescriptorUtils.getAllOverriddenDeclarations(descriptor) + } else { + mutableListOf().apply { + add(descriptor) + addAll(DescriptorUtils.getAllOverriddenDeclarations(descriptor)) + if (descriptor.isActual) { + addIfNotNull(descriptor.expectedDescriptor() as CallableMemberDescriptor?) + } + } + } for (superDescriptor in superDescriptors) { val declaration = superDescriptor.originalSource.getPsi() ?: continue @@ -123,11 +146,17 @@ abstract class Slicer( } val allDeclarations = mutableListOf(declaration) - val descriptor = declaration.unsafeResolveToDescriptor() + val descriptor = declaration.resolveToDescriptorIfAny() if (descriptor is CallableMemberDescriptor) { - DescriptorUtils.getAllOverriddenDeclarations(descriptor).mapNotNullTo(allDeclarations) { + val additionalDescriptors = if (descriptor.isActual) { + listOfNotNull(descriptor.expectedDescriptor() as? CallableMemberDescriptor) + } else { + DescriptorUtils.getAllOverriddenDeclarations(descriptor) + } + additionalDescriptors.mapNotNullTo(allDeclarations) { it.originalSource.getPsi() as? KtCallableDeclaration } + } allDeclarations.forEach { it.processAllExactUsages(options, usageProcessor) } diff --git a/idea/testData/slicer/inflow/onFunctionReceiverType.java b/idea/testData/slicer/inflow/onFunctionReceiverType.java new file mode 100644 index 00000000000..ae38432b32b --- /dev/null +++ b/idea/testData/slicer/inflow/onFunctionReceiverType.java @@ -0,0 +1,5 @@ +class JavaClass { + void f() { + KotlinUtil.extensionFun("x"); + } +} diff --git a/idea/testData/slicer/inflow/onFunctionReceiverType.kt b/idea/testData/slicer/inflow/onFunctionReceiverType.kt new file mode 100644 index 00000000000..51d86fa4b00 --- /dev/null +++ b/idea/testData/slicer/inflow/onFunctionReceiverType.kt @@ -0,0 +1,13 @@ +// FLOW: IN + +@file: JvmName("KotlinUtil") + +import kotlin.jvm.JvmName + +fun Any.extensionFun() { +} + +fun foo() { + "".extensionFun() + 1.extensionFun() +} \ No newline at end of file diff --git a/idea/testData/slicer/inflow/onFunctionReceiverType.leafGroups.txt b/idea/testData/slicer/inflow/onFunctionReceiverType.leafGroups.txt new file mode 100644 index 00000000000..7fbeaa3cfb4 --- /dev/null +++ b/idea/testData/slicer/inflow/onFunctionReceiverType.leafGroups.txt @@ -0,0 +1,12 @@ +11 "".extensionFun() +7 fun Any.extensionFun() { +11 "".extensionFun() + +3 KotlinUtil.extensionFun("x"); +7 fun Any.extensionFun() { +3 KotlinUtil.extensionFun("x"); + +12 1.extensionFun() +7 fun Any.extensionFun() { +12 1.extensionFun() + diff --git a/idea/testData/slicer/inflow/onFunctionReceiverType.nullnessGroups.txt b/idea/testData/slicer/inflow/onFunctionReceiverType.nullnessGroups.txt new file mode 100644 index 00000000000..a6c683edd00 --- /dev/null +++ b/idea/testData/slicer/inflow/onFunctionReceiverType.nullnessGroups.txt @@ -0,0 +1,13 @@ +[NotNull Values] +11 "".extensionFun() +7 fun Any.extensionFun() { +11 "".extensionFun() +12 1.extensionFun() +7 fun Any.extensionFun() { +12 1.extensionFun() + +[Other Values] +3 KotlinUtil.extensionFun("x"); +7 fun Any.extensionFun() { +3 KotlinUtil.extensionFun("x"); + diff --git a/idea/testData/slicer/inflow/onFunctionReceiverType.results.txt b/idea/testData/slicer/inflow/onFunctionReceiverType.results.txt new file mode 100644 index 00000000000..d2614d5f30a --- /dev/null +++ b/idea/testData/slicer/inflow/onFunctionReceiverType.results.txt @@ -0,0 +1,4 @@ +7 fun Any.extensionFun() { +3 KotlinUtil.extensionFun("x"); +11 "".extensionFun() +12 1.extensionFun() diff --git a/idea/testData/slicer/inflow/onPropertyReceiverType.kt b/idea/testData/slicer/inflow/onPropertyReceiverType.kt new file mode 100644 index 00000000000..6e92841310d --- /dev/null +++ b/idea/testData/slicer/inflow/onPropertyReceiverType.kt @@ -0,0 +1,10 @@ +// FLOW: IN + +var Any.property: Int + get() = 1 + set(value) { } + +fun foo() { + println("a".property) + "b".property = 2 +} \ No newline at end of file diff --git a/idea/testData/slicer/inflow/onPropertyReceiverType.leafGroups.txt b/idea/testData/slicer/inflow/onPropertyReceiverType.leafGroups.txt new file mode 100644 index 00000000000..59960990949 --- /dev/null +++ b/idea/testData/slicer/inflow/onPropertyReceiverType.leafGroups.txt @@ -0,0 +1,7 @@ +9 "b".property = 2 +3 var Any.property: Int +9 "b".property = 2 + +8 println("a".property) +3 var Any.property: Int +8 println("a".property) diff --git a/idea/testData/slicer/inflow/onPropertyReceiverType.nullnessGroups.txt b/idea/testData/slicer/inflow/onPropertyReceiverType.nullnessGroups.txt new file mode 100644 index 00000000000..68093133b5c --- /dev/null +++ b/idea/testData/slicer/inflow/onPropertyReceiverType.nullnessGroups.txt @@ -0,0 +1,7 @@ +[NotNull Values] +8 println("a".property) +3 var Any.property: Int +8 println("a".property) +9 "b".property = 2 +3 var Any.property: Int +9 "b".property = 2 diff --git a/idea/testData/slicer/inflow/onPropertyReceiverType.results.txt b/idea/testData/slicer/inflow/onPropertyReceiverType.results.txt new file mode 100644 index 00000000000..466a6164e25 --- /dev/null +++ b/idea/testData/slicer/inflow/onPropertyReceiverType.results.txt @@ -0,0 +1,3 @@ +3 var Any.property: Int +8 println("a".property) +9 "b".property = 2 diff --git a/idea/testData/slicer/inflow/overrideExtension1.kt b/idea/testData/slicer/inflow/overrideExtension1.kt new file mode 100644 index 00000000000..0fb108c769c --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension1.kt @@ -0,0 +1,20 @@ +// FLOW: IN + +open class Base { + open fun Int.extensionFun() { + println(this) + } + + fun baseF() { + 1.extensionFun() + } +} + +class Derived : Base() { + override fun Int.extensionFun() { + } + + fun derivedF() { + 2.extensionFun() + } +} \ No newline at end of file diff --git a/idea/testData/slicer/inflow/overrideExtension1.leafGroups.txt b/idea/testData/slicer/inflow/overrideExtension1.leafGroups.txt new file mode 100644 index 00000000000..6ee424d7e11 --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension1.leafGroups.txt @@ -0,0 +1,4 @@ +9 1.extensionFun() +5 println(this) +4 open fun Int.extensionFun() { +9 1.extensionFun() diff --git a/idea/testData/slicer/inflow/overrideExtension1.nullnessGroups.txt b/idea/testData/slicer/inflow/overrideExtension1.nullnessGroups.txt new file mode 100644 index 00000000000..16596b0c63e --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension1.nullnessGroups.txt @@ -0,0 +1,3 @@ +[NotNull Values] +5 println(this) +5 println(this) diff --git a/idea/testData/slicer/inflow/overrideExtension1.results.txt b/idea/testData/slicer/inflow/overrideExtension1.results.txt new file mode 100644 index 00000000000..2b37b4c287d --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension1.results.txt @@ -0,0 +1,3 @@ +5 println(this) +4 open fun Int.extensionFun() { +9 1.extensionFun() diff --git a/idea/testData/slicer/inflow/overrideExtension2.kt b/idea/testData/slicer/inflow/overrideExtension2.kt new file mode 100644 index 00000000000..0c006f104f8 --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension2.kt @@ -0,0 +1,20 @@ +// FLOW: IN + +open class Base { + open fun Int.extensionFun() { + println(this) + } + + fun baseF() { + 1.extensionFun() + } +} + +class Derived : Base() { + override fun Int.extensionFun() { + } + + fun derivedF() { + 2.extensionFun() + } +} \ No newline at end of file diff --git a/idea/testData/slicer/inflow/overrideExtension2.leafGroups.txt b/idea/testData/slicer/inflow/overrideExtension2.leafGroups.txt new file mode 100644 index 00000000000..47e6d291b2a --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension2.leafGroups.txt @@ -0,0 +1,7 @@ +9 1.extensionFun() +4 open fun Int.extensionFun() { +9 1.extensionFun() + +18 2.extensionFun() +4 open fun Int.extensionFun() { +18 2.extensionFun() diff --git a/idea/testData/slicer/inflow/overrideExtension2.nullnessGroups.txt b/idea/testData/slicer/inflow/overrideExtension2.nullnessGroups.txt new file mode 100644 index 00000000000..24d72add4c0 --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension2.nullnessGroups.txt @@ -0,0 +1,7 @@ +[NotNull Values] +9 1.extensionFun() +4 open fun Int.extensionFun() { +9 1.extensionFun() +18 2.extensionFun() +4 open fun Int.extensionFun() { +18 2.extensionFun() diff --git a/idea/testData/slicer/inflow/overrideExtension2.results.txt b/idea/testData/slicer/inflow/overrideExtension2.results.txt new file mode 100644 index 00000000000..87da662e608 --- /dev/null +++ b/idea/testData/slicer/inflow/overrideExtension2.results.txt @@ -0,0 +1,3 @@ +4 open fun Int.extensionFun() { +9 1.extensionFun() +18 2.extensionFun() diff --git a/idea/testData/slicer/inflow/thisInExtensionFunction.kt b/idea/testData/slicer/inflow/thisInExtensionFunction.kt new file mode 100644 index 00000000000..218b7d11f2a --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionFunction.kt @@ -0,0 +1,9 @@ +// FLOW: IN + +fun Any.extensionFun(): Any { + return this +} + +fun foo() { + val x = "".extensionFun() +} \ No newline at end of file diff --git a/idea/testData/slicer/inflow/thisInExtensionFunction.leafGroups.txt b/idea/testData/slicer/inflow/thisInExtensionFunction.leafGroups.txt new file mode 100644 index 00000000000..eafa8a7b714 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionFunction.leafGroups.txt @@ -0,0 +1,8 @@ +8 val x = "".extensionFun() +8 val x = "".extensionFun() +8 val x = "".extensionFun() +3 fun Any.extensionFun(): Any { +4 return this +3 fun Any.extensionFun(): Any { +8 val x = "".extensionFun() + diff --git a/idea/testData/slicer/inflow/thisInExtensionFunction.nullnessGroups.txt b/idea/testData/slicer/inflow/thisInExtensionFunction.nullnessGroups.txt new file mode 100644 index 00000000000..60b44919674 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionFunction.nullnessGroups.txt @@ -0,0 +1,3 @@ +[NotNull Values] +8 val x = "".extensionFun() +8 val x = "".extensionFun() diff --git a/idea/testData/slicer/inflow/thisInExtensionFunction.results.txt b/idea/testData/slicer/inflow/thisInExtensionFunction.results.txt new file mode 100644 index 00000000000..91848ff6504 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionFunction.results.txt @@ -0,0 +1,6 @@ +8 val x = "".extensionFun() +8 val x = "".extensionFun() +3 fun Any.extensionFun(): Any { +4 return this +3 fun Any.extensionFun(): Any { +8 val x = "".extensionFun() diff --git a/idea/testData/slicer/inflow/thisInExtensionProperty.kt b/idea/testData/slicer/inflow/thisInExtensionProperty.kt new file mode 100644 index 00000000000..4f726a4d4e0 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionProperty.kt @@ -0,0 +1,8 @@ +// FLOW: IN + +val Any.extensionProp: Any + get() = this + +fun foo() { + val x = "".extensionProp +} \ No newline at end of file diff --git a/idea/testData/slicer/inflow/thisInExtensionProperty.leafGroups.txt b/idea/testData/slicer/inflow/thisInExtensionProperty.leafGroups.txt new file mode 100644 index 00000000000..682e1cb81e3 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionProperty.leafGroups.txt @@ -0,0 +1,8 @@ +7 val x = "".extensionProp +7 val x = "".extensionProp +7 val x = "".extensionProp +3 val Any.extensionProp: Any +4 get() = this +3 val Any.extensionProp: Any +7 val x = "".extensionProp + diff --git a/idea/testData/slicer/inflow/thisInExtensionProperty.nullnessGroups.txt b/idea/testData/slicer/inflow/thisInExtensionProperty.nullnessGroups.txt new file mode 100644 index 00000000000..3edbfc1b822 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionProperty.nullnessGroups.txt @@ -0,0 +1,3 @@ +[NotNull Values] +7 val x = "".extensionProp +7 val x = "".extensionProp diff --git a/idea/testData/slicer/inflow/thisInExtensionProperty.results.txt b/idea/testData/slicer/inflow/thisInExtensionProperty.results.txt new file mode 100644 index 00000000000..630f22252a4 --- /dev/null +++ b/idea/testData/slicer/inflow/thisInExtensionProperty.results.txt @@ -0,0 +1,6 @@ +7 val x = "".extensionProp +7 val x = "".extensionProp +3 val Any.extensionProp: Any +4 get() = this +3 val Any.extensionProp: Any +7 val x = "".extensionProp diff --git a/idea/testData/slicer/mpp/actualClassFunctionParameter/common/common.kt b/idea/testData/slicer/mpp/actualClassFunctionParameter/common/common.kt new file mode 100644 index 00000000000..20797a31218 --- /dev/null +++ b/idea/testData/slicer/mpp/actualClassFunctionParameter/common/common.kt @@ -0,0 +1,9 @@ +package sample + +expect class ExpectClass() { + fun foo(p: Any) +} + +fun f(c: ExpectClass) { + c.foo(1) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/actualClassFunctionParameter/jvm/jvm.kt b/idea/testData/slicer/mpp/actualClassFunctionParameter/jvm/jvm.kt new file mode 100644 index 00000000000..0e5c863a1b3 --- /dev/null +++ b/idea/testData/slicer/mpp/actualClassFunctionParameter/jvm/jvm.kt @@ -0,0 +1,9 @@ +// FLOW: IN + +package sample + +actual class ExpectClass { + actual fun foo(p: Any) { + println(p) + } +} diff --git a/idea/testData/slicer/mpp/actualClassFunctionParameter/results.txt b/idea/testData/slicer/mpp/actualClassFunctionParameter/results.txt new file mode 100644 index 00000000000..6e5a96831cb --- /dev/null +++ b/idea/testData/slicer/mpp/actualClassFunctionParameter/results.txt @@ -0,0 +1,3 @@ +7 println(p) +6 actual fun foo(p: Any) { +8 c.foo(1) diff --git a/idea/testData/slicer/mpp/actualFunctionParameter/common/common.kt b/idea/testData/slicer/mpp/actualFunctionParameter/common/common.kt new file mode 100644 index 00000000000..b54d78fb9d6 --- /dev/null +++ b/idea/testData/slicer/mpp/actualFunctionParameter/common/common.kt @@ -0,0 +1,5 @@ +expect fun foo(p: Any) + +fun bar() { + foo(1) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/actualFunctionParameter/jvm/jvm.kt b/idea/testData/slicer/mpp/actualFunctionParameter/jvm/jvm.kt new file mode 100644 index 00000000000..d0bf202fe48 --- /dev/null +++ b/idea/testData/slicer/mpp/actualFunctionParameter/jvm/jvm.kt @@ -0,0 +1,5 @@ +// FLOW: IN + +actual fun foo(p: Any) { + println(p) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/actualFunctionParameter/results.txt b/idea/testData/slicer/mpp/actualFunctionParameter/results.txt new file mode 100644 index 00000000000..6ec0bc31231 --- /dev/null +++ b/idea/testData/slicer/mpp/actualFunctionParameter/results.txt @@ -0,0 +1,3 @@ +4 println(p) +3 actual fun foo(p: Any) { +4 foo(1) diff --git a/idea/testData/slicer/mpp/expectClassFunctionParameter/common/common.kt b/idea/testData/slicer/mpp/expectClassFunctionParameter/common/common.kt new file mode 100644 index 00000000000..7529cb62def --- /dev/null +++ b/idea/testData/slicer/mpp/expectClassFunctionParameter/common/common.kt @@ -0,0 +1,11 @@ +// FLOW: OUT + +package sample + +expect class ExpectClass() { + fun foo(p: Any) +} + +fun f(c: ExpectClass) { + c.foo(1) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectClassFunctionParameter/jvm/jvm.kt b/idea/testData/slicer/mpp/expectClassFunctionParameter/jvm/jvm.kt new file mode 100644 index 00000000000..96aa66eaef2 --- /dev/null +++ b/idea/testData/slicer/mpp/expectClassFunctionParameter/jvm/jvm.kt @@ -0,0 +1,7 @@ +package sample + +actual class ExpectClass { + actual fun foo(p: Any) { + println(p) + } +} diff --git a/idea/testData/slicer/mpp/expectClassFunctionParameter/results.txt b/idea/testData/slicer/mpp/expectClassFunctionParameter/results.txt new file mode 100644 index 00000000000..5d4e4a1f9f2 --- /dev/null +++ b/idea/testData/slicer/mpp/expectClassFunctionParameter/results.txt @@ -0,0 +1,4 @@ +10 c.foo(1) +6 fun foo(p: Any) +4 actual fun foo(p: Any) { +5 println(p) diff --git a/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/common/common.kt b/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/common/common.kt new file mode 100644 index 00000000000..24fd57ea7b7 --- /dev/null +++ b/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/common/common.kt @@ -0,0 +1,8 @@ +// FLOW: OUT + +expect fun Any.foo(): Any + +fun bar() { + val result = 1.foo() + println(result) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/jvm/jvm.kt b/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/jvm/jvm.kt new file mode 100644 index 00000000000..c18c6ab19ac --- /dev/null +++ b/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/jvm/jvm.kt @@ -0,0 +1,3 @@ +actual fun Any.foo(): Any { + return this +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/results.txt b/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/results.txt new file mode 100644 index 00000000000..788ac06c719 --- /dev/null +++ b/idea/testData/slicer/mpp/expectExtensionFunctionResultOut/results.txt @@ -0,0 +1,8 @@ +6 val result = 1.foo() +3 expect fun Any.foo(): Any +1 actual fun Any.foo(): Any { +2 return this +1 actual fun Any.foo(): Any { +6 val result = 1.foo() +6 val result = 1.foo() +7 println(result) diff --git a/idea/testData/slicer/mpp/expectFunctionParameter/common/common.kt b/idea/testData/slicer/mpp/expectFunctionParameter/common/common.kt new file mode 100644 index 00000000000..f567f23cece --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionParameter/common/common.kt @@ -0,0 +1,7 @@ +// FLOW: OUT + +expect fun foo(p: Any) + +fun bar() { + foo(1) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectFunctionParameter/jvm/jvm.kt b/idea/testData/slicer/mpp/expectFunctionParameter/jvm/jvm.kt new file mode 100644 index 00000000000..418fe306785 --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionParameter/jvm/jvm.kt @@ -0,0 +1,3 @@ +actual fun foo(p: Any) { + println(p) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectFunctionParameter/results.txt b/idea/testData/slicer/mpp/expectFunctionParameter/results.txt new file mode 100644 index 00000000000..2226b1a4465 --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionParameter/results.txt @@ -0,0 +1,4 @@ +6 foo(1) +3 expect fun foo(p: Any) +1 actual fun foo(p: Any) { +2 println(p) diff --git a/idea/testData/slicer/mpp/expectFunctionResultIn/common/common.kt b/idea/testData/slicer/mpp/expectFunctionResultIn/common/common.kt new file mode 100644 index 00000000000..9e88761e523 --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionResultIn/common/common.kt @@ -0,0 +1,8 @@ +// FLOW: IN + +expect fun foo(p: Any): Any + +fun bar() { + val result = foo(1) + println(result) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectFunctionResultIn/jvm/jvm.kt b/idea/testData/slicer/mpp/expectFunctionResultIn/jvm/jvm.kt new file mode 100644 index 00000000000..2ae4938aa2d --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionResultIn/jvm/jvm.kt @@ -0,0 +1,3 @@ +actual fun foo(p: Any): Any { + return p +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectFunctionResultIn/results.txt b/idea/testData/slicer/mpp/expectFunctionResultIn/results.txt new file mode 100644 index 00000000000..24cfb2735a4 --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionResultIn/results.txt @@ -0,0 +1,8 @@ +7 println(result) +6 val result = foo(1) +6 val result = foo(1) +1 actual fun foo(p: Any): Any { +2 return p +1 actual fun foo(p: Any): Any { +6 val result = foo(1) +3 expect fun foo(p: Any): Any diff --git a/idea/testData/slicer/mpp/expectFunctionResultOut/common/common.kt b/idea/testData/slicer/mpp/expectFunctionResultOut/common/common.kt new file mode 100644 index 00000000000..08745968a32 --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionResultOut/common/common.kt @@ -0,0 +1,8 @@ +// FLOW: OUT + +expect fun foo(p: Any): Any + +fun bar() { + val result = foo(1) + println(result) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectFunctionResultOut/jvm/jvm.kt b/idea/testData/slicer/mpp/expectFunctionResultOut/jvm/jvm.kt new file mode 100644 index 00000000000..2ae4938aa2d --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionResultOut/jvm/jvm.kt @@ -0,0 +1,3 @@ +actual fun foo(p: Any): Any { + return p +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectFunctionResultOut/results.txt b/idea/testData/slicer/mpp/expectFunctionResultOut/results.txt new file mode 100644 index 00000000000..a911734ad85 --- /dev/null +++ b/idea/testData/slicer/mpp/expectFunctionResultOut/results.txt @@ -0,0 +1,8 @@ +6 val result = foo(1) +3 expect fun foo(p: Any): Any +1 actual fun foo(p: Any): Any { +2 return p +1 actual fun foo(p: Any): Any { +6 val result = foo(1) +6 val result = foo(1) +7 println(result) diff --git a/idea/testData/slicer/mpp/expectPropertyResultIn/common/common.kt b/idea/testData/slicer/mpp/expectPropertyResultIn/common/common.kt new file mode 100644 index 00000000000..f08e4488d3b --- /dev/null +++ b/idea/testData/slicer/mpp/expectPropertyResultIn/common/common.kt @@ -0,0 +1,8 @@ +// FLOW: IN + +expect val Int.property: Any + +fun bar() { + val result = 1.property + println(result) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectPropertyResultIn/jvm/jvm.kt b/idea/testData/slicer/mpp/expectPropertyResultIn/jvm/jvm.kt new file mode 100644 index 00000000000..858c75e61a1 --- /dev/null +++ b/idea/testData/slicer/mpp/expectPropertyResultIn/jvm/jvm.kt @@ -0,0 +1,2 @@ +actual val Int.property: Any + get() = this diff --git a/idea/testData/slicer/mpp/expectPropertyResultIn/results.txt b/idea/testData/slicer/mpp/expectPropertyResultIn/results.txt new file mode 100644 index 00000000000..27e1489f526 --- /dev/null +++ b/idea/testData/slicer/mpp/expectPropertyResultIn/results.txt @@ -0,0 +1,8 @@ +7 println(result) +6 val result = 1.property +6 val result = 1.property +1 actual val Int.property: Any +2 get() = this +1 actual val Int.property: Any +6 val result = 1.property +3 expect val Int.property: Any diff --git a/idea/testData/slicer/mpp/expectPropertyResultOut/common/common.kt b/idea/testData/slicer/mpp/expectPropertyResultOut/common/common.kt new file mode 100644 index 00000000000..941932fadf7 --- /dev/null +++ b/idea/testData/slicer/mpp/expectPropertyResultOut/common/common.kt @@ -0,0 +1,8 @@ +// FLOW: OUT + +expect val Int.property: Any + +fun bar() { + val result = 1.property + println(result) +} \ No newline at end of file diff --git a/idea/testData/slicer/mpp/expectPropertyResultOut/jvm/jvm.kt b/idea/testData/slicer/mpp/expectPropertyResultOut/jvm/jvm.kt new file mode 100644 index 00000000000..858c75e61a1 --- /dev/null +++ b/idea/testData/slicer/mpp/expectPropertyResultOut/jvm/jvm.kt @@ -0,0 +1,2 @@ +actual val Int.property: Any + get() = this diff --git a/idea/testData/slicer/mpp/expectPropertyResultOut/results.txt b/idea/testData/slicer/mpp/expectPropertyResultOut/results.txt new file mode 100644 index 00000000000..c21ce46f88c --- /dev/null +++ b/idea/testData/slicer/mpp/expectPropertyResultOut/results.txt @@ -0,0 +1,8 @@ +6 val result = 1.property +3 expect val Int.property: Any +1 actual val Int.property: Any +2 get() = this +2 get() = this +6 val result = 1.property +6 val result = 1.property +7 println(result) diff --git a/idea/testData/slicer/outflow/operatorCallDereferences.results.txt b/idea/testData/slicer/outflow/operatorCallDereferences.results.txt index 70f56e4cca9..b5ba5cf6261 100644 --- a/idea/testData/slicer/outflow/operatorCallDereferences.results.txt +++ b/idea/testData/slicer/outflow/operatorCallDereferences.results.txt @@ -5,5 +5,18 @@ 22 DEREFERENCE: x += 1 23 DEREFERENCE: x *= 1 25 -x +12 operator fun A.unaryMinus() = this +12 operator fun A.unaryMinus() = this +12 operator fun A.unaryMinus() = this +25 -x 26 x - 1 +11 operator fun A.minus(n: Int) = this +11 operator fun A.minus(n: Int) = this +11 operator fun A.minus(n: Int) = this +26 x - 1 +28 x -= 1 +17 DUPLICATE: var x = A() 29 x /= 1 +14 operator fun A.divAssign(n: Int) = this +14 operator fun A.divAssign(n: Int) = this +14 operator fun A.divAssign(n: Int) = this diff --git a/idea/testData/slicer/outflow/simpleCallDereferences.results.txt b/idea/testData/slicer/outflow/simpleCallDereferences.results.txt index deeefea173d..4c5943be12a 100644 --- a/idea/testData/slicer/outflow/simpleCallDereferences.results.txt +++ b/idea/testData/slicer/outflow/simpleCallDereferences.results.txt @@ -2,10 +2,14 @@ 15 DEREFERENCE: x.foo() 16 DEREFERENCE: x.bar 17 x.fooExt() +9 fun A.fooExt() = 1 18 x.barExt +10 val A.barExt: Int get() = 2 20 val y: A? = x 20 val y: A? = x 22 DEREFERENCE: y?.foo() 23 DEREFERENCE: y?.bar 24 y?.fooExt() +9 DUPLICATE: fun A.fooExt() = 1 25 y?.barExt +10 DUPLICATE: val A.barExt: Int get() = 2 diff --git a/idea/testData/slicer/outflow/thisInExtensionFunction.kt b/idea/testData/slicer/outflow/thisInExtensionFunction.kt new file mode 100644 index 00000000000..e472800612a --- /dev/null +++ b/idea/testData/slicer/outflow/thisInExtensionFunction.kt @@ -0,0 +1,7 @@ +// FLOW: OUT + +fun String.extensionFun(): Any = this + +fun foo() { + val x = "".extensionFun() +} \ No newline at end of file diff --git a/idea/testData/slicer/outflow/thisInExtensionFunction.results.txt b/idea/testData/slicer/outflow/thisInExtensionFunction.results.txt new file mode 100644 index 00000000000..7c3cbfdabfc --- /dev/null +++ b/idea/testData/slicer/outflow/thisInExtensionFunction.results.txt @@ -0,0 +1,6 @@ +6 val x = "".extensionFun() +3 fun String.extensionFun(): Any = this +3 fun String.extensionFun(): Any = this +3 fun String.extensionFun(): Any = this +6 val x = "".extensionFun() +6 val x = "".extensionFun() diff --git a/idea/testData/slicer/outflow/thisInExtensionProperty.kt b/idea/testData/slicer/outflow/thisInExtensionProperty.kt new file mode 100644 index 00000000000..9a208eb9357 --- /dev/null +++ b/idea/testData/slicer/outflow/thisInExtensionProperty.kt @@ -0,0 +1,8 @@ +// FLOW: OUT + +val String.extensionProp: Any + get() = this + +fun foo() { + val x = "".extensionProp +} \ No newline at end of file diff --git a/idea/testData/slicer/outflow/thisInExtensionProperty.results.txt b/idea/testData/slicer/outflow/thisInExtensionProperty.results.txt new file mode 100644 index 00000000000..e815e7489ad --- /dev/null +++ b/idea/testData/slicer/outflow/thisInExtensionProperty.results.txt @@ -0,0 +1,6 @@ +7 val x = "".extensionProp +3 val String.extensionProp: Any +4 get() = this +4 get() = this +7 val x = "".extensionProp +7 val x = "".extensionProp diff --git a/idea/testData/slicer/outflow/wrongThis.kt b/idea/testData/slicer/outflow/wrongThis.kt new file mode 100644 index 00000000000..606e1cb6a64 --- /dev/null +++ b/idea/testData/slicer/outflow/wrongThis.kt @@ -0,0 +1,19 @@ +// FLOW: OUT + +class C { + fun String.extensionFun(): Any { + with("A") { + println(this.length) + println(this@extensionFun.length) + } + return this@C + } + + fun foo() { + val x = "".extensionFun() + } +} + +inline fun with(receiver: T, block: T.() -> R): R { + return receiver.block() +} diff --git a/idea/testData/slicer/outflow/wrongThis.results.txt b/idea/testData/slicer/outflow/wrongThis.results.txt new file mode 100644 index 00000000000..f2529851bf8 --- /dev/null +++ b/idea/testData/slicer/outflow/wrongThis.results.txt @@ -0,0 +1,3 @@ +13 val x = "".extensionFun() +4 fun String.extensionFun(): Any { +7 println(this@extensionFun.length) diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerLeafGroupingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerLeafGroupingTest.kt index 6889c2d79e9..2d83bbbb7af 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerLeafGroupingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerLeafGroupingTest.kt @@ -11,7 +11,7 @@ import java.io.File abstract class AbstractSlicerLeafGroupingTest : AbstractSlicerTest() { override fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) { - val treeStructure = SliceTreeStructure(rootNode) + val treeStructure = TestSliceTreeStructure(rootNode) val analyzer = sliceProvider.leafAnalyzer val possibleElementsByNode = analyzer.createMap() val leafExpressions = analyzer.calcLeafExpressions(rootNode, treeStructure, possibleElementsByNode) diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerMultiplatformTest.kt b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerMultiplatformTest.kt new file mode 100644 index 00000000000..04f0b8fa0d0 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerMultiplatformTest.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.slicer + +import com.intellij.psi.PsiDocumentManager +import org.jetbrains.annotations.NotNull +import org.jetbrains.kotlin.idea.multiplatform.setupMppProjectFromDirStructure +import org.jetbrains.kotlin.idea.stubs.AbstractMultiModuleTest +import org.jetbrains.kotlin.idea.test.PluginTestCaseBase +import org.jetbrains.kotlin.idea.test.extractMarkerOffset +import org.jetbrains.kotlin.idea.test.findFileWithCaret +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.test.KotlinTestUtils +import java.io.File + +abstract class AbstractSlicerMultiplatformTest : AbstractMultiModuleTest() { + override fun getTestDataPath() = + File(PluginTestCaseBase.getTestDataPathBase(), "/slicer/mpp").path + File.separator + + protected fun doTest(filePath: String) { + val testRoot = File(filePath) + setupMppProjectFromDirStructure(testRoot) + + val file = project.findFileWithCaret() as KtFile + val document = PsiDocumentManager.getInstance(myProject).getDocument(file)!! + val offset = document.extractMarkerOffset(project, "") + + testSliceFromOffset(file, offset) { _, rootNode -> + KotlinTestUtils.assertEqualsToFile(testRoot.resolve("results.txt"), buildTreeRepresentation(rootNode)) + } + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerNullnessGroupingTest.kt b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerNullnessGroupingTest.kt index e58e540975b..b80af7bb606 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerNullnessGroupingTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerNullnessGroupingTest.kt @@ -12,7 +12,7 @@ import java.io.File abstract class AbstractSlicerNullnessGroupingTest : AbstractSlicerTest() { override fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) { - val treeStructure = SliceTreeStructure(rootNode) + val treeStructure = TestSliceTreeStructure(rootNode) val analyzer = sliceProvider.nullnessAnalyzer val nullnessByNode = SliceNullnessAnalyzerBase.createMap() val nullness = analyzer.calcNullableLeaves(rootNode, treeStructure, nullnessByNode) diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerTest.kt b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerTest.kt index 49505bdfd6d..674657a744c 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerTest.kt +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/AbstractSlicerTest.kt @@ -5,96 +5,15 @@ package org.jetbrains.kotlin.idea.slicer -import com.intellij.analysis.AnalysisScope -import com.intellij.ide.projectView.TreeStructureProvider -import com.intellij.ide.util.treeView.AbstractTreeStructureBase import com.intellij.openapi.util.io.FileUtil -import com.intellij.slicer.DuplicateMap -import com.intellij.slicer.SliceAnalysisParams -import com.intellij.slicer.SliceNode import com.intellij.slicer.SliceRootNode -import com.intellij.usages.TextChunk import com.intellij.util.PathUtil import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.psi.KtFile -import org.jetbrains.kotlin.psi.psiUtil.startOffset -import org.jetbrains.kotlin.test.InTextDirectivesUtils import org.jetbrains.kotlin.test.KotlinTestUtils -import java.awt.Font import java.io.File abstract class AbstractSlicerTest : KotlinLightCodeInsightFixtureTestCase() { - protected class SliceTreeStructure(private val rootNode: SliceNode) : AbstractTreeStructureBase(rootNode.project) { - override fun getProviders(): List? = emptyList() - - override fun getRootElement() = rootNode - - override fun commit() { - - } - - override fun hasSomethingToCommit() = false - } - - companion object { - private val SliceNode.sortedChildren: List - get() = children.sortedBy { it.value.element?.startOffset ?: -1 } - - @JvmStatic - protected fun buildTreeRepresentation(rootNode: SliceNode): String { - fun TextChunk.render(): String { - var text = text - if (attributes.fontType == Font.BOLD) { - text = "$text" - } - return text - } - - fun SliceNode.isSliceLeafValueClassNode() = javaClass.name == "com.intellij.slicer.SliceLeafValueClassNode" - - fun process(node: SliceNode, indent: Int): String { - val usage = node.element!!.value - - node.calculateDupNode() - val isDuplicated = !node.isSliceLeafValueClassNode() && node.duplicate != null - - return buildString { - when { - node is SliceRootNode && usage.element is KtFile -> { - node.sortedChildren.forEach { append(process(it, indent)) } - return@buildString - } - // SliceLeafValueClassNode is package-private - node.isSliceLeafValueClassNode() -> append("[${node.nodeText}]\n") - else -> { - val chunks = usage.text - append(chunks.first().render() + " ") - append("\t".repeat(indent)) - if (usage is KotlinSliceDereferenceUsage) { - append("DEREFERENCE: ") - } - if (usage is KotlinSliceUsage) { - append("[LAMBDA] ".repeat(usage.lambdaLevel)) - } - chunks.slice(1 until chunks.size).joinTo( - this, - separator = "", - prefix = if (isDuplicated) "DUPLICATE: " else "", - postfix = "\n" - ) { it.render() } - } - } - - if (!isDuplicated) { - node.sortedChildren.forEach { append(process(it, indent + 1)) } - } - }.replace(Regex(""), "") - } - - return process(rootNode, 0) - } - } - protected abstract fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) protected fun doTest(path: String) { @@ -104,30 +23,15 @@ abstract class AbstractSlicerTest : KotlinLightCodeInsightFixtureTestCase() { val namePrefix = FileUtil.getNameWithoutExtension(mainFile) val extraFiles = rootDir.listFiles { _, name -> name.startsWith("$namePrefix.") && PathUtil.getFileExtension(name).let { it == "kt" || it == "java" } - } + }!! myFixture.testDataPath = "${KotlinTestUtils.getHomeDirectory()}/${rootDir.path}" - - val fileText = FileUtil.loadFile(mainFile, true) - val flowKind = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// FLOW: ") - val withDereferences = InTextDirectivesUtils.isDirectiveDefined(fileText, "// WITH_DEREFERENCES") - val analysisParams = SliceAnalysisParams().apply { - dataFlowToThis = when (flowKind) { - "IN" -> true - "OUT" -> false - else -> throw AssertionError("Invalid flow kind: $flowKind") - } - showInstanceDereferences = withDereferences - scope = AnalysisScope(project) - } - + extraFiles.forEach { myFixture.configureByFile(it.name) } val file = myFixture.configureByFile(mainFile.name) as KtFile - val elementAtCaret = file.findElementAt(editor.caretModel.offset)!! - val sliceProvider = KotlinSliceProvider() - val expression = sliceProvider.getExpressionAtCaret(elementAtCaret, analysisParams.dataFlowToThis)!! - val rootUsage = sliceProvider.createRootUsage(expression, analysisParams) - val rootNode = SliceRootNode(project, DuplicateMap(), rootUsage) - doTest(path, sliceProvider, rootNode) + + testSliceFromOffset(file, editor.caretModel.offset) { sliceProvider, rootNode -> + doTest(path, sliceProvider, rootNode) + } } } \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerLeafGroupingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerLeafGroupingTestGenerated.java index 9a961ec5735..637f33d9d3a 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerLeafGroupingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerLeafGroupingTestGenerated.java @@ -228,6 +228,16 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); } + @TestMetadata("onFunctionReceiverType.kt") + public void testOnFunctionReceiverType() throws Exception { + runTest("idea/testData/slicer/inflow/onFunctionReceiverType.kt"); + } + + @TestMetadata("onPropertyReceiverType.kt") + public void testOnPropertyReceiverType() throws Exception { + runTest("idea/testData/slicer/inflow/onPropertyReceiverType.kt"); + } + @TestMetadata("openFun.kt") public void testOpenFun() throws Exception { runTest("idea/testData/slicer/inflow/openFun.kt"); @@ -238,6 +248,16 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); } + @TestMetadata("overrideExtension1.kt") + public void testOverrideExtension1() throws Exception { + runTest("idea/testData/slicer/inflow/overrideExtension1.kt"); + } + + @TestMetadata("overrideExtension2.kt") + public void testOverrideExtension2() throws Exception { + runTest("idea/testData/slicer/inflow/overrideExtension2.kt"); + } + @TestMetadata("overrideFun.kt") public void testOverrideFun() throws Exception { runTest("idea/testData/slicer/inflow/overrideFun.kt"); @@ -323,6 +343,16 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); } + @TestMetadata("thisInExtensionFunction.kt") + public void testThisInExtensionFunction() throws Exception { + runTest("idea/testData/slicer/inflow/thisInExtensionFunction.kt"); + } + + @TestMetadata("thisInExtensionProperty.kt") + public void testThisInExtensionProperty() throws Exception { + runTest("idea/testData/slicer/inflow/thisInExtensionProperty.kt"); + } + @TestMetadata("topLevelVal.kt") public void testTopLevelVal() throws Exception { runTest("idea/testData/slicer/inflow/topLevelVal.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerMultiplatformTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerMultiplatformTestGenerated.java new file mode 100644 index 00000000000..b483948a483 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerMultiplatformTestGenerated.java @@ -0,0 +1,75 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.slicer; + +import com.intellij.testFramework.TestDataPath; +import org.jetbrains.kotlin.test.JUnit3RunnerWithInners; +import org.jetbrains.kotlin.test.KotlinTestUtils; +import org.jetbrains.kotlin.test.TestMetadata; +import org.junit.runner.RunWith; + +import java.io.File; +import java.util.regex.Pattern; + +/** This class is generated by {@link org.jetbrains.kotlin.generators.tests.TestsPackage}. DO NOT MODIFY MANUALLY */ +@SuppressWarnings("all") +@TestMetadata("idea/testData/slicer/mpp") +@TestDataPath("$PROJECT_ROOT") +@RunWith(JUnit3RunnerWithInners.class) +public class SlicerMultiplatformTestGenerated extends AbstractSlicerMultiplatformTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("actualClassFunctionParameter") + public void testActualClassFunctionParameter() throws Exception { + runTest("idea/testData/slicer/mpp/actualClassFunctionParameter/"); + } + + @TestMetadata("actualFunctionParameter") + public void testActualFunctionParameter() throws Exception { + runTest("idea/testData/slicer/mpp/actualFunctionParameter/"); + } + + public void testAllFilesPresentInMpp() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/slicer/mpp"), Pattern.compile("^([^\\.]+)$"), null, false); + } + + @TestMetadata("expectClassFunctionParameter") + public void testExpectClassFunctionParameter() throws Exception { + runTest("idea/testData/slicer/mpp/expectClassFunctionParameter/"); + } + + @TestMetadata("expectExtensionFunctionResultOut") + public void testExpectExtensionFunctionResultOut() throws Exception { + runTest("idea/testData/slicer/mpp/expectExtensionFunctionResultOut/"); + } + + @TestMetadata("expectFunctionParameter") + public void testExpectFunctionParameter() throws Exception { + runTest("idea/testData/slicer/mpp/expectFunctionParameter/"); + } + + @TestMetadata("expectFunctionResultIn") + public void testExpectFunctionResultIn() throws Exception { + runTest("idea/testData/slicer/mpp/expectFunctionResultIn/"); + } + + @TestMetadata("expectFunctionResultOut") + public void testExpectFunctionResultOut() throws Exception { + runTest("idea/testData/slicer/mpp/expectFunctionResultOut/"); + } + + @TestMetadata("expectPropertyResultIn") + public void testExpectPropertyResultIn() throws Exception { + runTest("idea/testData/slicer/mpp/expectPropertyResultIn/"); + } + + @TestMetadata("expectPropertyResultOut") + public void testExpectPropertyResultOut() throws Exception { + runTest("idea/testData/slicer/mpp/expectPropertyResultOut/"); + } +} diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerNullnessGroupingTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerNullnessGroupingTestGenerated.java index fa62eec9b31..a717e5ecfdb 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerNullnessGroupingTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerNullnessGroupingTestGenerated.java @@ -228,6 +228,16 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); } + @TestMetadata("onFunctionReceiverType.kt") + public void testOnFunctionReceiverType() throws Exception { + runTest("idea/testData/slicer/inflow/onFunctionReceiverType.kt"); + } + + @TestMetadata("onPropertyReceiverType.kt") + public void testOnPropertyReceiverType() throws Exception { + runTest("idea/testData/slicer/inflow/onPropertyReceiverType.kt"); + } + @TestMetadata("openFun.kt") public void testOpenFun() throws Exception { runTest("idea/testData/slicer/inflow/openFun.kt"); @@ -238,6 +248,16 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); } + @TestMetadata("overrideExtension1.kt") + public void testOverrideExtension1() throws Exception { + runTest("idea/testData/slicer/inflow/overrideExtension1.kt"); + } + + @TestMetadata("overrideExtension2.kt") + public void testOverrideExtension2() throws Exception { + runTest("idea/testData/slicer/inflow/overrideExtension2.kt"); + } + @TestMetadata("overrideFun.kt") public void testOverrideFun() throws Exception { runTest("idea/testData/slicer/inflow/overrideFun.kt"); @@ -323,6 +343,16 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); } + @TestMetadata("thisInExtensionFunction.kt") + public void testThisInExtensionFunction() throws Exception { + runTest("idea/testData/slicer/inflow/thisInExtensionFunction.kt"); + } + + @TestMetadata("thisInExtensionProperty.kt") + public void testThisInExtensionProperty() throws Exception { + runTest("idea/testData/slicer/inflow/thisInExtensionProperty.kt"); + } + @TestMetadata("topLevelVal.kt") public void testTopLevelVal() throws Exception { runTest("idea/testData/slicer/inflow/topLevelVal.kt"); diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTestUtil.kt b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTestUtil.kt new file mode 100644 index 00000000000..90a2b16f4c4 --- /dev/null +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTestUtil.kt @@ -0,0 +1,112 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.idea.slicer + +import com.intellij.analysis.AnalysisScope +import com.intellij.ide.projectView.TreeStructureProvider +import com.intellij.ide.util.treeView.AbstractTreeStructureBase +import com.intellij.slicer.DuplicateMap +import com.intellij.slicer.SliceAnalysisParams +import com.intellij.slicer.SliceNode +import com.intellij.slicer.SliceRootNode +import com.intellij.usages.TextChunk +import org.jetbrains.kotlin.psi.KtFile +import org.jetbrains.kotlin.psi.psiUtil.startOffset +import org.jetbrains.kotlin.test.InTextDirectivesUtils +import java.awt.Font + +internal class TestSliceTreeStructure(private val rootNode: SliceNode) : AbstractTreeStructureBase(rootNode.project) { + override fun getProviders() = emptyList() + + override fun getRootElement() = rootNode + + override fun commit() { + } + + override fun hasSomethingToCommit() = false +} + +internal fun buildTreeRepresentation(rootNode: SliceNode): String { + fun TextChunk.render(): String { + var text = text + if (attributes.fontType == Font.BOLD) { + text = "$text" + } + return text + } + + fun SliceNode.isSliceLeafValueClassNode() = javaClass.name == "com.intellij.slicer.SliceLeafValueClassNode" + + fun process(node: SliceNode, indent: Int): String { + val usage = node.element!!.value + + node.calculateDupNode() + val isDuplicated = !node.isSliceLeafValueClassNode() && node.duplicate != null + + return buildString { + when { + node is SliceRootNode && usage.element is KtFile -> { + node.sortedChildren.forEach { append(process(it, indent)) } + return@buildString + } + // SliceLeafValueClassNode is package-private + node.isSliceLeafValueClassNode() -> append("[${node.nodeText}]\n") + else -> { + val chunks = usage.text + append(chunks.first().render() + " ") + append("\t".repeat(indent)) + if (usage is KotlinSliceDereferenceUsage) { + append("DEREFERENCE: ") + } + if (usage is KotlinSliceUsage) { + append("[LAMBDA] ".repeat(usage.lambdaLevel)) + } + chunks.slice(1 until chunks.size).joinTo( + this, + separator = "", + prefix = if (isDuplicated) "DUPLICATE: " else "", + postfix = "\n" + ) { it.render() } + } + } + + if (!isDuplicated) { + node.sortedChildren.forEach { append(process(it, indent + 1)) } + } + }.replace(Regex(""), "") + } + + return process(rootNode, 0) +} + +private val SliceNode.sortedChildren: List + get() = children.sortedBy { it.value.element?.startOffset ?: -1 } + +internal fun testSliceFromOffset( + file: KtFile, + offset: Int, + doTest: (sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) -> Unit +) { + val fileText = file.text + val flowKind = InTextDirectivesUtils.findStringWithPrefixes(fileText, "// FLOW: ") + val withDereferences = InTextDirectivesUtils.isDirectiveDefined(fileText, "// WITH_DEREFERENCES") + val analysisParams = SliceAnalysisParams().apply { + dataFlowToThis = when (flowKind) { + "IN" -> true + "OUT" -> false + else -> throw AssertionError("Invalid flow kind: $flowKind") + } + showInstanceDereferences = withDereferences + scope = AnalysisScope(file.project) + } + + val elementAtCaret = file.findElementAt(offset)!! + val sliceProvider = KotlinSliceProvider() + val expression = sliceProvider.getExpressionAtCaret(elementAtCaret, analysisParams.dataFlowToThis)!! + val rootUsage = sliceProvider.createRootUsage(expression, analysisParams) + val rootNode = SliceRootNode(file.project, DuplicateMap(), rootUsage) + doTest(sliceProvider, rootNode) +} \ No newline at end of file diff --git a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTreeTestGenerated.java b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTreeTestGenerated.java index 6ec1820db63..36ae6e7295b 100644 --- a/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTreeTestGenerated.java +++ b/idea/tests/org/jetbrains/kotlin/idea/slicer/SlicerTreeTestGenerated.java @@ -25,616 +25,687 @@ public class SlicerTreeTestGenerated extends AbstractSlicerTreeTest { } public void testAllFilesPresentInSlicer() throws Exception { - KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClassWithExcluded(this.getClass(), new File("idea/testData/slicer"), Pattern.compile("^(.+)\\.kt$"), null); - } - - @TestMetadata("inflow/abstractFun.kt") - public void testInflow_AbstractFun() throws Exception { - runTest("idea/testData/slicer/inflow/abstractFun.kt"); - } - - @TestMetadata("inflow/anonymousFunBodyExpression.kt") - public void testInflow_AnonymousFunBodyExpression() throws Exception { - runTest("idea/testData/slicer/inflow/anonymousFunBodyExpression.kt"); - } - - @TestMetadata("inflow/anonymousFunReturnExpression.kt") - public void testInflow_AnonymousFunReturnExpression() throws Exception { - runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt"); - } - - @TestMetadata("inflow/cast.kt") - public void testInflow_Cast() throws Exception { - runTest("idea/testData/slicer/inflow/cast.kt"); - } - - @TestMetadata("inflow/compositeAssignments.kt") - public void testInflow_CompositeAssignments() throws Exception { - runTest("idea/testData/slicer/inflow/compositeAssignments.kt"); - } - - @TestMetadata("inflow/defaultGetterFieldInSetter.kt") - public void testInflow_DefaultGetterFieldInSetter() throws Exception { - runTest("idea/testData/slicer/inflow/defaultGetterFieldInSetter.kt"); - } - - @TestMetadata("inflow/delegateGetter.kt") - public void testInflow_DelegateGetter() throws Exception { - runTest("idea/testData/slicer/inflow/delegateGetter.kt"); - } - - @TestMetadata("inflow/delegateToJavaGetter.kt") - public void testInflow_DelegateToJavaGetter() throws Exception { - runTest("idea/testData/slicer/inflow/delegateToJavaGetter.kt"); - } - - @TestMetadata("inflow/diamondHierarchyJKMiddleClassFun.kt") - public void testInflow_DiamondHierarchyJKMiddleClassFun() throws Exception { - runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleClassFun.kt"); - } - - @TestMetadata("inflow/diamondHierarchyJKMiddleInterfaceFun.kt") - public void testInflow_DiamondHierarchyJKMiddleInterfaceFun() throws Exception { - runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleInterfaceFun.kt"); - } - - @TestMetadata("inflow/diamondHierarchyJKRootInterfaceFun.kt") - public void testInflow_DiamondHierarchyJKRootInterfaceFun() throws Exception { - runTest("idea/testData/slicer/inflow/diamondHierarchyJKRootInterfaceFun.kt"); - } - - @TestMetadata("inflow/diamondHierarchyMiddleClassFun.kt") - public void testInflow_DiamondHierarchyMiddleClassFun() throws Exception { - runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleClassFun.kt"); - } - - @TestMetadata("inflow/diamondHierarchyMiddleInterfaceFun.kt") - public void testInflow_DiamondHierarchyMiddleInterfaceFun() throws Exception { - runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleInterfaceFun.kt"); - } - - @TestMetadata("inflow/diamondHierarchyRootInterfaceFun.kt") - public void testInflow_DiamondHierarchyRootInterfaceFun() throws Exception { - runTest("idea/testData/slicer/inflow/diamondHierarchyRootInterfaceFun.kt"); - } - - @TestMetadata("inflow/doubleLambdaResult.kt") - public void testInflow_DoubleLambdaResult() throws Exception { - runTest("idea/testData/slicer/inflow/doubleLambdaResult.kt"); - } - - @TestMetadata("inflow/funParamerer.kt") - public void testInflow_FunParamerer() throws Exception { - runTest("idea/testData/slicer/inflow/funParamerer.kt"); - } - - @TestMetadata("inflow/funParamererWithDefault.kt") - public void testInflow_FunParamererWithDefault() throws Exception { - runTest("idea/testData/slicer/inflow/funParamererWithDefault.kt"); - } - - @TestMetadata("inflow/funResultViaCallableRef.kt") - public void testInflow_FunResultViaCallableRef() throws Exception { - runTest("idea/testData/slicer/inflow/funResultViaCallableRef.kt"); - } - - @TestMetadata("inflow/funResultViaCallableRefWithAssignment.kt") - public void testInflow_FunResultViaCallableRefWithAssignment() throws Exception { - runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithAssignment.kt"); - } - - @TestMetadata("inflow/funResultViaCallableRefWithDirectCall.kt") - public void testInflow_FunResultViaCallableRefWithDirectCall() throws Exception { - runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithDirectCall.kt"); - } - - @TestMetadata("inflow/funWithExpressionBody.kt") - public void testInflow_FunWithExpressionBody() throws Exception { - runTest("idea/testData/slicer/inflow/funWithExpressionBody.kt"); - } - - @TestMetadata("inflow/funWithReturnExpressions.kt") - public void testInflow_FunWithReturnExpressions() throws Exception { - runTest("idea/testData/slicer/inflow/funWithReturnExpressions.kt"); - } - - @TestMetadata("inflow/getterAndSetterUsingField.kt") - public void testInflow_GetterAndSetterUsingField() throws Exception { - runTest("idea/testData/slicer/inflow/getterAndSetterUsingField.kt"); - } - - @TestMetadata("inflow/getterExpressionBody.kt") - public void testInflow_GetterExpressionBody() throws Exception { - runTest("idea/testData/slicer/inflow/getterExpressionBody.kt"); - } - - @TestMetadata("inflow/getterReturnExpression.kt") - public void testInflow_GetterReturnExpression() throws Exception { - runTest("idea/testData/slicer/inflow/getterReturnExpression.kt"); - } - - @TestMetadata("inflow/ifExpression.kt") - public void testInflow_IfExpression() throws Exception { - runTest("idea/testData/slicer/inflow/ifExpression.kt"); - } - - @TestMetadata("inflow/lambdaResult.kt") - public void testInflow_LambdaResult() throws Exception { - runTest("idea/testData/slicer/inflow/lambdaResult.kt"); - } - - @TestMetadata("inflow/lambdaResultWithAssignments.kt") - public void testInflow_LambdaResultWithAssignments() throws Exception { - runTest("idea/testData/slicer/inflow/lambdaResultWithAssignments.kt"); - } - - @TestMetadata("inflow/lambdaResultWithDirectCall.kt") - public void testInflow_LambdaResultWithDirectCall() throws Exception { - runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCall.kt"); - } - - @TestMetadata("inflow/lambdaResultWithDirectCallViaAssignment.kt") - public void testInflow_LambdaResultWithDirectCallViaAssignment() throws Exception { - runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCallViaAssignment.kt"); - } - - @TestMetadata("inflow/localVal.kt") - public void testInflow_LocalVal() throws Exception { - runTest("idea/testData/slicer/inflow/localVal.kt"); - } - - @TestMetadata("inflow/localVar.kt") - public void testInflow_LocalVar() throws Exception { - runTest("idea/testData/slicer/inflow/localVar.kt"); - } - - @TestMetadata("inflow/memberValWithInitializer.kt") - public void testInflow_MemberValWithInitializer() throws Exception { - runTest("idea/testData/slicer/inflow/memberValWithInitializer.kt"); - } - - @TestMetadata("inflow/memberValWithSplitInitializer.kt") - public void testInflow_MemberValWithSplitInitializer() throws Exception { - runTest("idea/testData/slicer/inflow/memberValWithSplitInitializer.kt"); - } - - @TestMetadata("inflow/memberVarWithInitializer.kt") - public void testInflow_MemberVarWithInitializer() throws Exception { - runTest("idea/testData/slicer/inflow/memberVarWithInitializer.kt"); - } - - @TestMetadata("inflow/memberVarWithSplitInitializer.kt") - public void testInflow_MemberVarWithSplitInitializer() throws Exception { - runTest("idea/testData/slicer/inflow/memberVarWithSplitInitializer.kt"); - } - - @TestMetadata("inflow/noFieldInGetter.kt") - public void testInflow_NoFieldInGetter() throws Exception { - runTest("idea/testData/slicer/inflow/noFieldInGetter.kt"); - } - - @TestMetadata("inflow/nonLocalReturn.kt") - public void testInflow_NonLocalReturn() throws Exception { - runTest("idea/testData/slicer/inflow/nonLocalReturn.kt"); - } - - @TestMetadata("inflow/notNullAssertion.kt") - public void testInflow_NotNullAssertion() throws Exception { - runTest("idea/testData/slicer/inflow/notNullAssertion.kt"); - } - - @TestMetadata("inflow/nullsAndNotNulls.kt") - public void testInflow_NullsAndNotNulls() throws Exception { - runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); - } - - @TestMetadata("inflow/openFun.kt") - public void testInflow_OpenFun() throws Exception { - runTest("idea/testData/slicer/inflow/openFun.kt"); - } - - @TestMetadata("inflow/openFunInvokeOnParameter.kt") - public void testInflow_OpenFunInvokeOnParameter() throws Exception { - runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); - } - - @TestMetadata("inflow/overrideFun.kt") - public void testInflow_OverrideFun() throws Exception { - runTest("idea/testData/slicer/inflow/overrideFun.kt"); - } - - @TestMetadata("inflow/overrideProperty.kt") - public void testInflow_OverrideProperty() throws Exception { - runTest("idea/testData/slicer/inflow/overrideProperty.kt"); - } - - @TestMetadata("inflow/overridingFunctionResult.kt") - public void testInflow_OverridingFunctionResult() throws Exception { - runTest("idea/testData/slicer/inflow/overridingFunctionResult.kt"); - } - - @TestMetadata("inflow/overridingParameter.kt") - public void testInflow_OverridingParameter() throws Exception { - runTest("idea/testData/slicer/inflow/overridingParameter.kt"); - } - - @TestMetadata("inflow/overridingPropertyGetterResult.kt") - public void testInflow_OverridingPropertyGetterResult() throws Exception { - runTest("idea/testData/slicer/inflow/overridingPropertyGetterResult.kt"); - } - - @TestMetadata("inflow/overridingPropertyResult.kt") - public void testInflow_OverridingPropertyResult() throws Exception { - runTest("idea/testData/slicer/inflow/overridingPropertyResult.kt"); - } - - @TestMetadata("inflow/primaryConstructorParameter.kt") - public void testInflow_PrimaryConstructorParameter() throws Exception { - runTest("idea/testData/slicer/inflow/primaryConstructorParameter.kt"); - } - - @TestMetadata("inflow/primaryConstructorParameterWithDefault.kt") - public void testInflow_PrimaryConstructorParameterWithDefault() throws Exception { - runTest("idea/testData/slicer/inflow/primaryConstructorParameterWithDefault.kt"); - } - - @TestMetadata("inflow/propertyInInterface.kt") - public void testInflow_PropertyInInterface() throws Exception { - runTest("idea/testData/slicer/inflow/propertyInInterface.kt"); - } - - @TestMetadata("inflow/qualifiedAssignmentsForQualifiedRef.kt") - public void testInflow_QualifiedAssignmentsForQualifiedRef() throws Exception { - runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForQualifiedRef.kt"); - } - - @TestMetadata("inflow/qualifiedAssignmentsForSimpleRef.kt") - public void testInflow_QualifiedAssignmentsForSimpleRef() throws Exception { - runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForSimpleRef.kt"); - } - - @TestMetadata("inflow/safeCast.kt") - public void testInflow_SafeCast() throws Exception { - runTest("idea/testData/slicer/inflow/safeCast.kt"); - } - - @TestMetadata("inflow/secondaryConstructorParameter.kt") - public void testInflow_SecondaryConstructorParameter() throws Exception { - runTest("idea/testData/slicer/inflow/secondaryConstructorParameter.kt"); - } - - @TestMetadata("inflow/secondaryConstructorParameterWithDefault.kt") - public void testInflow_SecondaryConstructorParameterWithDefault() throws Exception { - runTest("idea/testData/slicer/inflow/secondaryConstructorParameterWithDefault.kt"); - } - - @TestMetadata("inflow/settersViaDelegateForQualifiedRef.kt") - public void testInflow_SettersViaDelegateForQualifiedRef() throws Exception { - runTest("idea/testData/slicer/inflow/settersViaDelegateForQualifiedRef.kt"); - } - - @TestMetadata("inflow/settersViaDelegateForSimpleRef.kt") - public void testInflow_SettersViaDelegateForSimpleRef() throws Exception { - runTest("idea/testData/slicer/inflow/settersViaDelegateForSimpleRef.kt"); - } - - @TestMetadata("inflow/settersViaJavaDelegate.kt") - public void testInflow_SettersViaJavaDelegate() throws Exception { - runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); - } - - @TestMetadata("inflow/topLevelVal.kt") - public void testInflow_TopLevelVal() throws Exception { - runTest("idea/testData/slicer/inflow/topLevelVal.kt"); - } - - @TestMetadata("inflow/topLevelVar.kt") - public void testInflow_TopLevelVar() throws Exception { - runTest("idea/testData/slicer/inflow/topLevelVar.kt"); - } - - @TestMetadata("inflow/valParameter.kt") - public void testInflow_ValParameter() throws Exception { - runTest("idea/testData/slicer/inflow/valParameter.kt"); - } - - @TestMetadata("inflow/varParameter.kt") - public void testInflow_VarParameter() throws Exception { - runTest("idea/testData/slicer/inflow/varParameter.kt"); - } - - @TestMetadata("inflow/whenExpression.kt") - public void testInflow_WhenExpression() throws Exception { - runTest("idea/testData/slicer/inflow/whenExpression.kt"); - } - - @TestMetadata("outflow/abstractExtensionMethodParameter.kt") - public void testOutflow_AbstractExtensionMethodParameter() throws Exception { - runTest("idea/testData/slicer/outflow/abstractExtensionMethodParameter.kt"); - } - - @TestMetadata("outflow/abstractMethodParameter1.kt") - public void testOutflow_AbstractMethodParameter1() throws Exception { - runTest("idea/testData/slicer/outflow/abstractMethodParameter1.kt"); - } - - @TestMetadata("outflow/abstractMethodParameter2.kt") - public void testOutflow_AbstractMethodParameter2() throws Exception { - runTest("idea/testData/slicer/outflow/abstractMethodParameter2.kt"); - } - - @TestMetadata("outflow/anonymousFunBodyExpression.kt") - public void testOutflow_AnonymousFunBodyExpression() throws Exception { - runTest("idea/testData/slicer/outflow/anonymousFunBodyExpression.kt"); - } - - @TestMetadata("outflow/anonymousFunReturnExpression.kt") - public void testOutflow_AnonymousFunReturnExpression() throws Exception { - runTest("idea/testData/slicer/outflow/anonymousFunReturnExpression.kt"); - } - - @TestMetadata("outflow/callArgument.kt") - public void testOutflow_CallArgument() throws Exception { - runTest("idea/testData/slicer/outflow/callArgument.kt"); - } - - @TestMetadata("outflow/callArgumentKJK.kt") - public void testOutflow_CallArgumentKJK() throws Exception { - runTest("idea/testData/slicer/outflow/callArgumentKJK.kt"); - } - - @TestMetadata("outflow/cast.kt") - public void testOutflow_Cast() throws Exception { - runTest("idea/testData/slicer/outflow/cast.kt"); - } - - @TestMetadata("outflow/defaultExplicitPrimaryConstructorCalls.kt") - public void testOutflow_DefaultExplicitPrimaryConstructorCalls() throws Exception { - runTest("idea/testData/slicer/outflow/defaultExplicitPrimaryConstructorCalls.kt"); - } - - @TestMetadata("outflow/diamondHierarchyJKLeafClassFun.kt") - public void testOutflow_DiamondHierarchyJKLeafClassFun() throws Exception { - runTest("idea/testData/slicer/outflow/diamondHierarchyJKLeafClassFun.kt"); - } - - @TestMetadata("outflow/diamondHierarchyJKMiddleClassFun.kt") - public void testOutflow_DiamondHierarchyJKMiddleClassFun() throws Exception { - runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleClassFun.kt"); - } - - @TestMetadata("outflow/diamondHierarchyJKMiddleInterfaceFun.kt") - public void testOutflow_DiamondHierarchyJKMiddleInterfaceFun() throws Exception { - runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleInterfaceFun.kt"); - } - - @TestMetadata("outflow/diamondHierarchyLeafClassFun.kt") - public void testOutflow_DiamondHierarchyLeafClassFun() throws Exception { - runTest("idea/testData/slicer/outflow/diamondHierarchyLeafClassFun.kt"); - } - - @TestMetadata("outflow/diamondHierarchyMiddleClassFun.kt") - public void testOutflow_DiamondHierarchyMiddleClassFun() throws Exception { - runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleClassFun.kt"); - } - - @TestMetadata("outflow/diamondHierarchyMiddleInterfaceFun.kt") - public void testOutflow_DiamondHierarchyMiddleInterfaceFun() throws Exception { - runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleInterfaceFun.kt"); - } - - @TestMetadata("outflow/doubleLambdaResult.kt") - public void testOutflow_DoubleLambdaResult() throws Exception { - runTest("idea/testData/slicer/outflow/doubleLambdaResult.kt"); - } - - @TestMetadata("outflow/explicitLambdaReturnExpression.kt") - public void testOutflow_ExplicitLambdaReturnExpression() throws Exception { - runTest("idea/testData/slicer/outflow/explicitLambdaReturnExpression.kt"); - } - - @TestMetadata("outflow/extensionIndexingDereferences.kt") - public void testOutflow_ExtensionIndexingDereferences() throws Exception { - runTest("idea/testData/slicer/outflow/extensionIndexingDereferences.kt"); - } - - @TestMetadata("outflow/forVariable.kt") - public void testOutflow_ForVariable() throws Exception { - runTest("idea/testData/slicer/outflow/forVariable.kt"); - } - - @TestMetadata("outflow/funBodyExpression.kt") - public void testOutflow_FunBodyExpression() throws Exception { - runTest("idea/testData/slicer/outflow/funBodyExpression.kt"); - } - - @TestMetadata("outflow/functionCalls.kt") - public void testOutflow_FunctionCalls() throws Exception { - runTest("idea/testData/slicer/outflow/functionCalls.kt"); - } - - @TestMetadata("outflow/funParameterUsages.kt") - public void testOutflow_FunParameterUsages() throws Exception { - runTest("idea/testData/slicer/outflow/funParameterUsages.kt"); - } - - @TestMetadata("outflow/funResultViaCallableRef.kt") - public void testOutflow_FunResultViaCallableRef() throws Exception { - runTest("idea/testData/slicer/outflow/funResultViaCallableRef.kt"); - } - - @TestMetadata("outflow/funResultViaCallableRefWithAssignment.kt") - public void testOutflow_FunResultViaCallableRefWithAssignment() throws Exception { - runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithAssignment.kt"); - } - - @TestMetadata("outflow/funResultViaCallableRefWithDirectCall.kt") - public void testOutflow_FunResultViaCallableRefWithDirectCall() throws Exception { - runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithDirectCall.kt"); - } - - @TestMetadata("outflow/funReturnExpression.kt") - public void testOutflow_FunReturnExpression() throws Exception { - runTest("idea/testData/slicer/outflow/funReturnExpression.kt"); - } - - @TestMetadata("outflow/getFunCalls.kt") - public void testOutflow_GetFunCalls() throws Exception { - runTest("idea/testData/slicer/outflow/getFunCalls.kt"); - } - - @TestMetadata("outflow/getterExpressionBody.kt") - public void testOutflow_GetterExpressionBody() throws Exception { - runTest("idea/testData/slicer/outflow/getterExpressionBody.kt"); - } - - @TestMetadata("outflow/getterReturnExpression.kt") - public void testOutflow_GetterReturnExpression() throws Exception { - runTest("idea/testData/slicer/outflow/getterReturnExpression.kt"); - } - - @TestMetadata("outflow/ifExpression.kt") - public void testOutflow_IfExpression() throws Exception { - runTest("idea/testData/slicer/outflow/ifExpression.kt"); - } - - @TestMetadata("outflow/indexingDereferences.kt") - public void testOutflow_IndexingDereferences() throws Exception { - runTest("idea/testData/slicer/outflow/indexingDereferences.kt"); - } - - @TestMetadata("outflow/jvmFieldMemberPropertyJavaUsages.kt") - public void testOutflow_JvmFieldMemberPropertyJavaUsages() throws Exception { - runTest("idea/testData/slicer/outflow/jvmFieldMemberPropertyJavaUsages.kt"); - } - - @TestMetadata("outflow/lambdaResult.kt") - public void testOutflow_LambdaResult() throws Exception { - runTest("idea/testData/slicer/outflow/lambdaResult.kt"); - } - - @TestMetadata("outflow/lambdaResultWithAssignments.kt") - public void testOutflow_LambdaResultWithAssignments() throws Exception { - runTest("idea/testData/slicer/outflow/lambdaResultWithAssignments.kt"); - } - - @TestMetadata("outflow/lambdaResultWithDirectCall.kt") - public void testOutflow_LambdaResultWithDirectCall() throws Exception { - runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCall.kt"); - } - - @TestMetadata("outflow/lambdaResultWithDirectCallViaAssignment.kt") - public void testOutflow_LambdaResultWithDirectCallViaAssignment() throws Exception { - runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCallViaAssignment.kt"); - } - - @TestMetadata("outflow/localVariableUsages.kt") - public void testOutflow_LocalVariableUsages() throws Exception { - runTest("idea/testData/slicer/outflow/localVariableUsages.kt"); - } - - @TestMetadata("outflow/memberPropertyUsages.kt") - public void testOutflow_MemberPropertyUsages() throws Exception { - runTest("idea/testData/slicer/outflow/memberPropertyUsages.kt"); - } - - @TestMetadata("outflow/nonLocalReturn.kt") - public void testOutflow_NonLocalReturn() throws Exception { - runTest("idea/testData/slicer/outflow/nonLocalReturn.kt"); - } - - @TestMetadata("outflow/notNullAssertion.kt") - public void testOutflow_NotNullAssertion() throws Exception { - runTest("idea/testData/slicer/outflow/notNullAssertion.kt"); - } - - @TestMetadata("outflow/openMethodParameter.kt") - public void testOutflow_OpenMethodParameter() throws Exception { - runTest("idea/testData/slicer/outflow/openMethodParameter.kt"); - } - - @TestMetadata("outflow/operatorCallDereferences.kt") - public void testOutflow_OperatorCallDereferences() throws Exception { - runTest("idea/testData/slicer/outflow/operatorCallDereferences.kt"); - } - - @TestMetadata("outflow/operatorFunCalls.kt") - public void testOutflow_OperatorFunCalls() throws Exception { - runTest("idea/testData/slicer/outflow/operatorFunCalls.kt"); - } - - @TestMetadata("outflow/overridingFunctionResult.kt") - public void testOutflow_OverridingFunctionResult() throws Exception { - runTest("idea/testData/slicer/outflow/overridingFunctionResult.kt"); - } - - @TestMetadata("outflow/overridingFunctionResultWithJava.kt") - public void testOutflow_OverridingFunctionResultWithJava() throws Exception { - runTest("idea/testData/slicer/outflow/overridingFunctionResultWithJava.kt"); - } - - @TestMetadata("outflow/overridingParameter.kt") - public void testOutflow_OverridingParameter() throws Exception { - runTest("idea/testData/slicer/outflow/overridingParameter.kt"); - } - - @TestMetadata("outflow/overridingPropertyGetterResult.kt") - public void testOutflow_OverridingPropertyGetterResult() throws Exception { - runTest("idea/testData/slicer/outflow/overridingPropertyGetterResult.kt"); - } - - @TestMetadata("outflow/overridingPropertyResult.kt") - public void testOutflow_OverridingPropertyResult() throws Exception { - runTest("idea/testData/slicer/outflow/overridingPropertyResult.kt"); - } - - @TestMetadata("outflow/primaryConstructorCalls.kt") - public void testOutflow_PrimaryConstructorCalls() throws Exception { - runTest("idea/testData/slicer/outflow/primaryConstructorCalls.kt"); - } - - @TestMetadata("outflow/primaryConstructorParameterUsages.kt") - public void testOutflow_PrimaryConstructorParameterUsages() throws Exception { - runTest("idea/testData/slicer/outflow/primaryConstructorParameterUsages.kt"); - } - - @TestMetadata("outflow/secondaryConstructorCalls.kt") - public void testOutflow_SecondaryConstructorCalls() throws Exception { - runTest("idea/testData/slicer/outflow/secondaryConstructorCalls.kt"); - } - - @TestMetadata("outflow/simpleCallDereferences.kt") - public void testOutflow_SimpleCallDereferences() throws Exception { - runTest("idea/testData/slicer/outflow/simpleCallDereferences.kt"); - } - - @TestMetadata("outflow/topLevelPropertyUsages.kt") - public void testOutflow_TopLevelPropertyUsages() throws Exception { - runTest("idea/testData/slicer/outflow/topLevelPropertyUsages.kt"); - } - - @TestMetadata("outflow/usagesInLoopRange.kt") - public void testOutflow_UsagesInLoopRange() throws Exception { - runTest("idea/testData/slicer/outflow/usagesInLoopRange.kt"); - } - - @TestMetadata("outflow/usagesInTemplates.kt") - public void testOutflow_UsagesInTemplates() throws Exception { - runTest("idea/testData/slicer/outflow/usagesInTemplates.kt"); - } - - @TestMetadata("outflow/valParameter.kt") - public void testOutflow_ValParameter() throws Exception { - runTest("idea/testData/slicer/outflow/valParameter.kt"); - } - - @TestMetadata("outflow/varParameter.kt") - public void testOutflow_VarParameter() throws Exception { - runTest("idea/testData/slicer/outflow/varParameter.kt"); - } - - @TestMetadata("outflow/whenExpression.kt") - public void testOutflow_WhenExpression() throws Exception { - runTest("idea/testData/slicer/outflow/whenExpression.kt"); + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/slicer"), Pattern.compile("^(.+)\\.kt$"), null, true, "mpp"); + } + + @TestMetadata("idea/testData/slicer/inflow") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Inflow extends AbstractSlicerTreeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("abstractFun.kt") + public void testAbstractFun() throws Exception { + runTest("idea/testData/slicer/inflow/abstractFun.kt"); + } + + public void testAllFilesPresentInInflow() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/slicer/inflow"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("anonymousFunBodyExpression.kt") + public void testAnonymousFunBodyExpression() throws Exception { + runTest("idea/testData/slicer/inflow/anonymousFunBodyExpression.kt"); + } + + @TestMetadata("anonymousFunReturnExpression.kt") + public void testAnonymousFunReturnExpression() throws Exception { + runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt"); + } + + @TestMetadata("cast.kt") + public void testCast() throws Exception { + runTest("idea/testData/slicer/inflow/cast.kt"); + } + + @TestMetadata("compositeAssignments.kt") + public void testCompositeAssignments() throws Exception { + runTest("idea/testData/slicer/inflow/compositeAssignments.kt"); + } + + @TestMetadata("defaultGetterFieldInSetter.kt") + public void testDefaultGetterFieldInSetter() throws Exception { + runTest("idea/testData/slicer/inflow/defaultGetterFieldInSetter.kt"); + } + + @TestMetadata("delegateGetter.kt") + public void testDelegateGetter() throws Exception { + runTest("idea/testData/slicer/inflow/delegateGetter.kt"); + } + + @TestMetadata("delegateToJavaGetter.kt") + public void testDelegateToJavaGetter() throws Exception { + runTest("idea/testData/slicer/inflow/delegateToJavaGetter.kt"); + } + + @TestMetadata("diamondHierarchyJKMiddleClassFun.kt") + public void testDiamondHierarchyJKMiddleClassFun() throws Exception { + runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleClassFun.kt"); + } + + @TestMetadata("diamondHierarchyJKMiddleInterfaceFun.kt") + public void testDiamondHierarchyJKMiddleInterfaceFun() throws Exception { + runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleInterfaceFun.kt"); + } + + @TestMetadata("diamondHierarchyJKRootInterfaceFun.kt") + public void testDiamondHierarchyJKRootInterfaceFun() throws Exception { + runTest("idea/testData/slicer/inflow/diamondHierarchyJKRootInterfaceFun.kt"); + } + + @TestMetadata("diamondHierarchyMiddleClassFun.kt") + public void testDiamondHierarchyMiddleClassFun() throws Exception { + runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleClassFun.kt"); + } + + @TestMetadata("diamondHierarchyMiddleInterfaceFun.kt") + public void testDiamondHierarchyMiddleInterfaceFun() throws Exception { + runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleInterfaceFun.kt"); + } + + @TestMetadata("diamondHierarchyRootInterfaceFun.kt") + public void testDiamondHierarchyRootInterfaceFun() throws Exception { + runTest("idea/testData/slicer/inflow/diamondHierarchyRootInterfaceFun.kt"); + } + + @TestMetadata("doubleLambdaResult.kt") + public void testDoubleLambdaResult() throws Exception { + runTest("idea/testData/slicer/inflow/doubleLambdaResult.kt"); + } + + @TestMetadata("funParamerer.kt") + public void testFunParamerer() throws Exception { + runTest("idea/testData/slicer/inflow/funParamerer.kt"); + } + + @TestMetadata("funParamererWithDefault.kt") + public void testFunParamererWithDefault() throws Exception { + runTest("idea/testData/slicer/inflow/funParamererWithDefault.kt"); + } + + @TestMetadata("funResultViaCallableRef.kt") + public void testFunResultViaCallableRef() throws Exception { + runTest("idea/testData/slicer/inflow/funResultViaCallableRef.kt"); + } + + @TestMetadata("funResultViaCallableRefWithAssignment.kt") + public void testFunResultViaCallableRefWithAssignment() throws Exception { + runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithAssignment.kt"); + } + + @TestMetadata("funResultViaCallableRefWithDirectCall.kt") + public void testFunResultViaCallableRefWithDirectCall() throws Exception { + runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithDirectCall.kt"); + } + + @TestMetadata("funWithExpressionBody.kt") + public void testFunWithExpressionBody() throws Exception { + runTest("idea/testData/slicer/inflow/funWithExpressionBody.kt"); + } + + @TestMetadata("funWithReturnExpressions.kt") + public void testFunWithReturnExpressions() throws Exception { + runTest("idea/testData/slicer/inflow/funWithReturnExpressions.kt"); + } + + @TestMetadata("getterAndSetterUsingField.kt") + public void testGetterAndSetterUsingField() throws Exception { + runTest("idea/testData/slicer/inflow/getterAndSetterUsingField.kt"); + } + + @TestMetadata("getterExpressionBody.kt") + public void testGetterExpressionBody() throws Exception { + runTest("idea/testData/slicer/inflow/getterExpressionBody.kt"); + } + + @TestMetadata("getterReturnExpression.kt") + public void testGetterReturnExpression() throws Exception { + runTest("idea/testData/slicer/inflow/getterReturnExpression.kt"); + } + + @TestMetadata("ifExpression.kt") + public void testIfExpression() throws Exception { + runTest("idea/testData/slicer/inflow/ifExpression.kt"); + } + + @TestMetadata("lambdaResult.kt") + public void testLambdaResult() throws Exception { + runTest("idea/testData/slicer/inflow/lambdaResult.kt"); + } + + @TestMetadata("lambdaResultWithAssignments.kt") + public void testLambdaResultWithAssignments() throws Exception { + runTest("idea/testData/slicer/inflow/lambdaResultWithAssignments.kt"); + } + + @TestMetadata("lambdaResultWithDirectCall.kt") + public void testLambdaResultWithDirectCall() throws Exception { + runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCall.kt"); + } + + @TestMetadata("lambdaResultWithDirectCallViaAssignment.kt") + public void testLambdaResultWithDirectCallViaAssignment() throws Exception { + runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCallViaAssignment.kt"); + } + + @TestMetadata("localVal.kt") + public void testLocalVal() throws Exception { + runTest("idea/testData/slicer/inflow/localVal.kt"); + } + + @TestMetadata("localVar.kt") + public void testLocalVar() throws Exception { + runTest("idea/testData/slicer/inflow/localVar.kt"); + } + + @TestMetadata("memberValWithInitializer.kt") + public void testMemberValWithInitializer() throws Exception { + runTest("idea/testData/slicer/inflow/memberValWithInitializer.kt"); + } + + @TestMetadata("memberValWithSplitInitializer.kt") + public void testMemberValWithSplitInitializer() throws Exception { + runTest("idea/testData/slicer/inflow/memberValWithSplitInitializer.kt"); + } + + @TestMetadata("memberVarWithInitializer.kt") + public void testMemberVarWithInitializer() throws Exception { + runTest("idea/testData/slicer/inflow/memberVarWithInitializer.kt"); + } + + @TestMetadata("memberVarWithSplitInitializer.kt") + public void testMemberVarWithSplitInitializer() throws Exception { + runTest("idea/testData/slicer/inflow/memberVarWithSplitInitializer.kt"); + } + + @TestMetadata("noFieldInGetter.kt") + public void testNoFieldInGetter() throws Exception { + runTest("idea/testData/slicer/inflow/noFieldInGetter.kt"); + } + + @TestMetadata("nonLocalReturn.kt") + public void testNonLocalReturn() throws Exception { + runTest("idea/testData/slicer/inflow/nonLocalReturn.kt"); + } + + @TestMetadata("notNullAssertion.kt") + public void testNotNullAssertion() throws Exception { + runTest("idea/testData/slicer/inflow/notNullAssertion.kt"); + } + + @TestMetadata("nullsAndNotNulls.kt") + public void testNullsAndNotNulls() throws Exception { + runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); + } + + @TestMetadata("onFunctionReceiverType.kt") + public void testOnFunctionReceiverType() throws Exception { + runTest("idea/testData/slicer/inflow/onFunctionReceiverType.kt"); + } + + @TestMetadata("onPropertyReceiverType.kt") + public void testOnPropertyReceiverType() throws Exception { + runTest("idea/testData/slicer/inflow/onPropertyReceiverType.kt"); + } + + @TestMetadata("openFun.kt") + public void testOpenFun() throws Exception { + runTest("idea/testData/slicer/inflow/openFun.kt"); + } + + @TestMetadata("openFunInvokeOnParameter.kt") + public void testOpenFunInvokeOnParameter() throws Exception { + runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); + } + + @TestMetadata("overrideExtension1.kt") + public void testOverrideExtension1() throws Exception { + runTest("idea/testData/slicer/inflow/overrideExtension1.kt"); + } + + @TestMetadata("overrideExtension2.kt") + public void testOverrideExtension2() throws Exception { + runTest("idea/testData/slicer/inflow/overrideExtension2.kt"); + } + + @TestMetadata("overrideFun.kt") + public void testOverrideFun() throws Exception { + runTest("idea/testData/slicer/inflow/overrideFun.kt"); + } + + @TestMetadata("overrideProperty.kt") + public void testOverrideProperty() throws Exception { + runTest("idea/testData/slicer/inflow/overrideProperty.kt"); + } + + @TestMetadata("overridingFunctionResult.kt") + public void testOverridingFunctionResult() throws Exception { + runTest("idea/testData/slicer/inflow/overridingFunctionResult.kt"); + } + + @TestMetadata("overridingParameter.kt") + public void testOverridingParameter() throws Exception { + runTest("idea/testData/slicer/inflow/overridingParameter.kt"); + } + + @TestMetadata("overridingPropertyGetterResult.kt") + public void testOverridingPropertyGetterResult() throws Exception { + runTest("idea/testData/slicer/inflow/overridingPropertyGetterResult.kt"); + } + + @TestMetadata("overridingPropertyResult.kt") + public void testOverridingPropertyResult() throws Exception { + runTest("idea/testData/slicer/inflow/overridingPropertyResult.kt"); + } + + @TestMetadata("primaryConstructorParameter.kt") + public void testPrimaryConstructorParameter() throws Exception { + runTest("idea/testData/slicer/inflow/primaryConstructorParameter.kt"); + } + + @TestMetadata("primaryConstructorParameterWithDefault.kt") + public void testPrimaryConstructorParameterWithDefault() throws Exception { + runTest("idea/testData/slicer/inflow/primaryConstructorParameterWithDefault.kt"); + } + + @TestMetadata("propertyInInterface.kt") + public void testPropertyInInterface() throws Exception { + runTest("idea/testData/slicer/inflow/propertyInInterface.kt"); + } + + @TestMetadata("qualifiedAssignmentsForQualifiedRef.kt") + public void testQualifiedAssignmentsForQualifiedRef() throws Exception { + runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForQualifiedRef.kt"); + } + + @TestMetadata("qualifiedAssignmentsForSimpleRef.kt") + public void testQualifiedAssignmentsForSimpleRef() throws Exception { + runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForSimpleRef.kt"); + } + + @TestMetadata("safeCast.kt") + public void testSafeCast() throws Exception { + runTest("idea/testData/slicer/inflow/safeCast.kt"); + } + + @TestMetadata("secondaryConstructorParameter.kt") + public void testSecondaryConstructorParameter() throws Exception { + runTest("idea/testData/slicer/inflow/secondaryConstructorParameter.kt"); + } + + @TestMetadata("secondaryConstructorParameterWithDefault.kt") + public void testSecondaryConstructorParameterWithDefault() throws Exception { + runTest("idea/testData/slicer/inflow/secondaryConstructorParameterWithDefault.kt"); + } + + @TestMetadata("settersViaDelegateForQualifiedRef.kt") + public void testSettersViaDelegateForQualifiedRef() throws Exception { + runTest("idea/testData/slicer/inflow/settersViaDelegateForQualifiedRef.kt"); + } + + @TestMetadata("settersViaDelegateForSimpleRef.kt") + public void testSettersViaDelegateForSimpleRef() throws Exception { + runTest("idea/testData/slicer/inflow/settersViaDelegateForSimpleRef.kt"); + } + + @TestMetadata("settersViaJavaDelegate.kt") + public void testSettersViaJavaDelegate() throws Exception { + runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); + } + + @TestMetadata("thisInExtensionFunction.kt") + public void testThisInExtensionFunction() throws Exception { + runTest("idea/testData/slicer/inflow/thisInExtensionFunction.kt"); + } + + @TestMetadata("thisInExtensionProperty.kt") + public void testThisInExtensionProperty() throws Exception { + runTest("idea/testData/slicer/inflow/thisInExtensionProperty.kt"); + } + + @TestMetadata("topLevelVal.kt") + public void testTopLevelVal() throws Exception { + runTest("idea/testData/slicer/inflow/topLevelVal.kt"); + } + + @TestMetadata("topLevelVar.kt") + public void testTopLevelVar() throws Exception { + runTest("idea/testData/slicer/inflow/topLevelVar.kt"); + } + + @TestMetadata("valParameter.kt") + public void testValParameter() throws Exception { + runTest("idea/testData/slicer/inflow/valParameter.kt"); + } + + @TestMetadata("varParameter.kt") + public void testVarParameter() throws Exception { + runTest("idea/testData/slicer/inflow/varParameter.kt"); + } + + @TestMetadata("whenExpression.kt") + public void testWhenExpression() throws Exception { + runTest("idea/testData/slicer/inflow/whenExpression.kt"); + } + } + + @TestMetadata("idea/testData/slicer/outflow") + @TestDataPath("$PROJECT_ROOT") + @RunWith(JUnit3RunnerWithInners.class) + public static class Outflow extends AbstractSlicerTreeTest { + private void runTest(String testDataFilePath) throws Exception { + KotlinTestUtils.runTest(this::doTest, this, testDataFilePath); + } + + @TestMetadata("abstractExtensionMethodParameter.kt") + public void testAbstractExtensionMethodParameter() throws Exception { + runTest("idea/testData/slicer/outflow/abstractExtensionMethodParameter.kt"); + } + + @TestMetadata("abstractMethodParameter1.kt") + public void testAbstractMethodParameter1() throws Exception { + runTest("idea/testData/slicer/outflow/abstractMethodParameter1.kt"); + } + + @TestMetadata("abstractMethodParameter2.kt") + public void testAbstractMethodParameter2() throws Exception { + runTest("idea/testData/slicer/outflow/abstractMethodParameter2.kt"); + } + + public void testAllFilesPresentInOutflow() throws Exception { + KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/slicer/outflow"), Pattern.compile("^(.+)\\.kt$"), null, true); + } + + @TestMetadata("anonymousFunBodyExpression.kt") + public void testAnonymousFunBodyExpression() throws Exception { + runTest("idea/testData/slicer/outflow/anonymousFunBodyExpression.kt"); + } + + @TestMetadata("anonymousFunReturnExpression.kt") + public void testAnonymousFunReturnExpression() throws Exception { + runTest("idea/testData/slicer/outflow/anonymousFunReturnExpression.kt"); + } + + @TestMetadata("callArgument.kt") + public void testCallArgument() throws Exception { + runTest("idea/testData/slicer/outflow/callArgument.kt"); + } + + @TestMetadata("callArgumentKJK.kt") + public void testCallArgumentKJK() throws Exception { + runTest("idea/testData/slicer/outflow/callArgumentKJK.kt"); + } + + @TestMetadata("cast.kt") + public void testCast() throws Exception { + runTest("idea/testData/slicer/outflow/cast.kt"); + } + + @TestMetadata("defaultExplicitPrimaryConstructorCalls.kt") + public void testDefaultExplicitPrimaryConstructorCalls() throws Exception { + runTest("idea/testData/slicer/outflow/defaultExplicitPrimaryConstructorCalls.kt"); + } + + @TestMetadata("diamondHierarchyJKLeafClassFun.kt") + public void testDiamondHierarchyJKLeafClassFun() throws Exception { + runTest("idea/testData/slicer/outflow/diamondHierarchyJKLeafClassFun.kt"); + } + + @TestMetadata("diamondHierarchyJKMiddleClassFun.kt") + public void testDiamondHierarchyJKMiddleClassFun() throws Exception { + runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleClassFun.kt"); + } + + @TestMetadata("diamondHierarchyJKMiddleInterfaceFun.kt") + public void testDiamondHierarchyJKMiddleInterfaceFun() throws Exception { + runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleInterfaceFun.kt"); + } + + @TestMetadata("diamondHierarchyLeafClassFun.kt") + public void testDiamondHierarchyLeafClassFun() throws Exception { + runTest("idea/testData/slicer/outflow/diamondHierarchyLeafClassFun.kt"); + } + + @TestMetadata("diamondHierarchyMiddleClassFun.kt") + public void testDiamondHierarchyMiddleClassFun() throws Exception { + runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleClassFun.kt"); + } + + @TestMetadata("diamondHierarchyMiddleInterfaceFun.kt") + public void testDiamondHierarchyMiddleInterfaceFun() throws Exception { + runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleInterfaceFun.kt"); + } + + @TestMetadata("doubleLambdaResult.kt") + public void testDoubleLambdaResult() throws Exception { + runTest("idea/testData/slicer/outflow/doubleLambdaResult.kt"); + } + + @TestMetadata("explicitLambdaReturnExpression.kt") + public void testExplicitLambdaReturnExpression() throws Exception { + runTest("idea/testData/slicer/outflow/explicitLambdaReturnExpression.kt"); + } + + @TestMetadata("extensionIndexingDereferences.kt") + public void testExtensionIndexingDereferences() throws Exception { + runTest("idea/testData/slicer/outflow/extensionIndexingDereferences.kt"); + } + + @TestMetadata("forVariable.kt") + public void testForVariable() throws Exception { + runTest("idea/testData/slicer/outflow/forVariable.kt"); + } + + @TestMetadata("funBodyExpression.kt") + public void testFunBodyExpression() throws Exception { + runTest("idea/testData/slicer/outflow/funBodyExpression.kt"); + } + + @TestMetadata("funParameterUsages.kt") + public void testFunParameterUsages() throws Exception { + runTest("idea/testData/slicer/outflow/funParameterUsages.kt"); + } + + @TestMetadata("funResultViaCallableRef.kt") + public void testFunResultViaCallableRef() throws Exception { + runTest("idea/testData/slicer/outflow/funResultViaCallableRef.kt"); + } + + @TestMetadata("funResultViaCallableRefWithAssignment.kt") + public void testFunResultViaCallableRefWithAssignment() throws Exception { + runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithAssignment.kt"); + } + + @TestMetadata("funResultViaCallableRefWithDirectCall.kt") + public void testFunResultViaCallableRefWithDirectCall() throws Exception { + runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithDirectCall.kt"); + } + + @TestMetadata("funReturnExpression.kt") + public void testFunReturnExpression() throws Exception { + runTest("idea/testData/slicer/outflow/funReturnExpression.kt"); + } + + @TestMetadata("functionCalls.kt") + public void testFunctionCalls() throws Exception { + runTest("idea/testData/slicer/outflow/functionCalls.kt"); + } + + @TestMetadata("getFunCalls.kt") + public void testGetFunCalls() throws Exception { + runTest("idea/testData/slicer/outflow/getFunCalls.kt"); + } + + @TestMetadata("getterExpressionBody.kt") + public void testGetterExpressionBody() throws Exception { + runTest("idea/testData/slicer/outflow/getterExpressionBody.kt"); + } + + @TestMetadata("getterReturnExpression.kt") + public void testGetterReturnExpression() throws Exception { + runTest("idea/testData/slicer/outflow/getterReturnExpression.kt"); + } + + @TestMetadata("ifExpression.kt") + public void testIfExpression() throws Exception { + runTest("idea/testData/slicer/outflow/ifExpression.kt"); + } + + @TestMetadata("indexingDereferences.kt") + public void testIndexingDereferences() throws Exception { + runTest("idea/testData/slicer/outflow/indexingDereferences.kt"); + } + + @TestMetadata("jvmFieldMemberPropertyJavaUsages.kt") + public void testJvmFieldMemberPropertyJavaUsages() throws Exception { + runTest("idea/testData/slicer/outflow/jvmFieldMemberPropertyJavaUsages.kt"); + } + + @TestMetadata("lambdaResult.kt") + public void testLambdaResult() throws Exception { + runTest("idea/testData/slicer/outflow/lambdaResult.kt"); + } + + @TestMetadata("lambdaResultWithAssignments.kt") + public void testLambdaResultWithAssignments() throws Exception { + runTest("idea/testData/slicer/outflow/lambdaResultWithAssignments.kt"); + } + + @TestMetadata("lambdaResultWithDirectCall.kt") + public void testLambdaResultWithDirectCall() throws Exception { + runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCall.kt"); + } + + @TestMetadata("lambdaResultWithDirectCallViaAssignment.kt") + public void testLambdaResultWithDirectCallViaAssignment() throws Exception { + runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCallViaAssignment.kt"); + } + + @TestMetadata("localVariableUsages.kt") + public void testLocalVariableUsages() throws Exception { + runTest("idea/testData/slicer/outflow/localVariableUsages.kt"); + } + + @TestMetadata("memberPropertyUsages.kt") + public void testMemberPropertyUsages() throws Exception { + runTest("idea/testData/slicer/outflow/memberPropertyUsages.kt"); + } + + @TestMetadata("nonLocalReturn.kt") + public void testNonLocalReturn() throws Exception { + runTest("idea/testData/slicer/outflow/nonLocalReturn.kt"); + } + + @TestMetadata("notNullAssertion.kt") + public void testNotNullAssertion() throws Exception { + runTest("idea/testData/slicer/outflow/notNullAssertion.kt"); + } + + @TestMetadata("openMethodParameter.kt") + public void testOpenMethodParameter() throws Exception { + runTest("idea/testData/slicer/outflow/openMethodParameter.kt"); + } + + @TestMetadata("operatorCallDereferences.kt") + public void testOperatorCallDereferences() throws Exception { + runTest("idea/testData/slicer/outflow/operatorCallDereferences.kt"); + } + + @TestMetadata("operatorFunCalls.kt") + public void testOperatorFunCalls() throws Exception { + runTest("idea/testData/slicer/outflow/operatorFunCalls.kt"); + } + + @TestMetadata("overridingFunctionResult.kt") + public void testOverridingFunctionResult() throws Exception { + runTest("idea/testData/slicer/outflow/overridingFunctionResult.kt"); + } + + @TestMetadata("overridingFunctionResultWithJava.kt") + public void testOverridingFunctionResultWithJava() throws Exception { + runTest("idea/testData/slicer/outflow/overridingFunctionResultWithJava.kt"); + } + + @TestMetadata("overridingParameter.kt") + public void testOverridingParameter() throws Exception { + runTest("idea/testData/slicer/outflow/overridingParameter.kt"); + } + + @TestMetadata("overridingPropertyGetterResult.kt") + public void testOverridingPropertyGetterResult() throws Exception { + runTest("idea/testData/slicer/outflow/overridingPropertyGetterResult.kt"); + } + + @TestMetadata("overridingPropertyResult.kt") + public void testOverridingPropertyResult() throws Exception { + runTest("idea/testData/slicer/outflow/overridingPropertyResult.kt"); + } + + @TestMetadata("primaryConstructorCalls.kt") + public void testPrimaryConstructorCalls() throws Exception { + runTest("idea/testData/slicer/outflow/primaryConstructorCalls.kt"); + } + + @TestMetadata("primaryConstructorParameterUsages.kt") + public void testPrimaryConstructorParameterUsages() throws Exception { + runTest("idea/testData/slicer/outflow/primaryConstructorParameterUsages.kt"); + } + + @TestMetadata("secondaryConstructorCalls.kt") + public void testSecondaryConstructorCalls() throws Exception { + runTest("idea/testData/slicer/outflow/secondaryConstructorCalls.kt"); + } + + @TestMetadata("simpleCallDereferences.kt") + public void testSimpleCallDereferences() throws Exception { + runTest("idea/testData/slicer/outflow/simpleCallDereferences.kt"); + } + + @TestMetadata("thisInExtensionFunction.kt") + public void testThisInExtensionFunction() throws Exception { + runTest("idea/testData/slicer/outflow/thisInExtensionFunction.kt"); + } + + @TestMetadata("thisInExtensionProperty.kt") + public void testThisInExtensionProperty() throws Exception { + runTest("idea/testData/slicer/outflow/thisInExtensionProperty.kt"); + } + + @TestMetadata("topLevelPropertyUsages.kt") + public void testTopLevelPropertyUsages() throws Exception { + runTest("idea/testData/slicer/outflow/topLevelPropertyUsages.kt"); + } + + @TestMetadata("usagesInLoopRange.kt") + public void testUsagesInLoopRange() throws Exception { + runTest("idea/testData/slicer/outflow/usagesInLoopRange.kt"); + } + + @TestMetadata("usagesInTemplates.kt") + public void testUsagesInTemplates() throws Exception { + runTest("idea/testData/slicer/outflow/usagesInTemplates.kt"); + } + + @TestMetadata("valParameter.kt") + public void testValParameter() throws Exception { + runTest("idea/testData/slicer/outflow/valParameter.kt"); + } + + @TestMetadata("varParameter.kt") + public void testVarParameter() throws Exception { + runTest("idea/testData/slicer/outflow/varParameter.kt"); + } + + @TestMetadata("whenExpression.kt") + public void testWhenExpression() throws Exception { + runTest("idea/testData/slicer/outflow/whenExpression.kt"); + } + + @TestMetadata("wrongThis.kt") + public void testWrongThis() throws Exception { + runTest("idea/testData/slicer/outflow/wrongThis.kt"); + } } }