Data flow to/from here: supported expected/actual declarations and extension receivers

This commit is contained in:
Valentin Kipyatkov
2020-04-09 22:01:22 +03:00
parent bfa3fb0589
commit 90188ef44f
78 changed files with 1704 additions and 801 deletions
@@ -124,6 +124,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationHighlightingT
import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationNavigationTest import org.jetbrains.kotlin.idea.script.AbstractScriptConfigurationNavigationTest
import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest 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.AbstractSlicerNullnessGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest
import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest import org.jetbrains.kotlin.idea.structureView.AbstractKotlinFileStructureTest
@@ -872,7 +873,7 @@ fun main(args: Array<String>) {
} }
testClass<AbstractSlicerTreeTest> { testClass<AbstractSlicerTreeTest> {
model("slicer", singleClass = true) model("slicer", excludeDirs = listOf("mpp"))
} }
testClass<AbstractSlicerLeafGroupingTest> { testClass<AbstractSlicerLeafGroupingTest> {
@@ -882,6 +883,10 @@ fun main(args: Array<String>) {
testClass<AbstractSlicerNullnessGroupingTest> { testClass<AbstractSlicerNullnessGroupingTest> {
model("slicer/inflow", singleClass = true) model("slicer/inflow", singleClass = true)
} }
testClass<AbstractSlicerMultiplatformTest> {
model("slicer/mpp", recursive = false, extension = null)
}
} }
testGroup("idea/idea-fir/tests", "idea/testData") { testGroup("idea/idea-fir/tests", "idea/testData") {
@@ -126,6 +126,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest 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.structureView.AbstractKotlinFileStructureTest
import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest
import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest
@@ -821,7 +822,7 @@ fun main(args: Array<String>) {
} }
testClass<AbstractSlicerTreeTest> { testClass<AbstractSlicerTreeTest> {
model("slicer", singleClass = true) model("slicer", excludeDirs = listOf("mpp"))
} }
testClass<AbstractSlicerLeafGroupingTest> { testClass<AbstractSlicerLeafGroupingTest> {
@@ -831,6 +832,10 @@ fun main(args: Array<String>) {
testClass<AbstractSlicerNullnessGroupingTest> { testClass<AbstractSlicerNullnessGroupingTest> {
model("slicer/inflow", singleClass = true) model("slicer/inflow", singleClass = true)
} }
testClass<AbstractSlicerMultiplatformTest> {
model("slicer/mpp", recursive = false, extension = null)
}
} }
testGroup("idea/scripting-support/test", "idea/scripting-support/testData") { testGroup("idea/scripting-support/test", "idea/scripting-support/testData") {
@@ -126,6 +126,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest 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.structureView.AbstractKotlinFileStructureTest
import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest
import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest
@@ -821,7 +822,7 @@ fun main(args: Array<String>) {
} }
testClass<AbstractSlicerTreeTest> { testClass<AbstractSlicerTreeTest> {
model("slicer", singleClass = true) model("slicer", excludeDirs = listOf("mpp"))
} }
testClass<AbstractSlicerLeafGroupingTest> { testClass<AbstractSlicerLeafGroupingTest> {
@@ -831,6 +832,10 @@ fun main(args: Array<String>) {
testClass<AbstractSlicerNullnessGroupingTest> { testClass<AbstractSlicerNullnessGroupingTest> {
model("slicer/inflow", singleClass = true) model("slicer/inflow", singleClass = true)
} }
testClass<AbstractSlicerMultiplatformTest> {
model("slicer/mpp", recursive = false, extension = null)
}
} }
testGroup("idea/scripting-support/test", "idea/scripting-support/testData") { testGroup("idea/scripting-support/test", "idea/scripting-support/testData") {
@@ -126,6 +126,7 @@ import org.jetbrains.kotlin.idea.script.AbstractScriptDefinitionsOrderTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerLeafGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest import org.jetbrains.kotlin.idea.slicer.AbstractSlicerNullnessGroupingTest
import org.jetbrains.kotlin.idea.slicer.AbstractSlicerTreeTest 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.structureView.AbstractKotlinFileStructureTest
import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest import org.jetbrains.kotlin.idea.stubs.AbstractMultiFileHighlightingTest
import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest import org.jetbrains.kotlin.idea.stubs.AbstractResolveByStubTest
@@ -821,7 +822,7 @@ fun main(args: Array<String>) {
} }
testClass<AbstractSlicerTreeTest> { testClass<AbstractSlicerTreeTest> {
model("slicer", singleClass = true) model("slicer", excludeDirs = listOf("mpp"))
} }
testClass<AbstractSlicerLeafGroupingTest> { testClass<AbstractSlicerLeafGroupingTest> {
@@ -831,6 +832,10 @@ fun main(args: Array<String>) {
testClass<AbstractSlicerNullnessGroupingTest> { testClass<AbstractSlicerNullnessGroupingTest> {
model("slicer/inflow", singleClass = true) model("slicer/inflow", singleClass = true)
} }
testClass<AbstractSlicerMultiplatformTest> {
model("slicer/mpp", recursive = false, extension = null)
}
} }
testGroup("idea/scripting-support/test", "idea/scripting-support/testData") { testGroup("idea/scripting-support/test", "idea/scripting-support/testData") {
@@ -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.pseudocode.instructions.jumps.ReturnValueInstruction
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder import org.jetbrains.kotlin.cfg.pseudocodeTraverser.TraversalOrder
import org.jetbrains.kotlin.cfg.pseudocodeTraverser.traverse import org.jetbrains.kotlin.cfg.pseudocodeTraverser.traverse
import org.jetbrains.kotlin.descriptors.CallableDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource import org.jetbrains.kotlin.descriptors.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.ReceiverParameterDescriptor
import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors import org.jetbrains.kotlin.descriptors.VariableDescriptorWithAccessors
import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor import org.jetbrains.kotlin.descriptors.impl.SyntheticFieldDescriptor
import org.jetbrains.kotlin.idea.caches.resolve.* 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.references.readWriteAccessWithFullExpression
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders 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.lexer.KtTokens
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType import org.jetbrains.kotlin.psi.psiUtil.forEachDescendantOfType
@@ -45,23 +49,34 @@ import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
class InflowSlicer( class InflowSlicer(
element: KtExpression, element: KtElement,
processor: SliceUsageProcessor, processor: SliceUsageProcessor,
parentUsage: KotlinSliceUsage parentUsage: KotlinSliceUsage
) : Slicer(element, processor, parentUsage) { ) : Slicer(element, processor, parentUsage) {
override fun processChildren() { override fun processChildren() {
if (parentUsage.forcedExpressionMode) { if (parentUsage.forcedExpressionMode) {
processExpression(element) (element as? KtExpression)?.let { processExpression(it) }
return return
} }
when (element) { when (element) {
is KtProperty -> processProperty(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 KtParameter -> processParameter(parameter = element, includeOverriders = parentUsage.parent == null)
is KtDeclarationWithBody -> element.processBody() 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) { fun processCall(usageInfo: UsageInfo) {
val refElement = usageInfo.element ?: return usageInfo.element?.let {
extractArgumentExpression(refElement)?.passToProcessorAsValue() extractArgumentExpression(it)?.passToProcessorAsValue()
}
} }
processCalls(function, analysisScope, includeOverriders, ::processCall) 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) { private fun processExpression(expression: KtExpression) {
val lambda = when (expression) { val lambda = when (expression) {
is KtLambdaExpression -> expression.functionLiteral is KtLambdaExpression -> expression.functionLiteral
@@ -171,18 +212,30 @@ class InflowSlicer(
} }
return return
} }
val accessedDescriptor = createdAt.target.accessedDescriptor ?: return val accessedDescriptor = createdAt.target.accessedDescriptor ?: return
val accessedDeclaration = accessedDescriptor.originalSource.getPsi() ?: return val accessedDeclaration = accessedDescriptor.originalSource.getPsi()
if (accessedDescriptor is SyntheticFieldDescriptor) { when (accessedDescriptor) {
is SyntheticFieldDescriptor -> {
val property = accessedDeclaration as? KtProperty ?: return val property = accessedDeclaration as? KtProperty ?: return
if (accessedDescriptor.propertyDescriptor.setter?.isDefault != false) { if (accessedDescriptor.propertyDescriptor.setter?.isDefault != false) {
property.processPropertyAssignments() property.processPropertyAssignments()
} else { } else {
property.setter?.processBackingFieldAssignments() property.setter?.processBackingFieldAssignments()
} }
return
} }
accessedDeclaration.passDeclarationToProcessorWithOverriders()
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()
}
}
} }
is MergeInstruction -> createdAt.passInputsToProcessor() is MergeInstruction -> createdAt.passInputsToProcessor()
@@ -287,8 +340,17 @@ class InflowSlicer(
private fun PsiElement.passDeclarationToProcessorWithOverriders() { private fun PsiElement.passDeclarationToProcessorWithOverriders() {
passToProcessor() passToProcessor()
HierarchySearchRequest(this, analysisScope) HierarchySearchRequest(this, analysisScope)
.searchOverriders() .searchOverriders()
.forEach { it.namedUnwrappedElement?.passToProcessor() } .forEach { it.namedUnwrappedElement?.passToProcessor() }
if (this is KtCallableDeclaration && isExpectDeclaration()) {
resolveToDescriptorIfAny(BodyResolveMode.FULL)
?.actualsForExpected()
?.forEach {
(it as? DeclarationDescriptorWithSource)?.originalSource?.getPsi()?.passToProcessor()
}
}
} }
} }
@@ -20,6 +20,7 @@ import com.intellij.codeInsight.Nullability
import com.intellij.ide.util.treeView.AbstractTreeStructure import com.intellij.ide.util.treeView.AbstractTreeStructure
import com.intellij.openapi.actionSystem.DefaultActionGroup import com.intellij.openapi.actionSystem.DefaultActionGroup
import com.intellij.psi.PsiElement import com.intellij.psi.PsiElement
import com.intellij.psi.util.parentOfType
import com.intellij.slicer.* import com.intellij.slicer.*
import org.jetbrains.kotlin.builtins.KotlinBuiltIns import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.descriptors.CallableDescriptor 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.*
import org.jetbrains.kotlin.psi.psiUtil.isPlainWithEscapes import org.jetbrains.kotlin.psi.psiUtil.isPlainWithEscapes
import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf import org.jetbrains.kotlin.psi.psiUtil.parentsWithSelf
import org.jetbrains.kotlin.psi2ir.deparenthesize
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.types.TypeUtils import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.isError import org.jetbrains.kotlin.types.isError
@@ -73,26 +75,34 @@ class KotlinSliceProvider : SliceLanguageSupportProvider, SliceUsageTransformer
return listOf(KotlinSliceUsage(usage.element, usage.parent, 0, false)) return listOf(KotlinSliceUsage(usage.element, usage.parent, 0, false))
} }
override fun getExpressionAtCaret(atCaret: PsiElement, dataFlowToThis: Boolean): KtExpression? { override fun getExpressionAtCaret(atCaret: PsiElement, dataFlowToThis: Boolean): KtElement? {
val element = val element = atCaret.parentsWithSelf
atCaret.parentsWithSelf .filterIsInstance<KtElement>()
.firstOrNull { .firstOrNull(::isSliceElement)
it is KtProperty || ?.deparenthesize() ?: return null
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
if (dataFlowToThis) { if (dataFlowToThis) {
if (element is KtConstantExpression) return null if (element is KtConstantExpression) return null
if (element is KtStringTemplateExpression && element.isPlainWithEscapes()) return null if (element is KtStringTemplateExpression && element.isPlainWithEscapes()) return null
if (element is KtClassLiteralExpression) return null if (element is KtClassLiteralExpression) return null
if (element is KtCallableReferenceExpression) return null if (element is KtCallableReferenceExpression) return null
} }
return element 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<KtTypeReference>() == null -> true
element is KtTypeReference && element == (element.parent as? KtCallableDeclaration)?.receiverTypeReference -> true
else -> false
}
}
override fun getElementForDescription(element: PsiElement): PsiElement { override fun getElementForDescription(element: PsiElement): PsiElement {
return (element as? KtSimpleNameExpression)?.mainReference?.resolve() ?: element return (element as? KtSimpleNameExpression)?.mainReference?.resolve() ?: element
} }
@@ -21,6 +21,7 @@ import com.intellij.slicer.SliceAnalysisParams
import com.intellij.slicer.SliceUsage import com.intellij.slicer.SliceUsage
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor
import org.jetbrains.kotlin.psi.KtElement
import org.jetbrains.kotlin.psi.KtExpression import org.jetbrains.kotlin.psi.KtExpression
open class KotlinSliceUsage : SliceUsage { open class KotlinSliceUsage : SliceUsage {
@@ -58,10 +59,10 @@ open class KotlinSliceUsage : SliceUsage {
override fun canBeLeaf() = element != null && lambdaLevel == 0 override fun canBeLeaf() = element != null && lambdaLevel == 0
public override fun processUsagesFlownDownTo(element: PsiElement, uniqueProcessor: SliceUsageProcessor) { 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) { public override fun processUsagesFlownFromThe(element: PsiElement, uniqueProcessor: SliceUsageProcessor) {
OutflowSlicer(element as? KtExpression ?: return, uniqueProcessor, this).processChildren() OutflowSlicer(element as? KtElement ?: return, uniqueProcessor, this).processChildren()
} }
} }
@@ -12,33 +12,77 @@ import com.intellij.psi.impl.light.LightMemberReference
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue import org.jetbrains.kotlin.cfg.pseudocode.PseudoValue
import org.jetbrains.kotlin.cfg.pseudocode.instructions.Instruction 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.eval.*
import org.jetbrains.kotlin.cfg.pseudocode.instructions.jumps.ReturnValueInstruction 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.findUsages.handlers.SliceUsageProcessor
import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingElement import org.jetbrains.kotlin.idea.search.declarationsSearch.forEachOverridingElement
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector 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.*
import org.jetbrains.kotlin.psi.psiUtil.getNonStrictParentOfType import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.psi.psiUtil.getParentOfTypeAndBranch import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.psi.psiUtil.isAncestor
import org.jetbrains.kotlin.psi.psiUtil.parameterIndex
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
class OutflowSlicer( class OutflowSlicer(
element: KtExpression, element: KtElement,
processor: SliceUsageProcessor, processor: SliceUsageProcessor,
parentUsage: KotlinSliceUsage parentUsage: KotlinSliceUsage
) : Slicer(element, processor, parentUsage) { ) : Slicer(element, processor, parentUsage) {
override fun processChildren() { override fun processChildren() {
if (parentUsage.forcedExpressionMode) return processExpression(element) if (parentUsage.forcedExpressionMode) {
(element as? KtExpression)?.let { processExpression(it) }
return
}
when (element) { when (element) {
is KtProperty -> processVariable(element) is KtProperty -> processVariable(element)
is KtParameter -> processVariable(element) is KtParameter -> processVariable(element)
is KtFunction -> processFunction(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,11 +109,19 @@ class OutflowSlicer(
if (variable is KtParameter) { if (variable is KtParameter) {
if (!canProcessParameter(variable)) return //TODO if (!canProcessParameter(variable)) return //TODO
//TODO: expect/actual
val callable = variable.ownerFunction as? KtCallableDeclaration val callable = variable.ownerFunction as? KtCallableDeclaration
if (callable != null) {
if (callable.isExpectDeclaration()) {
variable.resolveToDescriptorIfAny(BodyResolveMode.FULL)
?.actualsForExpected()
?.forEach {
(it as? DeclarationDescriptorWithSource)?.originalSource?.getPsi()?.passToProcessor()
}
}
val parameterIndex = variable.parameterIndex() val parameterIndex = variable.parameterIndex()
callable?.forEachOverridingElement(scope = analysisScope) { _, overridingMember -> callable.forEachOverridingElement(scope = analysisScope) { _, overridingMember ->
when (overridingMember) { when (overridingMember) {
is KtCallableDeclaration -> { is KtCallableDeclaration -> {
val parameters = overridingMember.valueParameters val parameters = overridingMember.valueParameters
@@ -89,6 +141,7 @@ class OutflowSlicer(
true true
} }
} }
}
processVariableAccesses(variable, analysisScope, accessKind, ::processVariableAccess) processVariableAccesses(variable, analysisScope, accessKind, ::processVariableAccess)
} }
@@ -113,30 +166,80 @@ class OutflowSlicer(
is KtNamedFunction -> function is KtNamedFunction -> function
else -> null else -> null
} ?: return } ?: return
funExpression as PsiElement
funExpression.passToProcessor(parentUsage.lambdaLevel + 1, true) 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<KtThisExpression> { thisExpression ->
val receiverDescriptor = thisExpression.resolveToCall(resolutionFacade)?.resultingDescriptor
if (receiverDescriptor == extensionReceiver) {
thisExpression.passToProcessor()
}
}
}
private fun processExpression(expression: KtExpression) { private fun processExpression(expression: KtExpression) {
expression.processPseudocodeUsages { pseudoValue, instr -> expression.processPseudocodeUsages { pseudoValue, instruction ->
when (instr) { when (instruction) {
is WriteValueInstruction -> instr.target.accessedDescriptor?.originalSource?.getPsi()?.passToProcessor() is WriteValueInstruction -> {
if (!processIfReceiverValue(instruction, pseudoValue)) {
instruction.target.accessedDescriptor?.originalSource?.getPsi()?.passToProcessor()
}
}
is ReadValueInstruction -> {
processIfReceiverValue(instruction, pseudoValue)
}
is CallInstruction -> { is CallInstruction -> {
if (parentUsage.lambdaLevel > 0 && instr.receiverValues[pseudoValue] != null) { if (!processIfReceiverValue(instruction, pseudoValue)) {
instr.element.passToProcessor(parentUsage.lambdaLevel - 1) instruction.arguments[pseudoValue]?.originalSource?.getPsi()?.passToProcessor()
} else {
instr.arguments[pseudoValue]?.originalSource?.getPsi()?.passToProcessor()
} }
} }
is ReturnValueInstruction -> instr.subroutine.passToProcessor()
is MagicInstruction -> when (instr.kind) { is ReturnValueInstruction -> {
MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> instr.outputValue.element?.passToProcessor() instruction.subroutine.passToProcessor()
}
is MagicInstruction -> {
when (instruction.kind) {
MagicKind.NOT_NULL_ASSERTION, MagicKind.CAST -> instruction.outputValue.element?.passToProcessor()
else -> { 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? { private fun PsiElement.getCallElementForExactCallee(): PsiElement? {
if (this is KtArrayAccessExpression) return this if (this is KtArrayAccessExpression) return this
@@ -10,6 +10,7 @@ import com.intellij.psi.PsiMethod
import com.intellij.psi.search.SearchScope import com.intellij.psi.search.SearchScope
import com.intellij.slicer.JavaSliceUsage import com.intellij.slicer.JavaSliceUsage
import com.intellij.usageView.UsageInfo import com.intellij.usageView.UsageInfo
import com.intellij.util.containers.addIfNotNull
import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode import org.jetbrains.kotlin.cfg.pseudocode.Pseudocode
import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode import org.jetbrains.kotlin.cfg.pseudocode.containingDeclarationForPseudocode
import org.jetbrains.kotlin.cfg.pseudocode.getContainingPseudocode 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.DeclarationDescriptorWithSource
import org.jetbrains.kotlin.descriptors.SourceElement import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.idea.caches.resolve.analyzeWithContent 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.core.getDeepestSuperDeclarations
import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.KotlinFunctionFindUsagesOptions
import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions import org.jetbrains.kotlin.idea.findUsages.KotlinPropertyFindUsagesOptions
import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor import org.jetbrains.kotlin.idea.findUsages.handlers.SliceUsageProcessor
import org.jetbrains.kotlin.idea.findUsages.processAllExactUsages import org.jetbrains.kotlin.idea.findUsages.processAllExactUsages
import org.jetbrains.kotlin.idea.findUsages.processAllUsages import org.jetbrains.kotlin.idea.findUsages.processAllUsages
import org.jetbrains.kotlin.idea.util.expectedDescriptor
import org.jetbrains.kotlin.psi.* import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.contains
import org.jetbrains.kotlin.resolve.DescriptorUtils import org.jetbrains.kotlin.resolve.DescriptorUtils
import org.jetbrains.kotlin.resolve.lazy.BodyResolveMode
import org.jetbrains.kotlin.resolve.source.getPsi import org.jetbrains.kotlin.resolve.source.getPsi
import java.util.* import java.util.*
abstract class Slicer( abstract class Slicer(
protected val element: KtExpression, protected val element: KtElement,
protected val processor: SliceUsageProcessor, protected val processor: SliceUsageProcessor,
protected val parentUsage: KotlinSliceUsage protected val parentUsage: KotlinSliceUsage
) { ) {
@@ -62,22 +64,43 @@ abstract class Slicer(
} }
protected fun processCalls( protected fun processCalls(
function: KtFunction, callable: KtCallableDeclaration,
scope: SearchScope, scope: SearchScope,
includeOverriders: Boolean, includeOverriders: Boolean,
usageProcessor: (UsageInfo) -> Unit usageProcessor: (UsageInfo) -> Unit
) { ) {
val options = KotlinFunctionFindUsagesOptions(project).apply { val options = when (callable) {
is KtFunction -> {
KotlinFunctionFindUsagesOptions(project).apply {
isSearchForTextOccurrences = false isSearchForTextOccurrences = false
isSkipImportStatements = true isSkipImportStatements = true
searchScope = scope searchScope = scope
} }
}
val descriptor = function.unsafeResolveToDescriptor() as? CallableMemberDescriptor ?: return is KtProperty -> {
val superDescriptors = if (includeOverriders) KotlinPropertyFindUsagesOptions(project).apply {
isSearchForTextOccurrences = false
isSkipImportStatements = true
searchScope = scope
}
}
else -> return
}
val descriptor = callable.resolveToDescriptorIfAny(BodyResolveMode.FULL) as? CallableMemberDescriptor ?: return
val superDescriptors = if (includeOverriders) {
descriptor.getDeepestSuperDeclarations() descriptor.getDeepestSuperDeclarations()
else } else {
listOf(descriptor) + DescriptorUtils.getAllOverriddenDeclarations(descriptor) mutableListOf<CallableMemberDescriptor>().apply {
add(descriptor)
addAll(DescriptorUtils.getAllOverriddenDeclarations(descriptor))
if (descriptor.isActual) {
addIfNotNull(descriptor.expectedDescriptor() as CallableMemberDescriptor?)
}
}
}
for (superDescriptor in superDescriptors) { for (superDescriptor in superDescriptors) {
val declaration = superDescriptor.originalSource.getPsi() ?: continue val declaration = superDescriptor.originalSource.getPsi() ?: continue
@@ -123,11 +146,17 @@ abstract class Slicer(
} }
val allDeclarations = mutableListOf(declaration) val allDeclarations = mutableListOf(declaration)
val descriptor = declaration.unsafeResolveToDescriptor() val descriptor = declaration.resolveToDescriptorIfAny()
if (descriptor is CallableMemberDescriptor) { 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 it.originalSource.getPsi() as? KtCallableDeclaration
} }
} }
allDeclarations.forEach { it.processAllExactUsages(options, usageProcessor) } allDeclarations.forEach { it.processAllExactUsages(options, usageProcessor) }
@@ -0,0 +1,5 @@
class JavaClass {
void f() {
KotlinUtil.extensionFun("x");
}
}
+13
View File
@@ -0,0 +1,13 @@
// FLOW: IN
@file: JvmName("KotlinUtil")
import kotlin.jvm.JvmName
fun <caret>Any.extensionFun() {
}
fun foo() {
"".extensionFun()
1.extensionFun()
}
@@ -0,0 +1,12 @@
11 <bold>""</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() {
11 <bold>""</bold>.extensionFun()
3 KotlinUtil.extensionFun(<bold>"x"</bold>);
7 fun <bold>Any</bold>.extensionFun() {
3 KotlinUtil.extensionFun(<bold>"x"</bold>);
12 <bold>1</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() {
12 <bold>1</bold>.extensionFun()
@@ -0,0 +1,13 @@
[NotNull Values]
11 <bold>""</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() {
11 <bold>""</bold>.extensionFun()
12 <bold>1</bold>.extensionFun()
7 fun <bold>Any</bold>.extensionFun() {
12 <bold>1</bold>.extensionFun()
[Other Values]
3 KotlinUtil.extensionFun(<bold>"x"</bold>);
7 fun <bold>Any</bold>.extensionFun() {
3 KotlinUtil.extensionFun(<bold>"x"</bold>);
@@ -0,0 +1,4 @@
7 fun <bold>Any</bold>.extensionFun() {
3 KotlinUtil.extensionFun(<bold>"x"</bold>);
11 <bold>""</bold>.extensionFun()
12 <bold>1</bold>.extensionFun()
+10
View File
@@ -0,0 +1,10 @@
// FLOW: IN
var <caret>Any.property: Int
get() = 1
set(value) { }
fun foo() {
println("a".property)
"b".property = 2
}
@@ -0,0 +1,7 @@
9 <bold>"b"</bold>.property = 2
3 var <bold>Any</bold>.property: Int
9 <bold>"b"</bold>.property = 2
8 println(<bold>"a"</bold>.property)
3 var <bold>Any</bold>.property: Int
8 println(<bold>"a"</bold>.property)
@@ -0,0 +1,7 @@
[NotNull Values]
8 println(<bold>"a"</bold>.property)
3 var <bold>Any</bold>.property: Int
8 println(<bold>"a"</bold>.property)
9 <bold>"b"</bold>.property = 2
3 var <bold>Any</bold>.property: Int
9 <bold>"b"</bold>.property = 2
@@ -0,0 +1,3 @@
3 var <bold>Any</bold>.property: Int
8 println(<bold>"a"</bold>.property)
9 <bold>"b"</bold>.property = 2
+20
View File
@@ -0,0 +1,20 @@
// FLOW: IN
open class Base {
open fun Int.extensionFun() {
println(<caret>this)
}
fun baseF() {
1.extensionFun()
}
}
class Derived : Base() {
override fun Int.extensionFun() {
}
fun derivedF() {
2.extensionFun()
}
}
@@ -0,0 +1,4 @@
9 <bold>1</bold>.extensionFun()
5 println(<bold>this</bold>)
4 open fun <bold>Int</bold>.extensionFun() {
9 <bold>1</bold>.extensionFun()
@@ -0,0 +1,3 @@
[NotNull Values]
5 println(<bold>this</bold>)
5 println(<bold>this</bold>)
@@ -0,0 +1,3 @@
5 println(<bold>this</bold>)
4 open fun <bold>Int</bold>.extensionFun() {
9 <bold>1</bold>.extensionFun()
+20
View File
@@ -0,0 +1,20 @@
// FLOW: IN
open class Base {
open fun <caret>Int.extensionFun() {
println(this)
}
fun baseF() {
1.extensionFun()
}
}
class Derived : Base() {
override fun Int.extensionFun() {
}
fun derivedF() {
2.extensionFun()
}
}
@@ -0,0 +1,7 @@
9 <bold>1</bold>.extensionFun()
4 open fun <bold>Int</bold>.extensionFun() {
9 <bold>1</bold>.extensionFun()
18 <bold>2</bold>.extensionFun()
4 open fun <bold>Int</bold>.extensionFun() {
18 <bold>2</bold>.extensionFun()
@@ -0,0 +1,7 @@
[NotNull Values]
9 <bold>1</bold>.extensionFun()
4 open fun <bold>Int</bold>.extensionFun() {
9 <bold>1</bold>.extensionFun()
18 <bold>2</bold>.extensionFun()
4 open fun <bold>Int</bold>.extensionFun() {
18 <bold>2</bold>.extensionFun()
@@ -0,0 +1,3 @@
4 open fun <bold>Int</bold>.extensionFun() {
9 <bold>1</bold>.extensionFun()
18 <bold>2</bold>.extensionFun()
@@ -0,0 +1,9 @@
// FLOW: IN
fun Any.extensionFun(): Any {
return this
}
fun foo() {
val <caret>x = "".extensionFun()
}
@@ -0,0 +1,8 @@
8 val x = <bold>""</bold>.extensionFun()
8 val <bold>x = "".extensionFun()</bold>
8 val x = <bold>"".extensionFun()</bold>
3 fun Any.<bold>extensionFun(): Any {</bold>
4 return <bold>this</bold>
3 fun <bold>Any</bold>.extensionFun(): Any {
8 val x = <bold>""</bold>.extensionFun()
@@ -0,0 +1,3 @@
[NotNull Values]
8 val <bold>x = "".extensionFun()</bold>
8 val <bold>x = "".extensionFun()</bold>
@@ -0,0 +1,6 @@
8 val <bold>x = "".extensionFun()</bold>
8 val x = <bold>"".extensionFun()</bold>
3 fun Any.<bold>extensionFun(): Any {</bold>
4 return <bold>this</bold>
3 fun <bold>Any</bold>.extensionFun(): Any {
8 val x = <bold>""</bold>.extensionFun()
@@ -0,0 +1,8 @@
// FLOW: IN
val Any.extensionProp: Any
get() = this
fun foo() {
val <caret>x = "".extensionProp
}
@@ -0,0 +1,8 @@
7 val x = <bold>""</bold>.extensionProp
7 val <bold>x = "".extensionProp</bold>
7 val x = <bold>"".extensionProp</bold>
3 val Any.<bold>extensionProp: Any</bold>
4 get() = <bold>this</bold>
3 val <bold>Any</bold>.extensionProp: Any
7 val x = <bold>""</bold>.extensionProp
@@ -0,0 +1,3 @@
[NotNull Values]
7 val <bold>x = "".extensionProp</bold>
7 val <bold>x = "".extensionProp</bold>
@@ -0,0 +1,6 @@
7 val <bold>x = "".extensionProp</bold>
7 val x = <bold>"".extensionProp</bold>
3 val Any.<bold>extensionProp: Any</bold>
4 get() = <bold>this</bold>
3 val <bold>Any</bold>.extensionProp: Any
7 val x = <bold>""</bold>.extensionProp
@@ -0,0 +1,9 @@
package sample
expect class ExpectClass() {
fun foo(p: Any)
}
fun f(c: ExpectClass) {
c.foo(1)
}
@@ -0,0 +1,9 @@
// FLOW: IN
package sample
actual class ExpectClass {
actual fun foo(p: Any) {
println(<caret>p)
}
}
@@ -0,0 +1,3 @@
7 println(<bold>p</bold>)
6 actual fun foo(<bold>p: Any</bold>) {
8 c.foo(<bold>1</bold>)
@@ -0,0 +1,5 @@
expect fun foo(p: Any)
fun bar() {
foo(1)
}
@@ -0,0 +1,5 @@
// FLOW: IN
actual fun foo(p: Any) {
println(<caret>p)
}
@@ -0,0 +1,3 @@
4 println(<bold>p</bold>)
3 actual fun foo(<bold>p: Any</bold>) {
4 foo(<bold>1</bold>)
@@ -0,0 +1,11 @@
// FLOW: OUT
package sample
expect class ExpectClass() {
fun foo(p: Any)
}
fun f(c: ExpectClass) {
c.foo(<caret>1)
}
@@ -0,0 +1,7 @@
package sample
actual class ExpectClass {
actual fun foo(p: Any) {
println(p)
}
}
@@ -0,0 +1,4 @@
10 c.foo(<bold>1</bold>)
6 fun foo(<bold>p: Any</bold>)
4 actual fun foo(<bold>p: Any</bold>) {
5 println(<bold>p</bold>)
@@ -0,0 +1,8 @@
// FLOW: OUT
expect fun Any.foo(): Any
fun bar() {
val result = <caret>1.foo()
println(result)
}
@@ -0,0 +1,3 @@
actual fun Any.foo(): Any {
return this
}
@@ -0,0 +1,8 @@
6 val result = <bold>1</bold>.foo()
3 expect fun <bold>Any</bold>.foo(): Any
1 actual fun <bold>Any</bold>.foo(): Any {
2 return <bold>this</bold>
1 actual fun Any.<bold>foo(): Any {</bold>
6 val result = 1.<bold>foo()</bold>
6 val <bold>result = 1.foo()</bold>
7 println(<bold>result</bold>)
@@ -0,0 +1,7 @@
// FLOW: OUT
expect fun foo(p: Any)
fun bar() {
foo(<caret>1)
}
@@ -0,0 +1,3 @@
actual fun foo(p: Any) {
println(p)
}
@@ -0,0 +1,4 @@
6 foo(<bold>1</bold>)
3 expect fun foo(<bold>p: Any</bold>)
1 actual fun foo(<bold>p: Any</bold>) {
2 println(<bold>p</bold>)
@@ -0,0 +1,8 @@
// FLOW: IN
expect fun foo(p: Any): Any
fun bar() {
val result = foo(1)
println(<caret>result)
}
@@ -0,0 +1,3 @@
actual fun foo(p: Any): Any {
return p
}
@@ -0,0 +1,8 @@
7 println(<bold>result</bold>)
6 val <bold>result = foo(1)</bold>
6 val result = <bold>foo(1)</bold>
1 actual fun <bold>foo(p: Any): Any {</bold>
2 return <bold>p</bold>
1 actual fun foo(<bold>p: Any</bold>): Any {
6 val result = foo(<bold>1</bold>)
3 expect fun <bold>foo(p: Any): Any</bold>
@@ -0,0 +1,8 @@
// FLOW: OUT
expect fun foo(p: Any): Any
fun bar() {
val result = foo(<caret>1)
println(result)
}
@@ -0,0 +1,3 @@
actual fun foo(p: Any): Any {
return p
}
@@ -0,0 +1,8 @@
6 val result = foo(<bold>1</bold>)
3 expect fun foo(<bold>p: Any</bold>): Any
1 actual fun foo(<bold>p: Any</bold>): Any {
2 return <bold>p</bold>
1 actual fun <bold>foo(p: Any): Any {</bold>
6 val result = <bold>foo(1)</bold>
6 val <bold>result = foo(1)</bold>
7 println(<bold>result</bold>)
@@ -0,0 +1,8 @@
// FLOW: IN
expect val Int.property: Any
fun bar() {
val result = 1.property
println(<caret>result)
}
@@ -0,0 +1,2 @@
actual val Int.property: Any
get() = this
@@ -0,0 +1,8 @@
7 println(<bold>result</bold>)
6 val <bold>result = 1.property</bold>
6 val result = <bold>1.property</bold>
1 actual val Int.<bold>property: Any</bold>
2 get() = <bold>this</bold>
1 actual val <bold>Int</bold>.property: Any
6 val result = <bold>1</bold>.property
3 expect val Int.<bold>property: Any</bold>
@@ -0,0 +1,8 @@
// FLOW: OUT
expect val Int.property: Any
fun bar() {
val result = <caret>1.property
println(result)
}
@@ -0,0 +1,2 @@
actual val Int.property: Any
get() = this
@@ -0,0 +1,8 @@
6 val result = <bold>1</bold>.property
3 expect val <bold>Int</bold>.property: Any
1 actual val <bold>Int</bold>.property: Any
2 get() = <bold>this</bold>
2 <bold>get() = this</bold>
6 val result = 1.<bold>property</bold>
6 val <bold>result = 1.property</bold>
7 println(<bold>result</bold>)
@@ -5,5 +5,18 @@
22 DEREFERENCE: <bold>x</bold> += 1 22 DEREFERENCE: <bold>x</bold> += 1
23 DEREFERENCE: <bold>x</bold> *= 1 23 DEREFERENCE: <bold>x</bold> *= 1
25 -<bold>x</bold> 25 -<bold>x</bold>
12 operator fun <bold>A</bold>.unaryMinus() = this
12 operator fun A.unaryMinus() = <bold>this</bold>
12 operator fun A.<bold>unaryMinus() = this</bold>
25 <bold>-x</bold>
26 <bold>x</bold> - 1 26 <bold>x</bold> - 1
11 operator fun <bold>A</bold>.minus(n: Int) = this
11 operator fun A.minus(n: Int) = <bold>this</bold>
11 operator fun A.<bold>minus(n: Int) = this</bold>
26 <bold>x - 1</bold>
28 <bold>x -= 1</bold>
17 DUPLICATE: var <bold>x = A()</bold>
29 <bold>x</bold> /= 1 29 <bold>x</bold> /= 1
14 operator fun <bold>A</bold>.divAssign(n: Int) = this
14 operator fun A.divAssign(n: Int) = <bold>this</bold>
14 operator fun A.<bold>divAssign(n: Int) = this</bold>
@@ -2,10 +2,14 @@
15 DEREFERENCE: <bold>x</bold>.foo() 15 DEREFERENCE: <bold>x</bold>.foo()
16 DEREFERENCE: <bold>x</bold>.bar 16 DEREFERENCE: <bold>x</bold>.bar
17 <bold>x</bold>.fooExt() 17 <bold>x</bold>.fooExt()
9 fun <bold>A</bold>.fooExt() = 1
18 <bold>x</bold>.barExt 18 <bold>x</bold>.barExt
10 val <bold>A</bold>.barExt: Int get() = 2
20 val y: A? = <bold>x</bold> 20 val y: A? = <bold>x</bold>
20 val <bold>y: A? = x</bold> 20 val <bold>y: A? = x</bold>
22 DEREFERENCE: <bold>y</bold>?.foo() 22 DEREFERENCE: <bold>y</bold>?.foo()
23 DEREFERENCE: <bold>y</bold>?.bar 23 DEREFERENCE: <bold>y</bold>?.bar
24 <bold>y</bold>?.fooExt() 24 <bold>y</bold>?.fooExt()
9 DUPLICATE: fun <bold>A</bold>.fooExt() = 1
25 <bold>y</bold>?.barExt 25 <bold>y</bold>?.barExt
10 DUPLICATE: val <bold>A</bold>.barExt: Int get() = 2
@@ -0,0 +1,7 @@
// FLOW: OUT
fun String.extensionFun(): Any = this
fun foo() {
val x = <caret>"".extensionFun()
}
@@ -0,0 +1,6 @@
6 val x = <bold>""</bold>.extensionFun()
3 fun <bold>String</bold>.extensionFun(): Any = this
3 fun String.extensionFun(): Any = <bold>this</bold>
3 fun String.<bold>extensionFun(): Any = this</bold>
6 val x = "".<bold>extensionFun()</bold>
6 val <bold>x = "".extensionFun()</bold>
@@ -0,0 +1,8 @@
// FLOW: OUT
val String.extensionProp: Any
get() = this
fun foo() {
val x = <caret>"".extensionProp
}
@@ -0,0 +1,6 @@
7 val x = <bold>""</bold>.extensionProp
3 val <bold>String</bold>.extensionProp: Any
4 get() = <bold>this</bold>
4 <bold>get() = this</bold>
7 val x = "".<bold>extensionProp</bold>
7 val <bold>x = "".extensionProp</bold>
+19
View File
@@ -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 = <caret>"".extensionFun()
}
}
inline fun <T, R> with(receiver: T, block: T.() -> R): R {
return receiver.block()
}
+3
View File
@@ -0,0 +1,3 @@
13 val x = <bold>""</bold>.extensionFun()
4 fun <bold>String</bold>.extensionFun(): Any {
7 println(<bold>this@extensionFun</bold>.length)
@@ -11,7 +11,7 @@ import java.io.File
abstract class AbstractSlicerLeafGroupingTest : AbstractSlicerTest() { abstract class AbstractSlicerLeafGroupingTest : AbstractSlicerTest() {
override fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) { override fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) {
val treeStructure = SliceTreeStructure(rootNode) val treeStructure = TestSliceTreeStructure(rootNode)
val analyzer = sliceProvider.leafAnalyzer val analyzer = sliceProvider.leafAnalyzer
val possibleElementsByNode = analyzer.createMap() val possibleElementsByNode = analyzer.createMap()
val leafExpressions = analyzer.calcLeafExpressions(rootNode, treeStructure, possibleElementsByNode) val leafExpressions = analyzer.calcLeafExpressions(rootNode, treeStructure, possibleElementsByNode)
@@ -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, "<caret>")
testSliceFromOffset(file, offset) { _, rootNode ->
KotlinTestUtils.assertEqualsToFile(testRoot.resolve("results.txt"), buildTreeRepresentation(rootNode))
}
}
}
@@ -12,7 +12,7 @@ import java.io.File
abstract class AbstractSlicerNullnessGroupingTest : AbstractSlicerTest() { abstract class AbstractSlicerNullnessGroupingTest : AbstractSlicerTest() {
override fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) { override fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) {
val treeStructure = SliceTreeStructure(rootNode) val treeStructure = TestSliceTreeStructure(rootNode)
val analyzer = sliceProvider.nullnessAnalyzer val analyzer = sliceProvider.nullnessAnalyzer
val nullnessByNode = SliceNullnessAnalyzerBase.createMap() val nullnessByNode = SliceNullnessAnalyzerBase.createMap()
val nullness = analyzer.calcNullableLeaves(rootNode, treeStructure, nullnessByNode) val nullness = analyzer.calcNullableLeaves(rootNode, treeStructure, nullnessByNode)
@@ -5,96 +5,15 @@
package org.jetbrains.kotlin.idea.slicer 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.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.slicer.SliceRootNode
import com.intellij.usages.TextChunk
import com.intellij.util.PathUtil import com.intellij.util.PathUtil
import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase import org.jetbrains.kotlin.idea.test.KotlinLightCodeInsightFixtureTestCase
import org.jetbrains.kotlin.psi.KtFile 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 org.jetbrains.kotlin.test.KotlinTestUtils
import java.awt.Font
import java.io.File import java.io.File
abstract class AbstractSlicerTest : KotlinLightCodeInsightFixtureTestCase() { abstract class AbstractSlicerTest : KotlinLightCodeInsightFixtureTestCase() {
protected class SliceTreeStructure(private val rootNode: SliceNode) : AbstractTreeStructureBase(rootNode.project) {
override fun getProviders(): List<TreeStructureProvider>? = emptyList()
override fun getRootElement() = rootNode
override fun commit() {
}
override fun hasSomethingToCommit() = false
}
companion object {
private val SliceNode.sortedChildren: List<SliceNode>
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 = "<bold>$text</bold>"
}
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("</bold><bold>"), "")
}
return process(rootNode, 0)
}
}
protected abstract fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode) protected abstract fun doTest(path: String, sliceProvider: KotlinSliceProvider, rootNode: SliceRootNode)
protected fun doTest(path: String) { protected fun doTest(path: String) {
@@ -104,30 +23,15 @@ abstract class AbstractSlicerTest : KotlinLightCodeInsightFixtureTestCase() {
val namePrefix = FileUtil.getNameWithoutExtension(mainFile) val namePrefix = FileUtil.getNameWithoutExtension(mainFile)
val extraFiles = rootDir.listFiles { _, name -> val extraFiles = rootDir.listFiles { _, name ->
name.startsWith("$namePrefix.") && PathUtil.getFileExtension(name).let { it == "kt" || it == "java" } name.startsWith("$namePrefix.") && PathUtil.getFileExtension(name).let { it == "kt" || it == "java" }
} }!!
myFixture.testDataPath = "${KotlinTestUtils.getHomeDirectory()}/${rootDir.path}" 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) } extraFiles.forEach { myFixture.configureByFile(it.name) }
val file = myFixture.configureByFile(mainFile.name) as KtFile val file = myFixture.configureByFile(mainFile.name) as KtFile
val elementAtCaret = file.findElementAt(editor.caretModel.offset)!!
val sliceProvider = KotlinSliceProvider() testSliceFromOffset(file, editor.caretModel.offset) { sliceProvider, rootNode ->
val expression = sliceProvider.getExpressionAtCaret(elementAtCaret, analysisParams.dataFlowToThis)!!
val rootUsage = sliceProvider.createRootUsage(expression, analysisParams)
val rootNode = SliceRootNode(project, DuplicateMap(), rootUsage)
doTest(path, sliceProvider, rootNode) doTest(path, sliceProvider, rootNode)
} }
} }
}
@@ -228,6 +228,16 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT
runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); 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") @TestMetadata("openFun.kt")
public void testOpenFun() throws Exception { public void testOpenFun() throws Exception {
runTest("idea/testData/slicer/inflow/openFun.kt"); runTest("idea/testData/slicer/inflow/openFun.kt");
@@ -238,6 +248,16 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT
runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); 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") @TestMetadata("overrideFun.kt")
public void testOverrideFun() throws Exception { public void testOverrideFun() throws Exception {
runTest("idea/testData/slicer/inflow/overrideFun.kt"); runTest("idea/testData/slicer/inflow/overrideFun.kt");
@@ -323,6 +343,16 @@ public class SlicerLeafGroupingTestGenerated extends AbstractSlicerLeafGroupingT
runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); 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") @TestMetadata("topLevelVal.kt")
public void testTopLevelVal() throws Exception { public void testTopLevelVal() throws Exception {
runTest("idea/testData/slicer/inflow/topLevelVal.kt"); runTest("idea/testData/slicer/inflow/topLevelVal.kt");
@@ -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/");
}
}
@@ -228,6 +228,16 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG
runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); 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") @TestMetadata("openFun.kt")
public void testOpenFun() throws Exception { public void testOpenFun() throws Exception {
runTest("idea/testData/slicer/inflow/openFun.kt"); runTest("idea/testData/slicer/inflow/openFun.kt");
@@ -238,6 +248,16 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG
runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); 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") @TestMetadata("overrideFun.kt")
public void testOverrideFun() throws Exception { public void testOverrideFun() throws Exception {
runTest("idea/testData/slicer/inflow/overrideFun.kt"); runTest("idea/testData/slicer/inflow/overrideFun.kt");
@@ -323,6 +343,16 @@ public class SlicerNullnessGroupingTestGenerated extends AbstractSlicerNullnessG
runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); 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") @TestMetadata("topLevelVal.kt")
public void testTopLevelVal() throws Exception { public void testTopLevelVal() throws Exception {
runTest("idea/testData/slicer/inflow/topLevelVal.kt"); runTest("idea/testData/slicer/inflow/topLevelVal.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<TreeStructureProvider>()
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 = "<bold>$text</bold>"
}
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("</bold><bold>"), "")
}
return process(rootNode, 0)
}
private val SliceNode.sortedChildren: List<SliceNode>
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)
}
@@ -25,616 +25,687 @@ public class SlicerTreeTestGenerated extends AbstractSlicerTreeTest {
} }
public void testAllFilesPresentInSlicer() throws Exception { public void testAllFilesPresentInSlicer() throws Exception {
KotlinTestUtils.assertAllTestsPresentInSingleGeneratedClassWithExcluded(this.getClass(), new File("idea/testData/slicer"), Pattern.compile("^(.+)\\.kt$"), null); KotlinTestUtils.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("idea/testData/slicer"), Pattern.compile("^(.+)\\.kt$"), null, true, "mpp");
} }
@TestMetadata("inflow/abstractFun.kt") @TestMetadata("idea/testData/slicer/inflow")
public void testInflow_AbstractFun() throws Exception { @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"); runTest("idea/testData/slicer/inflow/abstractFun.kt");
} }
@TestMetadata("inflow/anonymousFunBodyExpression.kt") public void testAllFilesPresentInInflow() throws Exception {
public void testInflow_AnonymousFunBodyExpression() 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"); runTest("idea/testData/slicer/inflow/anonymousFunBodyExpression.kt");
} }
@TestMetadata("inflow/anonymousFunReturnExpression.kt") @TestMetadata("anonymousFunReturnExpression.kt")
public void testInflow_AnonymousFunReturnExpression() throws Exception { public void testAnonymousFunReturnExpression() throws Exception {
runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt"); runTest("idea/testData/slicer/inflow/anonymousFunReturnExpression.kt");
} }
@TestMetadata("inflow/cast.kt") @TestMetadata("cast.kt")
public void testInflow_Cast() throws Exception { public void testCast() throws Exception {
runTest("idea/testData/slicer/inflow/cast.kt"); runTest("idea/testData/slicer/inflow/cast.kt");
} }
@TestMetadata("inflow/compositeAssignments.kt") @TestMetadata("compositeAssignments.kt")
public void testInflow_CompositeAssignments() throws Exception { public void testCompositeAssignments() throws Exception {
runTest("idea/testData/slicer/inflow/compositeAssignments.kt"); runTest("idea/testData/slicer/inflow/compositeAssignments.kt");
} }
@TestMetadata("inflow/defaultGetterFieldInSetter.kt") @TestMetadata("defaultGetterFieldInSetter.kt")
public void testInflow_DefaultGetterFieldInSetter() throws Exception { public void testDefaultGetterFieldInSetter() throws Exception {
runTest("idea/testData/slicer/inflow/defaultGetterFieldInSetter.kt"); runTest("idea/testData/slicer/inflow/defaultGetterFieldInSetter.kt");
} }
@TestMetadata("inflow/delegateGetter.kt") @TestMetadata("delegateGetter.kt")
public void testInflow_DelegateGetter() throws Exception { public void testDelegateGetter() throws Exception {
runTest("idea/testData/slicer/inflow/delegateGetter.kt"); runTest("idea/testData/slicer/inflow/delegateGetter.kt");
} }
@TestMetadata("inflow/delegateToJavaGetter.kt") @TestMetadata("delegateToJavaGetter.kt")
public void testInflow_DelegateToJavaGetter() throws Exception { public void testDelegateToJavaGetter() throws Exception {
runTest("idea/testData/slicer/inflow/delegateToJavaGetter.kt"); runTest("idea/testData/slicer/inflow/delegateToJavaGetter.kt");
} }
@TestMetadata("inflow/diamondHierarchyJKMiddleClassFun.kt") @TestMetadata("diamondHierarchyJKMiddleClassFun.kt")
public void testInflow_DiamondHierarchyJKMiddleClassFun() throws Exception { public void testDiamondHierarchyJKMiddleClassFun() throws Exception {
runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleClassFun.kt"); runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleClassFun.kt");
} }
@TestMetadata("inflow/diamondHierarchyJKMiddleInterfaceFun.kt") @TestMetadata("diamondHierarchyJKMiddleInterfaceFun.kt")
public void testInflow_DiamondHierarchyJKMiddleInterfaceFun() throws Exception { public void testDiamondHierarchyJKMiddleInterfaceFun() throws Exception {
runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleInterfaceFun.kt"); runTest("idea/testData/slicer/inflow/diamondHierarchyJKMiddleInterfaceFun.kt");
} }
@TestMetadata("inflow/diamondHierarchyJKRootInterfaceFun.kt") @TestMetadata("diamondHierarchyJKRootInterfaceFun.kt")
public void testInflow_DiamondHierarchyJKRootInterfaceFun() throws Exception { public void testDiamondHierarchyJKRootInterfaceFun() throws Exception {
runTest("idea/testData/slicer/inflow/diamondHierarchyJKRootInterfaceFun.kt"); runTest("idea/testData/slicer/inflow/diamondHierarchyJKRootInterfaceFun.kt");
} }
@TestMetadata("inflow/diamondHierarchyMiddleClassFun.kt") @TestMetadata("diamondHierarchyMiddleClassFun.kt")
public void testInflow_DiamondHierarchyMiddleClassFun() throws Exception { public void testDiamondHierarchyMiddleClassFun() throws Exception {
runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleClassFun.kt"); runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleClassFun.kt");
} }
@TestMetadata("inflow/diamondHierarchyMiddleInterfaceFun.kt") @TestMetadata("diamondHierarchyMiddleInterfaceFun.kt")
public void testInflow_DiamondHierarchyMiddleInterfaceFun() throws Exception { public void testDiamondHierarchyMiddleInterfaceFun() throws Exception {
runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleInterfaceFun.kt"); runTest("idea/testData/slicer/inflow/diamondHierarchyMiddleInterfaceFun.kt");
} }
@TestMetadata("inflow/diamondHierarchyRootInterfaceFun.kt") @TestMetadata("diamondHierarchyRootInterfaceFun.kt")
public void testInflow_DiamondHierarchyRootInterfaceFun() throws Exception { public void testDiamondHierarchyRootInterfaceFun() throws Exception {
runTest("idea/testData/slicer/inflow/diamondHierarchyRootInterfaceFun.kt"); runTest("idea/testData/slicer/inflow/diamondHierarchyRootInterfaceFun.kt");
} }
@TestMetadata("inflow/doubleLambdaResult.kt") @TestMetadata("doubleLambdaResult.kt")
public void testInflow_DoubleLambdaResult() throws Exception { public void testDoubleLambdaResult() throws Exception {
runTest("idea/testData/slicer/inflow/doubleLambdaResult.kt"); runTest("idea/testData/slicer/inflow/doubleLambdaResult.kt");
} }
@TestMetadata("inflow/funParamerer.kt") @TestMetadata("funParamerer.kt")
public void testInflow_FunParamerer() throws Exception { public void testFunParamerer() throws Exception {
runTest("idea/testData/slicer/inflow/funParamerer.kt"); runTest("idea/testData/slicer/inflow/funParamerer.kt");
} }
@TestMetadata("inflow/funParamererWithDefault.kt") @TestMetadata("funParamererWithDefault.kt")
public void testInflow_FunParamererWithDefault() throws Exception { public void testFunParamererWithDefault() throws Exception {
runTest("idea/testData/slicer/inflow/funParamererWithDefault.kt"); runTest("idea/testData/slicer/inflow/funParamererWithDefault.kt");
} }
@TestMetadata("inflow/funResultViaCallableRef.kt") @TestMetadata("funResultViaCallableRef.kt")
public void testInflow_FunResultViaCallableRef() throws Exception { public void testFunResultViaCallableRef() throws Exception {
runTest("idea/testData/slicer/inflow/funResultViaCallableRef.kt"); runTest("idea/testData/slicer/inflow/funResultViaCallableRef.kt");
} }
@TestMetadata("inflow/funResultViaCallableRefWithAssignment.kt") @TestMetadata("funResultViaCallableRefWithAssignment.kt")
public void testInflow_FunResultViaCallableRefWithAssignment() throws Exception { public void testFunResultViaCallableRefWithAssignment() throws Exception {
runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithAssignment.kt"); runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithAssignment.kt");
} }
@TestMetadata("inflow/funResultViaCallableRefWithDirectCall.kt") @TestMetadata("funResultViaCallableRefWithDirectCall.kt")
public void testInflow_FunResultViaCallableRefWithDirectCall() throws Exception { public void testFunResultViaCallableRefWithDirectCall() throws Exception {
runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithDirectCall.kt"); runTest("idea/testData/slicer/inflow/funResultViaCallableRefWithDirectCall.kt");
} }
@TestMetadata("inflow/funWithExpressionBody.kt") @TestMetadata("funWithExpressionBody.kt")
public void testInflow_FunWithExpressionBody() throws Exception { public void testFunWithExpressionBody() throws Exception {
runTest("idea/testData/slicer/inflow/funWithExpressionBody.kt"); runTest("idea/testData/slicer/inflow/funWithExpressionBody.kt");
} }
@TestMetadata("inflow/funWithReturnExpressions.kt") @TestMetadata("funWithReturnExpressions.kt")
public void testInflow_FunWithReturnExpressions() throws Exception { public void testFunWithReturnExpressions() throws Exception {
runTest("idea/testData/slicer/inflow/funWithReturnExpressions.kt"); runTest("idea/testData/slicer/inflow/funWithReturnExpressions.kt");
} }
@TestMetadata("inflow/getterAndSetterUsingField.kt") @TestMetadata("getterAndSetterUsingField.kt")
public void testInflow_GetterAndSetterUsingField() throws Exception { public void testGetterAndSetterUsingField() throws Exception {
runTest("idea/testData/slicer/inflow/getterAndSetterUsingField.kt"); runTest("idea/testData/slicer/inflow/getterAndSetterUsingField.kt");
} }
@TestMetadata("inflow/getterExpressionBody.kt") @TestMetadata("getterExpressionBody.kt")
public void testInflow_GetterExpressionBody() throws Exception { public void testGetterExpressionBody() throws Exception {
runTest("idea/testData/slicer/inflow/getterExpressionBody.kt"); runTest("idea/testData/slicer/inflow/getterExpressionBody.kt");
} }
@TestMetadata("inflow/getterReturnExpression.kt") @TestMetadata("getterReturnExpression.kt")
public void testInflow_GetterReturnExpression() throws Exception { public void testGetterReturnExpression() throws Exception {
runTest("idea/testData/slicer/inflow/getterReturnExpression.kt"); runTest("idea/testData/slicer/inflow/getterReturnExpression.kt");
} }
@TestMetadata("inflow/ifExpression.kt") @TestMetadata("ifExpression.kt")
public void testInflow_IfExpression() throws Exception { public void testIfExpression() throws Exception {
runTest("idea/testData/slicer/inflow/ifExpression.kt"); runTest("idea/testData/slicer/inflow/ifExpression.kt");
} }
@TestMetadata("inflow/lambdaResult.kt") @TestMetadata("lambdaResult.kt")
public void testInflow_LambdaResult() throws Exception { public void testLambdaResult() throws Exception {
runTest("idea/testData/slicer/inflow/lambdaResult.kt"); runTest("idea/testData/slicer/inflow/lambdaResult.kt");
} }
@TestMetadata("inflow/lambdaResultWithAssignments.kt") @TestMetadata("lambdaResultWithAssignments.kt")
public void testInflow_LambdaResultWithAssignments() throws Exception { public void testLambdaResultWithAssignments() throws Exception {
runTest("idea/testData/slicer/inflow/lambdaResultWithAssignments.kt"); runTest("idea/testData/slicer/inflow/lambdaResultWithAssignments.kt");
} }
@TestMetadata("inflow/lambdaResultWithDirectCall.kt") @TestMetadata("lambdaResultWithDirectCall.kt")
public void testInflow_LambdaResultWithDirectCall() throws Exception { public void testLambdaResultWithDirectCall() throws Exception {
runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCall.kt"); runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCall.kt");
} }
@TestMetadata("inflow/lambdaResultWithDirectCallViaAssignment.kt") @TestMetadata("lambdaResultWithDirectCallViaAssignment.kt")
public void testInflow_LambdaResultWithDirectCallViaAssignment() throws Exception { public void testLambdaResultWithDirectCallViaAssignment() throws Exception {
runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCallViaAssignment.kt"); runTest("idea/testData/slicer/inflow/lambdaResultWithDirectCallViaAssignment.kt");
} }
@TestMetadata("inflow/localVal.kt") @TestMetadata("localVal.kt")
public void testInflow_LocalVal() throws Exception { public void testLocalVal() throws Exception {
runTest("idea/testData/slicer/inflow/localVal.kt"); runTest("idea/testData/slicer/inflow/localVal.kt");
} }
@TestMetadata("inflow/localVar.kt") @TestMetadata("localVar.kt")
public void testInflow_LocalVar() throws Exception { public void testLocalVar() throws Exception {
runTest("idea/testData/slicer/inflow/localVar.kt"); runTest("idea/testData/slicer/inflow/localVar.kt");
} }
@TestMetadata("inflow/memberValWithInitializer.kt") @TestMetadata("memberValWithInitializer.kt")
public void testInflow_MemberValWithInitializer() throws Exception { public void testMemberValWithInitializer() throws Exception {
runTest("idea/testData/slicer/inflow/memberValWithInitializer.kt"); runTest("idea/testData/slicer/inflow/memberValWithInitializer.kt");
} }
@TestMetadata("inflow/memberValWithSplitInitializer.kt") @TestMetadata("memberValWithSplitInitializer.kt")
public void testInflow_MemberValWithSplitInitializer() throws Exception { public void testMemberValWithSplitInitializer() throws Exception {
runTest("idea/testData/slicer/inflow/memberValWithSplitInitializer.kt"); runTest("idea/testData/slicer/inflow/memberValWithSplitInitializer.kt");
} }
@TestMetadata("inflow/memberVarWithInitializer.kt") @TestMetadata("memberVarWithInitializer.kt")
public void testInflow_MemberVarWithInitializer() throws Exception { public void testMemberVarWithInitializer() throws Exception {
runTest("idea/testData/slicer/inflow/memberVarWithInitializer.kt"); runTest("idea/testData/slicer/inflow/memberVarWithInitializer.kt");
} }
@TestMetadata("inflow/memberVarWithSplitInitializer.kt") @TestMetadata("memberVarWithSplitInitializer.kt")
public void testInflow_MemberVarWithSplitInitializer() throws Exception { public void testMemberVarWithSplitInitializer() throws Exception {
runTest("idea/testData/slicer/inflow/memberVarWithSplitInitializer.kt"); runTest("idea/testData/slicer/inflow/memberVarWithSplitInitializer.kt");
} }
@TestMetadata("inflow/noFieldInGetter.kt") @TestMetadata("noFieldInGetter.kt")
public void testInflow_NoFieldInGetter() throws Exception { public void testNoFieldInGetter() throws Exception {
runTest("idea/testData/slicer/inflow/noFieldInGetter.kt"); runTest("idea/testData/slicer/inflow/noFieldInGetter.kt");
} }
@TestMetadata("inflow/nonLocalReturn.kt") @TestMetadata("nonLocalReturn.kt")
public void testInflow_NonLocalReturn() throws Exception { public void testNonLocalReturn() throws Exception {
runTest("idea/testData/slicer/inflow/nonLocalReturn.kt"); runTest("idea/testData/slicer/inflow/nonLocalReturn.kt");
} }
@TestMetadata("inflow/notNullAssertion.kt") @TestMetadata("notNullAssertion.kt")
public void testInflow_NotNullAssertion() throws Exception { public void testNotNullAssertion() throws Exception {
runTest("idea/testData/slicer/inflow/notNullAssertion.kt"); runTest("idea/testData/slicer/inflow/notNullAssertion.kt");
} }
@TestMetadata("inflow/nullsAndNotNulls.kt") @TestMetadata("nullsAndNotNulls.kt")
public void testInflow_NullsAndNotNulls() throws Exception { public void testNullsAndNotNulls() throws Exception {
runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt"); runTest("idea/testData/slicer/inflow/nullsAndNotNulls.kt");
} }
@TestMetadata("inflow/openFun.kt") @TestMetadata("onFunctionReceiverType.kt")
public void testInflow_OpenFun() throws Exception { 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"); runTest("idea/testData/slicer/inflow/openFun.kt");
} }
@TestMetadata("inflow/openFunInvokeOnParameter.kt") @TestMetadata("openFunInvokeOnParameter.kt")
public void testInflow_OpenFunInvokeOnParameter() throws Exception { public void testOpenFunInvokeOnParameter() throws Exception {
runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt"); runTest("idea/testData/slicer/inflow/openFunInvokeOnParameter.kt");
} }
@TestMetadata("inflow/overrideFun.kt") @TestMetadata("overrideExtension1.kt")
public void testInflow_OverrideFun() throws Exception { 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"); runTest("idea/testData/slicer/inflow/overrideFun.kt");
} }
@TestMetadata("inflow/overrideProperty.kt") @TestMetadata("overrideProperty.kt")
public void testInflow_OverrideProperty() throws Exception { public void testOverrideProperty() throws Exception {
runTest("idea/testData/slicer/inflow/overrideProperty.kt"); runTest("idea/testData/slicer/inflow/overrideProperty.kt");
} }
@TestMetadata("inflow/overridingFunctionResult.kt") @TestMetadata("overridingFunctionResult.kt")
public void testInflow_OverridingFunctionResult() throws Exception { public void testOverridingFunctionResult() throws Exception {
runTest("idea/testData/slicer/inflow/overridingFunctionResult.kt"); runTest("idea/testData/slicer/inflow/overridingFunctionResult.kt");
} }
@TestMetadata("inflow/overridingParameter.kt") @TestMetadata("overridingParameter.kt")
public void testInflow_OverridingParameter() throws Exception { public void testOverridingParameter() throws Exception {
runTest("idea/testData/slicer/inflow/overridingParameter.kt"); runTest("idea/testData/slicer/inflow/overridingParameter.kt");
} }
@TestMetadata("inflow/overridingPropertyGetterResult.kt") @TestMetadata("overridingPropertyGetterResult.kt")
public void testInflow_OverridingPropertyGetterResult() throws Exception { public void testOverridingPropertyGetterResult() throws Exception {
runTest("idea/testData/slicer/inflow/overridingPropertyGetterResult.kt"); runTest("idea/testData/slicer/inflow/overridingPropertyGetterResult.kt");
} }
@TestMetadata("inflow/overridingPropertyResult.kt") @TestMetadata("overridingPropertyResult.kt")
public void testInflow_OverridingPropertyResult() throws Exception { public void testOverridingPropertyResult() throws Exception {
runTest("idea/testData/slicer/inflow/overridingPropertyResult.kt"); runTest("idea/testData/slicer/inflow/overridingPropertyResult.kt");
} }
@TestMetadata("inflow/primaryConstructorParameter.kt") @TestMetadata("primaryConstructorParameter.kt")
public void testInflow_PrimaryConstructorParameter() throws Exception { public void testPrimaryConstructorParameter() throws Exception {
runTest("idea/testData/slicer/inflow/primaryConstructorParameter.kt"); runTest("idea/testData/slicer/inflow/primaryConstructorParameter.kt");
} }
@TestMetadata("inflow/primaryConstructorParameterWithDefault.kt") @TestMetadata("primaryConstructorParameterWithDefault.kt")
public void testInflow_PrimaryConstructorParameterWithDefault() throws Exception { public void testPrimaryConstructorParameterWithDefault() throws Exception {
runTest("idea/testData/slicer/inflow/primaryConstructorParameterWithDefault.kt"); runTest("idea/testData/slicer/inflow/primaryConstructorParameterWithDefault.kt");
} }
@TestMetadata("inflow/propertyInInterface.kt") @TestMetadata("propertyInInterface.kt")
public void testInflow_PropertyInInterface() throws Exception { public void testPropertyInInterface() throws Exception {
runTest("idea/testData/slicer/inflow/propertyInInterface.kt"); runTest("idea/testData/slicer/inflow/propertyInInterface.kt");
} }
@TestMetadata("inflow/qualifiedAssignmentsForQualifiedRef.kt") @TestMetadata("qualifiedAssignmentsForQualifiedRef.kt")
public void testInflow_QualifiedAssignmentsForQualifiedRef() throws Exception { public void testQualifiedAssignmentsForQualifiedRef() throws Exception {
runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForQualifiedRef.kt"); runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForQualifiedRef.kt");
} }
@TestMetadata("inflow/qualifiedAssignmentsForSimpleRef.kt") @TestMetadata("qualifiedAssignmentsForSimpleRef.kt")
public void testInflow_QualifiedAssignmentsForSimpleRef() throws Exception { public void testQualifiedAssignmentsForSimpleRef() throws Exception {
runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForSimpleRef.kt"); runTest("idea/testData/slicer/inflow/qualifiedAssignmentsForSimpleRef.kt");
} }
@TestMetadata("inflow/safeCast.kt") @TestMetadata("safeCast.kt")
public void testInflow_SafeCast() throws Exception { public void testSafeCast() throws Exception {
runTest("idea/testData/slicer/inflow/safeCast.kt"); runTest("idea/testData/slicer/inflow/safeCast.kt");
} }
@TestMetadata("inflow/secondaryConstructorParameter.kt") @TestMetadata("secondaryConstructorParameter.kt")
public void testInflow_SecondaryConstructorParameter() throws Exception { public void testSecondaryConstructorParameter() throws Exception {
runTest("idea/testData/slicer/inflow/secondaryConstructorParameter.kt"); runTest("idea/testData/slicer/inflow/secondaryConstructorParameter.kt");
} }
@TestMetadata("inflow/secondaryConstructorParameterWithDefault.kt") @TestMetadata("secondaryConstructorParameterWithDefault.kt")
public void testInflow_SecondaryConstructorParameterWithDefault() throws Exception { public void testSecondaryConstructorParameterWithDefault() throws Exception {
runTest("idea/testData/slicer/inflow/secondaryConstructorParameterWithDefault.kt"); runTest("idea/testData/slicer/inflow/secondaryConstructorParameterWithDefault.kt");
} }
@TestMetadata("inflow/settersViaDelegateForQualifiedRef.kt") @TestMetadata("settersViaDelegateForQualifiedRef.kt")
public void testInflow_SettersViaDelegateForQualifiedRef() throws Exception { public void testSettersViaDelegateForQualifiedRef() throws Exception {
runTest("idea/testData/slicer/inflow/settersViaDelegateForQualifiedRef.kt"); runTest("idea/testData/slicer/inflow/settersViaDelegateForQualifiedRef.kt");
} }
@TestMetadata("inflow/settersViaDelegateForSimpleRef.kt") @TestMetadata("settersViaDelegateForSimpleRef.kt")
public void testInflow_SettersViaDelegateForSimpleRef() throws Exception { public void testSettersViaDelegateForSimpleRef() throws Exception {
runTest("idea/testData/slicer/inflow/settersViaDelegateForSimpleRef.kt"); runTest("idea/testData/slicer/inflow/settersViaDelegateForSimpleRef.kt");
} }
@TestMetadata("inflow/settersViaJavaDelegate.kt") @TestMetadata("settersViaJavaDelegate.kt")
public void testInflow_SettersViaJavaDelegate() throws Exception { public void testSettersViaJavaDelegate() throws Exception {
runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt"); runTest("idea/testData/slicer/inflow/settersViaJavaDelegate.kt");
} }
@TestMetadata("inflow/topLevelVal.kt") @TestMetadata("thisInExtensionFunction.kt")
public void testInflow_TopLevelVal() throws Exception { 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"); runTest("idea/testData/slicer/inflow/topLevelVal.kt");
} }
@TestMetadata("inflow/topLevelVar.kt") @TestMetadata("topLevelVar.kt")
public void testInflow_TopLevelVar() throws Exception { public void testTopLevelVar() throws Exception {
runTest("idea/testData/slicer/inflow/topLevelVar.kt"); runTest("idea/testData/slicer/inflow/topLevelVar.kt");
} }
@TestMetadata("inflow/valParameter.kt") @TestMetadata("valParameter.kt")
public void testInflow_ValParameter() throws Exception { public void testValParameter() throws Exception {
runTest("idea/testData/slicer/inflow/valParameter.kt"); runTest("idea/testData/slicer/inflow/valParameter.kt");
} }
@TestMetadata("inflow/varParameter.kt") @TestMetadata("varParameter.kt")
public void testInflow_VarParameter() throws Exception { public void testVarParameter() throws Exception {
runTest("idea/testData/slicer/inflow/varParameter.kt"); runTest("idea/testData/slicer/inflow/varParameter.kt");
} }
@TestMetadata("inflow/whenExpression.kt") @TestMetadata("whenExpression.kt")
public void testInflow_WhenExpression() throws Exception { public void testWhenExpression() throws Exception {
runTest("idea/testData/slicer/inflow/whenExpression.kt"); runTest("idea/testData/slicer/inflow/whenExpression.kt");
} }
}
@TestMetadata("outflow/abstractExtensionMethodParameter.kt") @TestMetadata("idea/testData/slicer/outflow")
public void testOutflow_AbstractExtensionMethodParameter() throws Exception { @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"); runTest("idea/testData/slicer/outflow/abstractExtensionMethodParameter.kt");
} }
@TestMetadata("outflow/abstractMethodParameter1.kt") @TestMetadata("abstractMethodParameter1.kt")
public void testOutflow_AbstractMethodParameter1() throws Exception { public void testAbstractMethodParameter1() throws Exception {
runTest("idea/testData/slicer/outflow/abstractMethodParameter1.kt"); runTest("idea/testData/slicer/outflow/abstractMethodParameter1.kt");
} }
@TestMetadata("outflow/abstractMethodParameter2.kt") @TestMetadata("abstractMethodParameter2.kt")
public void testOutflow_AbstractMethodParameter2() throws Exception { public void testAbstractMethodParameter2() throws Exception {
runTest("idea/testData/slicer/outflow/abstractMethodParameter2.kt"); runTest("idea/testData/slicer/outflow/abstractMethodParameter2.kt");
} }
@TestMetadata("outflow/anonymousFunBodyExpression.kt") public void testAllFilesPresentInOutflow() throws Exception {
public void testOutflow_AnonymousFunBodyExpression() 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"); runTest("idea/testData/slicer/outflow/anonymousFunBodyExpression.kt");
} }
@TestMetadata("outflow/anonymousFunReturnExpression.kt") @TestMetadata("anonymousFunReturnExpression.kt")
public void testOutflow_AnonymousFunReturnExpression() throws Exception { public void testAnonymousFunReturnExpression() throws Exception {
runTest("idea/testData/slicer/outflow/anonymousFunReturnExpression.kt"); runTest("idea/testData/slicer/outflow/anonymousFunReturnExpression.kt");
} }
@TestMetadata("outflow/callArgument.kt") @TestMetadata("callArgument.kt")
public void testOutflow_CallArgument() throws Exception { public void testCallArgument() throws Exception {
runTest("idea/testData/slicer/outflow/callArgument.kt"); runTest("idea/testData/slicer/outflow/callArgument.kt");
} }
@TestMetadata("outflow/callArgumentKJK.kt") @TestMetadata("callArgumentKJK.kt")
public void testOutflow_CallArgumentKJK() throws Exception { public void testCallArgumentKJK() throws Exception {
runTest("idea/testData/slicer/outflow/callArgumentKJK.kt"); runTest("idea/testData/slicer/outflow/callArgumentKJK.kt");
} }
@TestMetadata("outflow/cast.kt") @TestMetadata("cast.kt")
public void testOutflow_Cast() throws Exception { public void testCast() throws Exception {
runTest("idea/testData/slicer/outflow/cast.kt"); runTest("idea/testData/slicer/outflow/cast.kt");
} }
@TestMetadata("outflow/defaultExplicitPrimaryConstructorCalls.kt") @TestMetadata("defaultExplicitPrimaryConstructorCalls.kt")
public void testOutflow_DefaultExplicitPrimaryConstructorCalls() throws Exception { public void testDefaultExplicitPrimaryConstructorCalls() throws Exception {
runTest("idea/testData/slicer/outflow/defaultExplicitPrimaryConstructorCalls.kt"); runTest("idea/testData/slicer/outflow/defaultExplicitPrimaryConstructorCalls.kt");
} }
@TestMetadata("outflow/diamondHierarchyJKLeafClassFun.kt") @TestMetadata("diamondHierarchyJKLeafClassFun.kt")
public void testOutflow_DiamondHierarchyJKLeafClassFun() throws Exception { public void testDiamondHierarchyJKLeafClassFun() throws Exception {
runTest("idea/testData/slicer/outflow/diamondHierarchyJKLeafClassFun.kt"); runTest("idea/testData/slicer/outflow/diamondHierarchyJKLeafClassFun.kt");
} }
@TestMetadata("outflow/diamondHierarchyJKMiddleClassFun.kt") @TestMetadata("diamondHierarchyJKMiddleClassFun.kt")
public void testOutflow_DiamondHierarchyJKMiddleClassFun() throws Exception { public void testDiamondHierarchyJKMiddleClassFun() throws Exception {
runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleClassFun.kt"); runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleClassFun.kt");
} }
@TestMetadata("outflow/diamondHierarchyJKMiddleInterfaceFun.kt") @TestMetadata("diamondHierarchyJKMiddleInterfaceFun.kt")
public void testOutflow_DiamondHierarchyJKMiddleInterfaceFun() throws Exception { public void testDiamondHierarchyJKMiddleInterfaceFun() throws Exception {
runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleInterfaceFun.kt"); runTest("idea/testData/slicer/outflow/diamondHierarchyJKMiddleInterfaceFun.kt");
} }
@TestMetadata("outflow/diamondHierarchyLeafClassFun.kt") @TestMetadata("diamondHierarchyLeafClassFun.kt")
public void testOutflow_DiamondHierarchyLeafClassFun() throws Exception { public void testDiamondHierarchyLeafClassFun() throws Exception {
runTest("idea/testData/slicer/outflow/diamondHierarchyLeafClassFun.kt"); runTest("idea/testData/slicer/outflow/diamondHierarchyLeafClassFun.kt");
} }
@TestMetadata("outflow/diamondHierarchyMiddleClassFun.kt") @TestMetadata("diamondHierarchyMiddleClassFun.kt")
public void testOutflow_DiamondHierarchyMiddleClassFun() throws Exception { public void testDiamondHierarchyMiddleClassFun() throws Exception {
runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleClassFun.kt"); runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleClassFun.kt");
} }
@TestMetadata("outflow/diamondHierarchyMiddleInterfaceFun.kt") @TestMetadata("diamondHierarchyMiddleInterfaceFun.kt")
public void testOutflow_DiamondHierarchyMiddleInterfaceFun() throws Exception { public void testDiamondHierarchyMiddleInterfaceFun() throws Exception {
runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleInterfaceFun.kt"); runTest("idea/testData/slicer/outflow/diamondHierarchyMiddleInterfaceFun.kt");
} }
@TestMetadata("outflow/doubleLambdaResult.kt") @TestMetadata("doubleLambdaResult.kt")
public void testOutflow_DoubleLambdaResult() throws Exception { public void testDoubleLambdaResult() throws Exception {
runTest("idea/testData/slicer/outflow/doubleLambdaResult.kt"); runTest("idea/testData/slicer/outflow/doubleLambdaResult.kt");
} }
@TestMetadata("outflow/explicitLambdaReturnExpression.kt") @TestMetadata("explicitLambdaReturnExpression.kt")
public void testOutflow_ExplicitLambdaReturnExpression() throws Exception { public void testExplicitLambdaReturnExpression() throws Exception {
runTest("idea/testData/slicer/outflow/explicitLambdaReturnExpression.kt"); runTest("idea/testData/slicer/outflow/explicitLambdaReturnExpression.kt");
} }
@TestMetadata("outflow/extensionIndexingDereferences.kt") @TestMetadata("extensionIndexingDereferences.kt")
public void testOutflow_ExtensionIndexingDereferences() throws Exception { public void testExtensionIndexingDereferences() throws Exception {
runTest("idea/testData/slicer/outflow/extensionIndexingDereferences.kt"); runTest("idea/testData/slicer/outflow/extensionIndexingDereferences.kt");
} }
@TestMetadata("outflow/forVariable.kt") @TestMetadata("forVariable.kt")
public void testOutflow_ForVariable() throws Exception { public void testForVariable() throws Exception {
runTest("idea/testData/slicer/outflow/forVariable.kt"); runTest("idea/testData/slicer/outflow/forVariable.kt");
} }
@TestMetadata("outflow/funBodyExpression.kt") @TestMetadata("funBodyExpression.kt")
public void testOutflow_FunBodyExpression() throws Exception { public void testFunBodyExpression() throws Exception {
runTest("idea/testData/slicer/outflow/funBodyExpression.kt"); runTest("idea/testData/slicer/outflow/funBodyExpression.kt");
} }
@TestMetadata("outflow/functionCalls.kt") @TestMetadata("funParameterUsages.kt")
public void testOutflow_FunctionCalls() throws Exception { public void testFunParameterUsages() 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"); runTest("idea/testData/slicer/outflow/funParameterUsages.kt");
} }
@TestMetadata("outflow/funResultViaCallableRef.kt") @TestMetadata("funResultViaCallableRef.kt")
public void testOutflow_FunResultViaCallableRef() throws Exception { public void testFunResultViaCallableRef() throws Exception {
runTest("idea/testData/slicer/outflow/funResultViaCallableRef.kt"); runTest("idea/testData/slicer/outflow/funResultViaCallableRef.kt");
} }
@TestMetadata("outflow/funResultViaCallableRefWithAssignment.kt") @TestMetadata("funResultViaCallableRefWithAssignment.kt")
public void testOutflow_FunResultViaCallableRefWithAssignment() throws Exception { public void testFunResultViaCallableRefWithAssignment() throws Exception {
runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithAssignment.kt"); runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithAssignment.kt");
} }
@TestMetadata("outflow/funResultViaCallableRefWithDirectCall.kt") @TestMetadata("funResultViaCallableRefWithDirectCall.kt")
public void testOutflow_FunResultViaCallableRefWithDirectCall() throws Exception { public void testFunResultViaCallableRefWithDirectCall() throws Exception {
runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithDirectCall.kt"); runTest("idea/testData/slicer/outflow/funResultViaCallableRefWithDirectCall.kt");
} }
@TestMetadata("outflow/funReturnExpression.kt") @TestMetadata("funReturnExpression.kt")
public void testOutflow_FunReturnExpression() throws Exception { public void testFunReturnExpression() throws Exception {
runTest("idea/testData/slicer/outflow/funReturnExpression.kt"); runTest("idea/testData/slicer/outflow/funReturnExpression.kt");
} }
@TestMetadata("outflow/getFunCalls.kt") @TestMetadata("functionCalls.kt")
public void testOutflow_GetFunCalls() throws Exception { 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"); runTest("idea/testData/slicer/outflow/getFunCalls.kt");
} }
@TestMetadata("outflow/getterExpressionBody.kt") @TestMetadata("getterExpressionBody.kt")
public void testOutflow_GetterExpressionBody() throws Exception { public void testGetterExpressionBody() throws Exception {
runTest("idea/testData/slicer/outflow/getterExpressionBody.kt"); runTest("idea/testData/slicer/outflow/getterExpressionBody.kt");
} }
@TestMetadata("outflow/getterReturnExpression.kt") @TestMetadata("getterReturnExpression.kt")
public void testOutflow_GetterReturnExpression() throws Exception { public void testGetterReturnExpression() throws Exception {
runTest("idea/testData/slicer/outflow/getterReturnExpression.kt"); runTest("idea/testData/slicer/outflow/getterReturnExpression.kt");
} }
@TestMetadata("outflow/ifExpression.kt") @TestMetadata("ifExpression.kt")
public void testOutflow_IfExpression() throws Exception { public void testIfExpression() throws Exception {
runTest("idea/testData/slicer/outflow/ifExpression.kt"); runTest("idea/testData/slicer/outflow/ifExpression.kt");
} }
@TestMetadata("outflow/indexingDereferences.kt") @TestMetadata("indexingDereferences.kt")
public void testOutflow_IndexingDereferences() throws Exception { public void testIndexingDereferences() throws Exception {
runTest("idea/testData/slicer/outflow/indexingDereferences.kt"); runTest("idea/testData/slicer/outflow/indexingDereferences.kt");
} }
@TestMetadata("outflow/jvmFieldMemberPropertyJavaUsages.kt") @TestMetadata("jvmFieldMemberPropertyJavaUsages.kt")
public void testOutflow_JvmFieldMemberPropertyJavaUsages() throws Exception { public void testJvmFieldMemberPropertyJavaUsages() throws Exception {
runTest("idea/testData/slicer/outflow/jvmFieldMemberPropertyJavaUsages.kt"); runTest("idea/testData/slicer/outflow/jvmFieldMemberPropertyJavaUsages.kt");
} }
@TestMetadata("outflow/lambdaResult.kt") @TestMetadata("lambdaResult.kt")
public void testOutflow_LambdaResult() throws Exception { public void testLambdaResult() throws Exception {
runTest("idea/testData/slicer/outflow/lambdaResult.kt"); runTest("idea/testData/slicer/outflow/lambdaResult.kt");
} }
@TestMetadata("outflow/lambdaResultWithAssignments.kt") @TestMetadata("lambdaResultWithAssignments.kt")
public void testOutflow_LambdaResultWithAssignments() throws Exception { public void testLambdaResultWithAssignments() throws Exception {
runTest("idea/testData/slicer/outflow/lambdaResultWithAssignments.kt"); runTest("idea/testData/slicer/outflow/lambdaResultWithAssignments.kt");
} }
@TestMetadata("outflow/lambdaResultWithDirectCall.kt") @TestMetadata("lambdaResultWithDirectCall.kt")
public void testOutflow_LambdaResultWithDirectCall() throws Exception { public void testLambdaResultWithDirectCall() throws Exception {
runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCall.kt"); runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCall.kt");
} }
@TestMetadata("outflow/lambdaResultWithDirectCallViaAssignment.kt") @TestMetadata("lambdaResultWithDirectCallViaAssignment.kt")
public void testOutflow_LambdaResultWithDirectCallViaAssignment() throws Exception { public void testLambdaResultWithDirectCallViaAssignment() throws Exception {
runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCallViaAssignment.kt"); runTest("idea/testData/slicer/outflow/lambdaResultWithDirectCallViaAssignment.kt");
} }
@TestMetadata("outflow/localVariableUsages.kt") @TestMetadata("localVariableUsages.kt")
public void testOutflow_LocalVariableUsages() throws Exception { public void testLocalVariableUsages() throws Exception {
runTest("idea/testData/slicer/outflow/localVariableUsages.kt"); runTest("idea/testData/slicer/outflow/localVariableUsages.kt");
} }
@TestMetadata("outflow/memberPropertyUsages.kt") @TestMetadata("memberPropertyUsages.kt")
public void testOutflow_MemberPropertyUsages() throws Exception { public void testMemberPropertyUsages() throws Exception {
runTest("idea/testData/slicer/outflow/memberPropertyUsages.kt"); runTest("idea/testData/slicer/outflow/memberPropertyUsages.kt");
} }
@TestMetadata("outflow/nonLocalReturn.kt") @TestMetadata("nonLocalReturn.kt")
public void testOutflow_NonLocalReturn() throws Exception { public void testNonLocalReturn() throws Exception {
runTest("idea/testData/slicer/outflow/nonLocalReturn.kt"); runTest("idea/testData/slicer/outflow/nonLocalReturn.kt");
} }
@TestMetadata("outflow/notNullAssertion.kt") @TestMetadata("notNullAssertion.kt")
public void testOutflow_NotNullAssertion() throws Exception { public void testNotNullAssertion() throws Exception {
runTest("idea/testData/slicer/outflow/notNullAssertion.kt"); runTest("idea/testData/slicer/outflow/notNullAssertion.kt");
} }
@TestMetadata("outflow/openMethodParameter.kt") @TestMetadata("openMethodParameter.kt")
public void testOutflow_OpenMethodParameter() throws Exception { public void testOpenMethodParameter() throws Exception {
runTest("idea/testData/slicer/outflow/openMethodParameter.kt"); runTest("idea/testData/slicer/outflow/openMethodParameter.kt");
} }
@TestMetadata("outflow/operatorCallDereferences.kt") @TestMetadata("operatorCallDereferences.kt")
public void testOutflow_OperatorCallDereferences() throws Exception { public void testOperatorCallDereferences() throws Exception {
runTest("idea/testData/slicer/outflow/operatorCallDereferences.kt"); runTest("idea/testData/slicer/outflow/operatorCallDereferences.kt");
} }
@TestMetadata("outflow/operatorFunCalls.kt") @TestMetadata("operatorFunCalls.kt")
public void testOutflow_OperatorFunCalls() throws Exception { public void testOperatorFunCalls() throws Exception {
runTest("idea/testData/slicer/outflow/operatorFunCalls.kt"); runTest("idea/testData/slicer/outflow/operatorFunCalls.kt");
} }
@TestMetadata("outflow/overridingFunctionResult.kt") @TestMetadata("overridingFunctionResult.kt")
public void testOutflow_OverridingFunctionResult() throws Exception { public void testOverridingFunctionResult() throws Exception {
runTest("idea/testData/slicer/outflow/overridingFunctionResult.kt"); runTest("idea/testData/slicer/outflow/overridingFunctionResult.kt");
} }
@TestMetadata("outflow/overridingFunctionResultWithJava.kt") @TestMetadata("overridingFunctionResultWithJava.kt")
public void testOutflow_OverridingFunctionResultWithJava() throws Exception { public void testOverridingFunctionResultWithJava() throws Exception {
runTest("idea/testData/slicer/outflow/overridingFunctionResultWithJava.kt"); runTest("idea/testData/slicer/outflow/overridingFunctionResultWithJava.kt");
} }
@TestMetadata("outflow/overridingParameter.kt") @TestMetadata("overridingParameter.kt")
public void testOutflow_OverridingParameter() throws Exception { public void testOverridingParameter() throws Exception {
runTest("idea/testData/slicer/outflow/overridingParameter.kt"); runTest("idea/testData/slicer/outflow/overridingParameter.kt");
} }
@TestMetadata("outflow/overridingPropertyGetterResult.kt") @TestMetadata("overridingPropertyGetterResult.kt")
public void testOutflow_OverridingPropertyGetterResult() throws Exception { public void testOverridingPropertyGetterResult() throws Exception {
runTest("idea/testData/slicer/outflow/overridingPropertyGetterResult.kt"); runTest("idea/testData/slicer/outflow/overridingPropertyGetterResult.kt");
} }
@TestMetadata("outflow/overridingPropertyResult.kt") @TestMetadata("overridingPropertyResult.kt")
public void testOutflow_OverridingPropertyResult() throws Exception { public void testOverridingPropertyResult() throws Exception {
runTest("idea/testData/slicer/outflow/overridingPropertyResult.kt"); runTest("idea/testData/slicer/outflow/overridingPropertyResult.kt");
} }
@TestMetadata("outflow/primaryConstructorCalls.kt") @TestMetadata("primaryConstructorCalls.kt")
public void testOutflow_PrimaryConstructorCalls() throws Exception { public void testPrimaryConstructorCalls() throws Exception {
runTest("idea/testData/slicer/outflow/primaryConstructorCalls.kt"); runTest("idea/testData/slicer/outflow/primaryConstructorCalls.kt");
} }
@TestMetadata("outflow/primaryConstructorParameterUsages.kt") @TestMetadata("primaryConstructorParameterUsages.kt")
public void testOutflow_PrimaryConstructorParameterUsages() throws Exception { public void testPrimaryConstructorParameterUsages() throws Exception {
runTest("idea/testData/slicer/outflow/primaryConstructorParameterUsages.kt"); runTest("idea/testData/slicer/outflow/primaryConstructorParameterUsages.kt");
} }
@TestMetadata("outflow/secondaryConstructorCalls.kt") @TestMetadata("secondaryConstructorCalls.kt")
public void testOutflow_SecondaryConstructorCalls() throws Exception { public void testSecondaryConstructorCalls() throws Exception {
runTest("idea/testData/slicer/outflow/secondaryConstructorCalls.kt"); runTest("idea/testData/slicer/outflow/secondaryConstructorCalls.kt");
} }
@TestMetadata("outflow/simpleCallDereferences.kt") @TestMetadata("simpleCallDereferences.kt")
public void testOutflow_SimpleCallDereferences() throws Exception { public void testSimpleCallDereferences() throws Exception {
runTest("idea/testData/slicer/outflow/simpleCallDereferences.kt"); runTest("idea/testData/slicer/outflow/simpleCallDereferences.kt");
} }
@TestMetadata("outflow/topLevelPropertyUsages.kt") @TestMetadata("thisInExtensionFunction.kt")
public void testOutflow_TopLevelPropertyUsages() throws Exception { 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"); runTest("idea/testData/slicer/outflow/topLevelPropertyUsages.kt");
} }
@TestMetadata("outflow/usagesInLoopRange.kt") @TestMetadata("usagesInLoopRange.kt")
public void testOutflow_UsagesInLoopRange() throws Exception { public void testUsagesInLoopRange() throws Exception {
runTest("idea/testData/slicer/outflow/usagesInLoopRange.kt"); runTest("idea/testData/slicer/outflow/usagesInLoopRange.kt");
} }
@TestMetadata("outflow/usagesInTemplates.kt") @TestMetadata("usagesInTemplates.kt")
public void testOutflow_UsagesInTemplates() throws Exception { public void testUsagesInTemplates() throws Exception {
runTest("idea/testData/slicer/outflow/usagesInTemplates.kt"); runTest("idea/testData/slicer/outflow/usagesInTemplates.kt");
} }
@TestMetadata("outflow/valParameter.kt") @TestMetadata("valParameter.kt")
public void testOutflow_ValParameter() throws Exception { public void testValParameter() throws Exception {
runTest("idea/testData/slicer/outflow/valParameter.kt"); runTest("idea/testData/slicer/outflow/valParameter.kt");
} }
@TestMetadata("outflow/varParameter.kt") @TestMetadata("varParameter.kt")
public void testOutflow_VarParameter() throws Exception { public void testVarParameter() throws Exception {
runTest("idea/testData/slicer/outflow/varParameter.kt"); runTest("idea/testData/slicer/outflow/varParameter.kt");
} }
@TestMetadata("outflow/whenExpression.kt") @TestMetadata("whenExpression.kt")
public void testOutflow_WhenExpression() throws Exception { public void testWhenExpression() throws Exception {
runTest("idea/testData/slicer/outflow/whenExpression.kt"); runTest("idea/testData/slicer/outflow/whenExpression.kt");
} }
@TestMetadata("wrongThis.kt")
public void testWrongThis() throws Exception {
runTest("idea/testData/slicer/outflow/wrongThis.kt");
}
}
} }