Analyze Data Flow: Support cross-language analysis

#KT-16833 Fixed
This commit is contained in:
Alexey Sedunov
2017-11-22 18:09:21 +03:00
parent 6cb68531ae
commit c6a9c36275
125 changed files with 1109 additions and 108 deletions
@@ -59,7 +59,7 @@ fun KtElement.toLightElements(): List<PsiNamedElement> =
when (this) {
is KtClassOrObject -> listOfNotNull(toLightClass())
is KtNamedFunction,
is KtSecondaryConstructor -> LightClassUtil.getLightClassMethods(this as KtFunction)
is KtConstructor<*> -> LightClassUtil.getLightClassMethods(this as KtFunction)
is KtProperty -> LightClassUtil.getLightClassPropertyMethods(this).allDeclarations
is KtPropertyAccessor -> listOfNotNull(LightClassUtil.getLightClassAccessorMethod(this))
is KtParameter -> mutableListOf<PsiNamedElement>().also { elements ->
@@ -125,6 +125,9 @@ abstract class KotlinLightCodeInsightFixtureTestCase : KotlinLightCodeInsightFix
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_FULL_JDK")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_FULL_JDK
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME_WITH_REFLECT")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE_WITH_REFLECT
}
else if (InTextDirectivesUtils.isDirectiveDefined(fileText, "RUNTIME") ||
InTextDirectivesUtils.isDirectiveDefined(fileText, "WITH_RUNTIME")) {
return KotlinWithJdkAndRuntimeLightProjectDescriptor.INSTANCE
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.idea.test;
import com.intellij.openapi.projectRoots.Sdk;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.codegen.forTestCompile.ForTestCompileRuntime;
import org.jetbrains.kotlin.test.KotlinTestUtils;
import org.jetbrains.kotlin.utils.PathUtil;
import java.io.File;
@@ -43,6 +44,12 @@ public class KotlinWithJdkAndRuntimeLightProjectDescriptor extends KotlinJdkAndL
PathUtil.getKotlinPathsForDistDirectory().getKotlinTestPath())
);
@NotNull
public static final KotlinWithJdkAndRuntimeLightProjectDescriptor INSTANCE_WITH_REFLECT = new KotlinWithJdkAndRuntimeLightProjectDescriptor(
Arrays.asList(ForTestCompileRuntime.runtimeJarForTests(),
ForTestCompileRuntime.reflectJarForTests())
);
@NotNull
public static final KotlinWithJdkAndRuntimeLightProjectDescriptor INSTANCE_FULL_JDK = new KotlinWithJdkAndRuntimeLightProjectDescriptor() {
@Override
@@ -27,4 +27,8 @@ class KotlinReferenceUsageInfo(reference: PsiReference) : UsageInfo(reference) {
val element = element ?: return null
return element.references.singleOrNull { it::class.java == referenceType }
}
}
class KotlinReferencePreservingUsageInfo(private val reference: PsiReference) : UsageInfo(reference) {
override fun getReference() = reference
}
@@ -16,25 +16,49 @@
package org.jetbrains.kotlin.idea.findUsages
import com.intellij.find.findUsages.FindUsagesManager
import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.light.LightMemberReference
import com.intellij.usageView.UsageInfo
import com.intellij.usages.UsageViewManager
import org.jetbrains.kotlin.asJava.toLightClass
import org.jetbrains.kotlin.asJava.toLightElements
import org.jetbrains.kotlin.idea.references.KtReference
import org.jetbrains.kotlin.psi.KtConstructor
import org.jetbrains.kotlin.psi.KtDeclaration
import org.jetbrains.kotlin.utils.SmartList
fun KtDeclaration.processAllExactUsages(
fun PsiElement.processAllExactUsages(
options: () -> FindUsagesOptions,
processor: (UsageInfo) -> Unit
) {
val findUsagesHandler = KotlinFindUsagesHandlerFactory(project).createFindUsagesHandler(this, true)
findUsagesHandler.processElementUsages(
this,
{
if (it.reference?.isReferenceTo(this) ?: false) {
processor(it)
}
true
},
options()
)
fun elementsToCheckReferenceAgainst(reference: PsiReference): List<PsiElement> {
if (reference is KtReference || this !is KtDeclaration) return listOf(this)
return SmartList<PsiElement>().also { list ->
list += this
list += toLightElements()
if (this is KtConstructor<*>) {
getContainingClassOrObject().toLightClass()?.let { list += it }
}
}
}
val project = project
FindUsagesManager(project, UsageViewManager.getInstance(project))
.getFindUsagesHandler(this, true)
?.processElementUsages(
this,
{
val reference = it.reference ?: return@processElementUsages true
if (reference is LightMemberReference || elementsToCheckReferenceAgainst(reference).any { reference.isReferenceTo(it) }) {
processor(it)
}
true
},
options()
)
}
fun KtDeclaration.processAllUsages(
@@ -21,12 +21,14 @@ import com.intellij.find.findUsages.FindUsagesOptions
import com.intellij.openapi.diagnostic.Logger
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiReference
import com.intellij.psi.impl.light.LightMemberReference
import com.intellij.psi.search.GlobalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.usageView.UsageInfo
import com.intellij.util.CommonProcessors
import com.intellij.util.Processor
import org.jetbrains.kotlin.idea.findUsages.KotlinFindUsagesHandlerFactory
import org.jetbrains.kotlin.idea.findUsages.KotlinReferencePreservingUsageInfo
import org.jetbrains.kotlin.idea.findUsages.KotlinReferenceUsageInfo
import org.jetbrains.kotlin.idea.util.application.runReadAction
import java.util.*
@@ -118,7 +120,13 @@ abstract class KotlinFindUsagesHandler<T : PsiElement>(psiElement: T,
val LOG = Logger.getInstance(KotlinFindUsagesHandler::class.java)
internal fun processUsage(processor: Processor<UsageInfo>, ref: PsiReference): Boolean =
processor.processIfNotNull { if (ref.element.isValid) KotlinReferenceUsageInfo(ref) else null }
processor.processIfNotNull {
when {
ref is LightMemberReference -> KotlinReferencePreservingUsageInfo(ref)
ref.element.isValid -> KotlinReferenceUsageInfo(ref)
else -> null
}
}
internal fun processUsage(processor: Processor<UsageInfo>, element: PsiElement): Boolean =
processor.processIfNotNull { if (element.isValid) UsageInfo(element) else null }
@@ -35,7 +35,7 @@ import org.jetbrains.kotlin.types.TypeUtils
import org.jetbrains.kotlin.types.isError
import org.jetbrains.kotlin.types.isNullabilityFlexible
class KotlinSliceProvider : SliceLanguageSupportProvider {
class KotlinSliceProvider : SliceLanguageSupportProvider, SliceUsageTransformer {
companion object {
val LEAF_ELEMENT_EQUALITY = object : SliceLeafEquality() {
override fun substituteElement(element: PsiElement) = (element as? KtReference)?.resolve() ?: element
@@ -71,6 +71,11 @@ class KotlinSliceProvider : SliceLanguageSupportProvider {
override fun createRootUsage(element: PsiElement, params: SliceAnalysisParams) = KotlinSliceUsage(element, params)
override fun transform(usage: SliceUsage): Collection<SliceUsage>? {
if (usage is KotlinSliceUsage) return null
return listOf(KotlinSliceUsage(usage.element, usage.parent, 0, false))
}
override fun getExpressionAtCaret(atCaret: PsiElement?, dataFlowToThis: Boolean): KtExpression? {
val element =
atCaret?.parentsWithSelf
@@ -78,6 +83,7 @@ class KotlinSliceProvider : SliceLanguageSupportProvider {
it is KtProperty ||
it is KtParameter ||
it is KtDeclarationWithBody ||
(it is KtClass && !it.hasExplicitPrimaryConstructor()) ||
(it is KtExpression && it !is KtDeclaration)
}
?.let { KtPsiUtil.safeDeparenthesize(it as KtExpression) } ?: return null
@@ -18,10 +18,15 @@ package org.jetbrains.kotlin.idea.slicer
import com.intellij.analysis.AnalysisScope
import com.intellij.codeInsight.highlighting.ReadWriteAccessDetector.Access
import com.intellij.lang.java.JavaLanguage
import com.intellij.psi.PsiCall
import com.intellij.psi.PsiElement
import com.intellij.psi.PsiMethod
import com.intellij.psi.impl.light.LightMemberReference
import com.intellij.psi.search.LocalSearchScope
import com.intellij.psi.search.SearchScope
import com.intellij.psi.search.searches.ReferencesSearch
import com.intellij.slicer.JavaSliceUsage
import com.intellij.slicer.SliceUsage
import com.intellij.usageView.UsageInfo
import com.intellij.util.Processor
@@ -54,8 +59,8 @@ import org.jetbrains.kotlin.idea.references.ReferenceAccess
import org.jetbrains.kotlin.idea.references.readWriteAccessWithFullExpression
import org.jetbrains.kotlin.idea.search.declarationsSearch.HierarchySearchRequest
import org.jetbrains.kotlin.idea.search.declarationsSearch.searchOverriders
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.idea.search.ideaExtensions.KotlinReadWriteAccessDetector
import org.jetbrains.kotlin.lexer.KtTokens
import org.jetbrains.kotlin.psi.*
import org.jetbrains.kotlin.psi.psiUtil.*
import org.jetbrains.kotlin.resolve.BindingContext
@@ -68,19 +73,19 @@ import org.jetbrains.kotlin.resolve.source.getPsi
import org.jetbrains.kotlin.util.OperatorNameConventions
import java.util.*
private fun KtDeclaration.processHierarchyDownward(scope: SearchScope, processor: KtDeclaration.() -> Unit) {
private fun PsiElement.processHierarchyDownward(scope: SearchScope, processor: PsiElement.() -> Unit) {
processor()
HierarchySearchRequest(this, scope).searchOverriders().forEach {
(it.namedUnwrappedElement as? KtDeclaration)?.processor()
it.namedUnwrappedElement?.processor()
}
}
private fun KtDeclaration.processHierarchyUpward(scope: AnalysisScope, processor: KtDeclaration.() -> Unit) {
private fun KtDeclaration.processHierarchyUpward(scope: AnalysisScope, processor: PsiElement.() -> Unit) {
processor()
val descriptor = unsafeResolveToDescriptor() as? CallableMemberDescriptor ?: return
DescriptorUtils
.getAllOverriddenDescriptors(descriptor)
.mapNotNull { it.source.getPsi() as? KtDeclaration }
.mapNotNull { it.source.getPsi() }
.filter { scope.contains(it) }
.forEach(processor)
}
@@ -157,7 +162,7 @@ class InflowSlicer(
processor: Processor<SliceUsage>,
parentUsage: KotlinSliceUsage
) : Slicer(element, processor, parentUsage) {
private fun KtDeclaration.processHierarchyDownwardAndPass() {
private fun PsiElement.processHierarchyDownwardAndPass() {
processHierarchyDownward(parentUsage.scope.toSearchScope()) { passToProcessor() }
}
@@ -165,14 +170,25 @@ class InflowSlicer(
private fun KtDeclaration.processAssignments(accessSearchScope: SearchScope) {
processVariableAccesses(accessSearchScope, AccessKind.WRITE_WITH_OPTIONAL_READ) body@ {
val refExpression = it.element as? KtExpression ?: return@body
val (accessKind, accessExpression) = refExpression.readWriteAccessWithFullExpression(true)
if (accessKind == ReferenceAccess.WRITE && accessExpression is KtBinaryExpression && accessExpression.operationToken == KtTokens.EQ) {
accessExpression.right?.passToProcessorAsValue()
}
else {
accessExpression.passToProcessorAsValue()
val refElement = it.element ?: return@body
val refParent = refElement.parent
val rhsValue = when {
refElement is KtExpression -> {
val (accessKind, accessExpression) = refElement.readWriteAccessWithFullExpression(true)
if (accessKind == ReferenceAccess.WRITE && accessExpression is KtBinaryExpression && accessExpression.operationToken == KtTokens.EQ) {
accessExpression.right
}
else {
accessExpression
}
}
refParent is PsiCall -> refParent.argumentList?.expressions?.getOrNull(0)
else -> null
}
rhsValue?.passToProcessorAsValue()
}
}
@@ -202,7 +218,7 @@ class InflowSlicer(
if (hasDelegateExpression()) {
val getter = (unsafeResolveToDescriptor() as VariableDescriptorWithAccessors).getter
val delegateGetterResolvedCall = getter?.let { bindingContext[BindingContext.DELEGATED_PROPERTY_RESOLVED_CALL, it] }
(delegateGetterResolvedCall?.resultingDescriptor?.source?.getPsi() as? KtDeclarationWithBody)?.passToProcessor()
delegateGetterResolvedCall?.resultingDescriptor?.source?.getPsi()?.passToProcessor()
return
}
@@ -246,16 +262,26 @@ class InflowSlicer(
val parameterDescriptor = analyze()[BindingContext.VALUE_PARAMETER, this] ?: return
(function as? KtFunction)?.processCalls(parentUsage.scope.toSearchScope()) body@ {
val refExpression = it.element as? KtExpression ?: return@body
val callElement = refExpression.getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return@body
val resolvedCall = callElement.getResolvedCall(callElement.analyze()) ?: return@body
val resolvedArgument = resolvedCall.valueArguments[parameterDescriptor] ?: return@body
val flownExpression = when (resolvedArgument) {
is DefaultValueArgument -> defaultValue
is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression()
else -> null
} ?: return@body
flownExpression.passToProcessorAsValue()
val refElement = it.element ?: return@body
val refParent = refElement.parent
val argumentExpression = when {
refElement is KtExpression -> {
val callElement = refElement.getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return@body
val resolvedCall = callElement.getResolvedCall(callElement.analyze()) ?: return@body
val resolvedArgument = resolvedCall.valueArguments[parameterDescriptor] ?: return@body
when (resolvedArgument) {
is DefaultValueArgument -> defaultValue
is ExpressionValueArgument -> resolvedArgument.valueArgument?.getArgumentExpression()
else -> null
}
}
refParent is PsiCall -> refParent.argumentList?.expressions?.getOrNull(this@processParameter.parameterIndex())
else -> null
}
argumentExpression?.passToProcessorAsValue()
}
if (valOrVarKeyword.toValVar() == KotlinValVar.Var) {
@@ -313,7 +339,7 @@ class InflowSlicer(
return
}
val accessedDescriptor = createdAt.target.accessedDescriptor ?: return
val accessedDeclaration = accessedDescriptor.source.getPsi() as? KtDeclaration ?: return
val accessedDeclaration = accessedDescriptor.source.getPsi() ?: return
if (accessedDescriptor is SyntheticFieldDescriptor) {
val property = accessedDeclaration as? KtProperty ?: return
if (accessedDescriptor.propertyDescriptor.setter?.isDefault ?: true) {
@@ -347,7 +373,7 @@ class InflowSlicer(
(resolvedCall.dispatchReceiver as? ExpressionReceiver)?.expression?.passToProcessorAsValue(parentUsage.lambdaLevel + 1)
}
else {
(resultingDescriptor.source.getPsi() as? KtDeclaration)?.processHierarchyDownwardAndPass()
resultingDescriptor.source.getPsi()?.processHierarchyDownwardAndPass()
}
}
}
@@ -376,8 +402,14 @@ class OutflowSlicer(
val withDereferences = parentUsage.params.showInstanceDereferences
val accessKind = if (withDereferences) AccessKind.READ_OR_WRITE else AccessKind.READ_ONLY
processVariableAccesses(parentUsage.scope.toSearchScope(), accessKind) body@ {
val refExpression = (it.element as? KtExpression)?.let { KtPsiUtil.safeDeparenthesize(it) } ?: return@body
(this as? KtDeclaration)?.processVariableAccesses(parentUsage.scope.toSearchScope(), accessKind) body@ {
val refElement = it.element
if (refElement !is KtExpression) {
refElement?.passToProcessor()
return@body
}
val refExpression = KtPsiUtil.safeDeparenthesize(refElement)
if (withDereferences) {
refExpression.processDereferences()
}
@@ -388,7 +420,7 @@ class OutflowSlicer(
}
}
private fun PsiElement.getCallElementForExactCallee(): KtElement? {
private fun PsiElement.getCallElementForExactCallee(): PsiElement? {
if (this is KtArrayAccessExpression) return this
val operationRefExpr = getNonStrictParentOfType<KtOperationReferenceExpression>()
@@ -397,6 +429,7 @@ class OutflowSlicer(
val parentCall = getParentOfTypeAndBranch<KtCallElement> { calleeExpression } ?: return null
val callee = parentCall.calleeExpression?.let { KtPsiUtil.safeDeparenthesize(it) }
if (callee == this || callee is KtConstructorCalleeExpression && callee.isAncestor(this, true)) return parentCall
return null
}
@@ -409,9 +442,25 @@ class OutflowSlicer(
private fun KtFunction.processFunction() {
if (this is KtConstructor<*> || this is KtNamedFunction && name != null) {
processHierarchyUpward(parentUsage.scope) {
(this as? KtFunction)?.processCalls(parentUsage.scope.toSearchScope()) {
it.element?.getCallElementForExactCallee()?.passToProcessor()
it.element?.getCallableReferenceForExactCallee()?.passToProcessor(parentUsage.lambdaLevel + 1)
if (this is KtFunction) {
processCalls(parentUsage.scope.toSearchScope()) {
val refElement = it.element
when {
refElement == null -> (it.reference as? LightMemberReference)?.element?.passToProcessor()
refElement is KtExpression -> {
refElement.getCallElementForExactCallee()?.passToProcessor()
refElement.getCallableReferenceForExactCallee()?.passToProcessor(parentUsage.lambdaLevel + 1)
}
else -> refElement.passToProcessor()
}
}
}
else if (this is PsiMethod && language == JavaLanguage.INSTANCE) {
// todo: work around the bug in JavaSliceProvider.transform()
processor.process(JavaSliceUsage.createRootUsage(this, parentUsage.params))
}
else {
passToProcessor()
}
}
return
@@ -462,7 +511,7 @@ class OutflowSlicer(
private fun KtExpression.processExpression() {
processPseudocodeUsages { pseudoValue, instr ->
when (instr) {
is WriteValueInstruction -> (instr.target.accessedDescriptor?.source?.getPsi() as? KtDeclaration)?.passToProcessor()
is WriteValueInstruction -> instr.target.accessedDescriptor?.source?.getPsi()?.passToProcessor()
is CallInstruction -> {
if (parentUsage.lambdaLevel > 0 && instr.receiverValues[pseudoValue] != null) {
instr.element.passToProcessor(parentUsage.lambdaLevel - 1)
+11
View File
@@ -0,0 +1,11 @@
import kotlin.reflect.KProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class D {
public static D INSTANCE = new D();
int getValue(@Nullable Object thisRef, @NotNull KProperty<?> property) {
return 1;
}
}
+8
View File
@@ -0,0 +1,8 @@
// FLOW: IN
// RUNTIME_WITH_REFLECT
val foo: Int by D.INSTANCE
fun test() {
val <caret>x = foo
}
@@ -0,0 +1,5 @@
9 return <bold>1</bold>;
7 val <bold>x = foo</bold>
7 val x = <bold>foo</bold>
4 val <bold>foo: Int by D.INSTANCE</bold>
9 return <bold>1</bold>;
@@ -0,0 +1,3 @@
[NotNull Values]
7 val <bold>x = foo</bold>
7 val <bold>x = foo</bold>
@@ -0,0 +1,4 @@
7 val <bold>x = foo</bold>
7 val x = <bold>foo</bold>
4 val <bold>foo: Int by D.INSTANCE</bold>
9 return <bold>1</bold>;
@@ -0,0 +1,15 @@
// FLOW: OUT
interface A {
public int foo();
}
interface C extends A {
public int foo();
}
class D extends B implements C {
public int foo() {
return 4;
}
}
@@ -0,0 +1,12 @@
// FLOW: IN
open class B : A {
override fun foo() = 2
}
fun test(a: A, b: B, c: C, d: D) {
val x = a.foo()
val <caret>y = b.foo()
val z = c.foo()
val u = d.foo()
}
@@ -0,0 +1,10 @@
4 override fun foo() = <bold>2</bold>
9 val <bold>y = b.foo()</bold>
9 val y = <bold>b.foo()</bold>
4 override fun <bold>foo() = 2</bold>
4 override fun foo() = <bold>2</bold>
13 return <bold>4</bold>;
9 val <bold>y = b.foo()</bold>
9 val y = <bold>b.foo()</bold>
13 return <bold>4</bold>;
@@ -0,0 +1,3 @@
[NotNull Values]
9 val <bold>y = b.foo()</bold>
9 val <bold>y = b.foo()</bold>
@@ -0,0 +1,5 @@
9 val <bold>y = b.foo()</bold>
9 val y = <bold>b.foo()</bold>
4 override fun <bold>foo() = 2</bold>
4 override fun foo() = <bold>2</bold>
13 return <bold>4</bold>;
@@ -0,0 +1,15 @@
interface A {
public int foo();
}
class B extends A {
public int foo() {
return 2;
}
}
class D extends B implements C {
public int foo() {
return 4;
}
}
@@ -0,0 +1,12 @@
// FLOW: IN
interface C : A {
override fun foo() = 3
}
fun test(a: A, b: B, c: C, d: D) {
val x = a.foo()
val y = b.foo()
val <caret>z = c.foo()
val u = d.foo()
}
@@ -0,0 +1,10 @@
4 override fun foo() = <bold>3</bold>
10 val <bold>z = c.foo()</bold>
10 val z = <bold>c.foo()</bold>
4 override fun <bold>foo() = 3</bold>
4 override fun foo() = <bold>3</bold>
13 return <bold>4</bold>;
10 val <bold>z = c.foo()</bold>
10 val z = <bold>c.foo()</bold>
13 return <bold>4</bold>;
@@ -0,0 +1,3 @@
[NotNull Values]
10 val <bold>z = c.foo()</bold>
10 val <bold>z = c.foo()</bold>
@@ -0,0 +1,5 @@
10 val <bold>z = c.foo()</bold>
10 val z = <bold>c.foo()</bold>
4 override fun <bold>foo() = 3</bold>
4 override fun foo() = <bold>3</bold>
13 return <bold>4</bold>;
@@ -0,0 +1,15 @@
class B implements A {
public int foo() {
return 2;
}
}
interface C extends A {
public int foo();
}
class D extends B implements C {
public int foo() {
return 4;
}
}
@@ -0,0 +1,12 @@
// FLOW: IN
interface A {
fun foo() = 1
}
fun test(a: A, b: B, c: C, d: D) {
val <caret>x = a.foo()
val y = b.foo()
val z = c.foo()
val u = d.foo()
}
@@ -0,0 +1,15 @@
4 fun foo() = <bold>1</bold>
8 val <bold>x = a.foo()</bold>
8 val x = <bold>a.foo()</bold>
4 fun <bold>foo() = 1</bold>
4 fun foo() = <bold>1</bold>
3 return <bold>2</bold>;
8 val <bold>x = a.foo()</bold>
8 val x = <bold>a.foo()</bold>
3 return <bold>2</bold>;
13 return <bold>4</bold>;
8 val <bold>x = a.foo()</bold>
8 val x = <bold>a.foo()</bold>
13 return <bold>4</bold>;
@@ -0,0 +1,3 @@
[NotNull Values]
8 val <bold>x = a.foo()</bold>
8 val <bold>x = a.foo()</bold>
@@ -0,0 +1,6 @@
8 val <bold>x = a.foo()</bold>
8 val x = <bold>a.foo()</bold>
4 fun <bold>foo() = 1</bold>
4 fun foo() = <bold>1</bold>
13 return <bold>4</bold>;
3 return <bold>2</bold>;
+6
View File
@@ -0,0 +1,6 @@
class J {
void test() {
FunParamererKt.foo(1):
FunParamererKt.foo(1, "2"):
}
}
+1
View File
@@ -1,5 +1,6 @@
// FLOW: IN
@JvmOverloads
fun foo(<caret>n: Int, s: String = "???") {
}
+7 -3
View File
@@ -1,4 +1,8 @@
8 foo(<bold>1</bold>)
3 fun foo(<bold>n: Int</bold>, s: String = "???") {
8 foo(<bold>1</bold>)
3 FunParamererKt.foo(<bold>1</bold>):
4 fun foo(<bold>n: Int</bold>, s: String = "???") {
3 FunParamererKt.foo(<bold>1</bold>):
9 foo(<bold>1</bold>)
4 fun foo(<bold>n: Int</bold>, s: String = "???") {
9 foo(<bold>1</bold>)
@@ -1,3 +1,4 @@
[NotNull Values]
3 fun foo(<bold>n: Int</bold>, s: String = "???") {
3 fun foo(<bold>n: Int</bold>, s: String = "???") {
4 fun foo(<bold>n: Int</bold>, s: String = "???") {
4 fun foo(<bold>n: Int</bold>, s: String = "???") {
+8 -6
View File
@@ -1,6 +1,8 @@
3 fun foo(<bold>n: Int</bold>, s: String = "???") {
8 foo(<bold>1</bold>)
9 foo(<bold>1</bold>, "2")
10 foo(<bold>1</bold>, s = "2")
11 foo(n = <bold>1</bold>, s = "2")
12 foo(s = "2", n = <bold>1</bold>)
4 fun foo(<bold>n: Int</bold>, s: String = "???") {
3 FunParamererKt.foo(<bold>1</bold>):
4 FunParamererKt.foo(<bold>1</bold>, "2"):
9 foo(<bold>1</bold>)
10 foo(<bold>1</bold>, "2")
11 foo(<bold>1</bold>, s = "2")
12 foo(n = <bold>1</bold>, s = "2")
13 foo(s = "2", n = <bold>1</bold>)
@@ -0,0 +1,6 @@
class J {
void test() {
FunParamererWithDefaultKt.foo(1):
FunParamererWithDefaultKt.foo(1, "2"):
}
}
@@ -1,5 +1,6 @@
// FLOW: IN
@JvmOverloads
fun foo(n: Int, <caret>s: String = "???") {
}
@@ -1,8 +1,12 @@
9 foo(1, <bold>"2"</bold>)
3 fun foo(n: Int, <bold>s: String = "???"</bold>) {
9 foo(1, <bold>"2"</bold>)
4 FunParamererWithDefaultKt.foo(1, <bold>"2"</bold>):
4 fun foo(n: Int, <bold>s: String = "???"</bold>) {
4 FunParamererWithDefaultKt.foo(1, <bold>"2"</bold>):
3 fun foo(n: Int, s: String = <bold>"???"</bold>) {
3 fun foo(n: Int, <bold>s: String = "???"</bold>) {
3 fun foo(n: Int, s: String = <bold>"???"</bold>) {
10 foo(1, <bold>"2"</bold>)
4 fun foo(n: Int, <bold>s: String = "???"</bold>) {
10 foo(1, <bold>"2"</bold>)
4 fun foo(n: Int, s: String = <bold>"???"</bold>) {
4 fun foo(n: Int, <bold>s: String = "???"</bold>) {
4 fun foo(n: Int, s: String = <bold>"???"</bold>) {
@@ -1,3 +1,4 @@
[NotNull Values]
3 fun foo(n: Int, <bold>s: String = "???"</bold>) {
3 fun foo(n: Int, <bold>s: String = "???"</bold>) {
4 fun foo(n: Int, <bold>s: String = "???"</bold>) {
4 fun foo(n: Int, <bold>s: String = "???"</bold>) {
@@ -1,6 +1,7 @@
3 fun foo(n: Int, <bold>s: String = "???"</bold>) {
3 fun foo(n: Int, s: String = <bold>"???"</bold>) {
9 foo(1, <bold>"2"</bold>)
10 foo(1, s = <bold>"2"</bold>)
11 foo(n = 1, s = <bold>"2"</bold>)
12 foo(s = <bold>"2"</bold>, n = 1)
4 fun foo(n: Int, <bold>s: String = "???"</bold>) {
4 FunParamererWithDefaultKt.foo(1, <bold>"2"</bold>):
4 fun foo(n: Int, s: String = <bold>"???"</bold>) {
10 foo(1, <bold>"2"</bold>)
11 foo(1, s = <bold>"2"</bold>)
12 foo(n = 1, s = <bold>"2"</bold>)
13 foo(s = <bold>"2"</bold>, n = 1)
@@ -0,0 +1,5 @@
class D extends B {
public int foo() {
return 5;
}
}
@@ -10,3 +10,8 @@
12 override fun <bold>foo() = 3</bold>
12 override fun foo() = <bold>3</bold>
3 return <bold>5</bold>;
17 val <bold>y = b.foo()</bold>
17 val y = <bold>b.foo()</bold>
3 return <bold>5</bold>;
@@ -2,5 +2,6 @@
17 val y = <bold>b.foo()</bold>
8 override fun <bold>foo() = 2</bold>
8 override fun foo() = <bold>2</bold>
3 return <bold>5</bold>;
12 override fun <bold>foo() = 3</bold>
12 override fun foo() = <bold>3</bold>
+5
View File
@@ -0,0 +1,5 @@
class D extends B {
public int getFoo() {
return 5;
}
}
@@ -9,3 +9,8 @@
10 override val <bold>foo = 3</bold>
10 override val foo = <bold>3</bold>
3 return <bold>5</bold>;
15 val <bold>y = b.foo</bold>
15 val y = <bold>b.foo</bold>
3 return <bold>5</bold>;
@@ -1,5 +1,6 @@
15 val <bold>y = b.foo</bold>
15 val y = <bold>b.foo</bold>
7 open class B(override val <bold>foo: Int</bold>) : A()
3 return <bold>5</bold>;
10 override val <bold>foo = 3</bold>
10 override val foo = <bold>3</bold>
@@ -0,0 +1,5 @@
class D extends B {
public int getFoo() {
return 5;
}
}
@@ -10,3 +10,8 @@
14 override val <bold>foo: Int</bold>
15 get() = <bold>3</bold>
3 return <bold>5</bold>;
20 val <bold>y = b.foo</bold>
20 val y = <bold>b.foo</bold>
3 return <bold>5</bold>;
@@ -2,5 +2,6 @@
20 val y = <bold>b.foo</bold>
9 override val <bold>foo: Int</bold>
10 get() = <bold>2</bold>
3 return <bold>5</bold>;
14 override val <bold>foo: Int</bold>
15 get() = <bold>3</bold>
@@ -0,0 +1,5 @@
class D extends B {
public int getFoo() {
return 5;
}
}
@@ -10,3 +10,8 @@
12 override val <bold>foo = 3</bold>
12 override val foo = <bold>3</bold>
3 return <bold>5</bold>;
17 val <bold>y = b.foo</bold>
17 val y = <bold>b.foo</bold>
3 return <bold>5</bold>;
@@ -2,5 +2,6 @@
17 val y = <bold>b.foo</bold>
8 override val <bold>foo = 2</bold>
8 override val foo = <bold>2</bold>
3 return <bold>5</bold>;
12 override val <bold>foo = 3</bold>
12 override val foo = <bold>3</bold>
@@ -0,0 +1,14 @@
class D extends A {
D(int n, String s) {
super(n, s);
}
D(int n) {
super(n);
}
void test() {
new A(1);
new A(1, "2");
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
// FLOW: IN
open class A(<caret>n: Int, s: String = "???")
open class A @JvmOverloads constructor(<caret>n: Int, s: String = "???")
class B1: A(1)
class B2: A(1, "2")
@@ -1,4 +1,13 @@
2 D(int <bold>n</bold>, String s) {
3 open class A @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
3 super(<bold>n</bold>, s);
2 D(int <bold>n</bold>, String s) {
5 class B1: A(<bold>1</bold>)
3 open class A(<bold>n: Int</bold>, s: String = "???")
3 open class A @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
5 class B1: A(<bold>1</bold>)
11 new A(<bold>1</bold>);
3 open class A @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
11 new A(<bold>1</bold>);
@@ -1,3 +1,4 @@
[NotNull Values]
3 open class A(<bold>n: Int</bold>, s: String = "???")
3 open class A(<bold>n: Int</bold>, s: String = "???")
3 open class A @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
3 open class A @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
@@ -1,4 +1,4 @@
3 open class A(<bold>n: Int</bold>, s: String = "???")
3 open class A @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
5 class B1: A(<bold>1</bold>)
6 class B2: A(<bold>1</bold>, "2")
7 class B3: A(<bold>1</bold>, s = "2")
@@ -9,3 +9,9 @@
14 A(<bold>1</bold>, s = "2")
15 A(n = <bold>1</bold>, s = "2")
16 A(s = "2", n = <bold>1</bold>)
3 super(<bold>n</bold>, s);
2 D(int <bold>n</bold>, String s) {
7 super(<bold>n</bold>);
6 D(int <bold>n</bold>) {
11 new A(<bold>1</bold>);
12 new A(<bold>1</bold>, "2");
@@ -0,0 +1,14 @@
class D extends A {
D(int n, String s) {
super(n, s);
}
D(int n) {
super(n);
}
void test() {
new A(1);
new A(1, "2");
}
}
@@ -1,6 +1,6 @@
// FLOW: IN
open class A(n: Int, <caret>s: String = "???")
open class A @JvmOverloads constructor(n: Int, <caret>s: String = "???")
class B1: A(1)
class B2: A(1, "2")
@@ -1,8 +1,17 @@
6 class B2: A(1, <bold>"2"</bold>)
3 open class A(n: Int, <bold>s: String = "???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
6 class B2: A(1, <bold>"2"</bold>)
3 open class A(n: Int, s: String = <bold>"???"</bold>)
3 open class A(n: Int, <bold>s: String = "???"</bold>)
3 open class A(n: Int, s: String = <bold>"???"</bold>)
12 new A(1, <bold>"2"</bold>);
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
12 new A(1, <bold>"2"</bold>);
2 D(int n, String <bold>s</bold>) {
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
3 super(n, <bold>s</bold>);
2 D(int n, String <bold>s</bold>) {
3 open class A @JvmOverloads constructor(n: Int, s: String = <bold>"???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, s: String = <bold>"???"</bold>)
@@ -1,3 +1,4 @@
[NotNull Values]
3 open class A(n: Int, <bold>s: String = "???"</bold>)
3 open class A(n: Int, <bold>s: String = "???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
@@ -1,5 +1,5 @@
3 open class A(n: Int, <bold>s: String = "???"</bold>)
3 open class A(n: Int, s: String = <bold>"???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
3 open class A @JvmOverloads constructor(n: Int, s: String = <bold>"???"</bold>)
6 class B2: A(1, <bold>"2"</bold>)
7 class B3: A(1, s = <bold>"2"</bold>)
8 class B4: A(n = 1, s = <bold>"2"</bold>)
@@ -8,3 +8,6 @@
14 A(1, s = <bold>"2"</bold>)
15 A(n = 1, s = <bold>"2"</bold>)
16 A(s = <bold>"2"</bold>, n = 1)
3 super(n, <bold>s</bold>);
2 D(int n, String <bold>s</bold>) {
12 new A(1, <bold>"2"</bold>);
@@ -0,0 +1,14 @@
class D extends A {
D(int n, String s) {
super(n, s);
}
D(int n) {
super(n);
}
void test() {
new A(1);
new A(1, "2");
}
}
@@ -1,7 +1,7 @@
// FLOW: IN
open class A {
constructor(<caret>n: Int, s: String = "???")
@JvmOverloads constructor(<caret>n: Int, s: String = "???")
}
class B1: A(1)
@@ -1,4 +1,13 @@
2 D(int <bold>n</bold>, String s) {
4 @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
3 super(<bold>n</bold>, s);
2 D(int <bold>n</bold>, String s) {
7 class B1: A(<bold>1</bold>)
4 constructor(<bold>n: Int</bold>, s: String = "???")
4 @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
7 class B1: A(<bold>1</bold>)
11 new A(<bold>1</bold>);
4 @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
11 new A(<bold>1</bold>);
@@ -1,3 +1,4 @@
[NotNull Values]
4 constructor(<bold>n: Int</bold>, s: String = "???")
4 constructor(<bold>n: Int</bold>, s: String = "???")
4 @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
4 @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
@@ -1,4 +1,4 @@
4 constructor(<bold>n: Int</bold>, s: String = "???")
4 @JvmOverloads constructor(<bold>n: Int</bold>, s: String = "???")
7 class B1: A(<bold>1</bold>)
8 class B2: A(<bold>1</bold>, "2")
9 class B3: A(<bold>1</bold>, s = "2")
@@ -9,3 +9,9 @@
16 A(<bold>1</bold>, s = "2")
17 A(n = <bold>1</bold>, s = "2")
18 A(s = "2", n = <bold>1</bold>)
3 super(<bold>n</bold>, s);
2 D(int <bold>n</bold>, String s) {
7 super(<bold>n</bold>);
6 D(int <bold>n</bold>) {
11 new A(<bold>1</bold>);
12 new A(<bold>1</bold>, "2");
@@ -0,0 +1,14 @@
class D extends A {
D(int n, String s) {
super(n, s);
}
D(int n) {
super(n);
}
void test() {
new A(1);
new A(1, "2");
}
}
@@ -1,7 +1,7 @@
// FLOW: IN
open class A {
constructor(n: Int, <caret>s: String = "???")
@JvmOverloads constructor(n: Int, <caret>s: String = "???")
}
class B1: A(1)
@@ -1,8 +1,17 @@
8 class B2: A(1, <bold>"2"</bold>)
4 constructor(n: Int, <bold>s: String = "???"</bold>)
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
8 class B2: A(1, <bold>"2"</bold>)
4 constructor(n: Int, s: String = <bold>"???"</bold>)
4 constructor(n: Int, <bold>s: String = "???"</bold>)
4 constructor(n: Int, s: String = <bold>"???"</bold>)
12 new A(1, <bold>"2"</bold>);
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
12 new A(1, <bold>"2"</bold>);
2 D(int n, String <bold>s</bold>) {
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
3 super(n, <bold>s</bold>);
2 D(int n, String <bold>s</bold>) {
4 @JvmOverloads constructor(n: Int, s: String = <bold>"???"</bold>)
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
4 @JvmOverloads constructor(n: Int, s: String = <bold>"???"</bold>)
@@ -1,3 +1,4 @@
[NotNull Values]
4 constructor(n: Int, <bold>s: String = "???"</bold>)
4 constructor(n: Int, <bold>s: String = "???"</bold>)
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
@@ -1,5 +1,5 @@
4 constructor(n: Int, <bold>s: String = "???"</bold>)
4 constructor(n: Int, s: String = <bold>"???"</bold>)
4 @JvmOverloads constructor(n: Int, <bold>s: String = "???"</bold>)
4 @JvmOverloads constructor(n: Int, s: String = <bold>"???"</bold>)
8 class B2: A(1, <bold>"2"</bold>)
9 class B3: A(1, s = <bold>"2"</bold>)
10 class B4: A(n = 1, s = <bold>"2"</bold>)
@@ -8,3 +8,6 @@
16 A(1, s = <bold>"2"</bold>)
17 A(n = 1, s = <bold>"2"</bold>)
18 A(s = <bold>"2"</bold>, n = 1)
3 super(n, <bold>s</bold>);
2 D(int n, String <bold>s</bold>) {
12 new A(1, <bold>"2"</bold>);
+15
View File
@@ -0,0 +1,15 @@
import kotlin.reflect.KProperty;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
public class D {
private String _value = "";
int getValue(@Nullable Object thisRef, @NotNull KProperty<?> property) {
return _value;
}
void setValue(@Nullable Object thisRef, @NotNull KProperty<?> property, @NotNull String value) {
_value = value;
}
}
+19
View File
@@ -0,0 +1,19 @@
// FLOW: IN
// RUNTIME_WITH_REFLECT
class AClass(name1: String){
var name by D()
init {
name = name1
}
fun uses(){
name = "bye"
println("Now my name is '$<caret>name'")
}
}
fun main(args: Array<String>) {
val a = AClass("hello")
println("My name is '${a.name}'")
}
@@ -0,0 +1,12 @@
6 private String _value = <bold>""</bold>;
12 println("Now my name is '$<bold>name</bold>'")
5 var <bold>name by D()</bold>
9 return <bold>_value</bold>;
6 private String _value = <bold>""</bold>;
12 void setValue(@Nullable Object thisRef, @NotNull KProperty<?> property, @NotNull String <bold>value</bold>) {
12 println("Now my name is '$<bold>name</bold>'")
5 var <bold>name by D()</bold>
9 return <bold>_value</bold>;
13 _value = <bold>value</bold>;
12 void setValue(@Nullable Object thisRef, @NotNull KProperty<?> property, @NotNull String <bold>value</bold>) {
@@ -0,0 +1,3 @@
[NotNull Values]
12 println("Now my name is '$<bold>name</bold>'")
12 println("Now my name is '$<bold>name</bold>'")
@@ -0,0 +1,6 @@
12 println("Now my name is '$<bold>name</bold>'")
5 var <bold>name by D()</bold>
9 return <bold>_value</bold>;
6 private String _value = <bold>""</bold>;
13 _value = <bold>value</bold>;
12 void setValue(@Nullable Object thisRef, @NotNull KProperty<?> property, @NotNull String <bold>value</bold>) {
+5
View File
@@ -0,0 +1,5 @@
class D {
void test() {
int foo = TopLevelValKt.getFoo();
}
}
+6
View File
@@ -0,0 +1,6 @@
class D {
void test() {
int foo = TopLevelVarKt.getFoo();
TopLevelVarKt.setFoo(3);
}
}
@@ -6,3 +6,7 @@
3 var <bold>foo: Int = 1</bold>
7 foo = <bold>2</bold>
4 TopLevelVarKt.setFoo(<bold>3</bold>);
3 var <bold>foo: Int = 1</bold>
4 TopLevelVarKt.setFoo(<bold>3</bold>);
+1
View File
@@ -1,3 +1,4 @@
3 var <bold>foo: Int = 1</bold>
3 var foo: Int = <bold>1</bold>
4 TopLevelVarKt.setFoo(<bold>3</bold>);
7 foo = <bold>2</bold>
+10
View File
@@ -0,0 +1,10 @@
class D extends A {
D(int n) {
super(n);
}
void test() {
A a = new A(3);
int foo = a.getN();
}
}
@@ -1,3 +1,8 @@
2 D(int <bold>n</bold>) {
3 open class A(val <bold>n: Int</bold>)
3 super(<bold>n</bold>);
2 D(int <bold>n</bold>) {
5 class B : A(<bold>1</bold>)
3 open class A(val <bold>n: Int</bold>)
5 class B : A(<bold>1</bold>)
@@ -6,3 +11,7 @@
3 open class A(val <bold>n: Int</bold>)
8 val z = A(<bold>2</bold>).n
7 A a = new A(<bold>3</bold>);
3 open class A(val <bold>n: Int</bold>)
7 A a = new A(<bold>3</bold>);
+3
View File
@@ -1,3 +1,6 @@
3 open class A(val <bold>n: Int</bold>)
5 class B : A(<bold>1</bold>)
8 val z = A(<bold>2</bold>).n
3 super(<bold>n</bold>);
2 D(int <bold>n</bold>) {
7 A a = new A(<bold>3</bold>);
+11
View File
@@ -0,0 +1,11 @@
class D extends A {
D(int n) {
super(n);
}
void test() {
A a = new A(3);
int foo = a.getN();
a.setN(4);
}
}
+13
View File
@@ -1,3 +1,8 @@
2 D(int <bold>n</bold>) {
3 open class A(var <bold>n: Int</bold>) {
3 super(<bold>n</bold>);
2 D(int <bold>n</bold>) {
20 class B : A(<bold>1</bold>)
3 open class A(var <bold>n: Int</bold>) {
20 class B : A(<bold>1</bold>)
@@ -10,3 +15,11 @@
3 open class A(var <bold>n: Int</bold>) {
24 A(<bold>3</bold>).n = 2
7 A a = new A(<bold>3</bold>);
3 open class A(var <bold>n: Int</bold>) {
7 A a = new A(<bold>3</bold>);
9 a.setN(<bold>4</bold>);
3 open class A(var <bold>n: Int</bold>) {
9 a.setN(<bold>4</bold>);
+4
View File
@@ -2,5 +2,9 @@
20 class B : A(<bold>1</bold>)
23 val z = A(<bold>2</bold>).n
24 A(<bold>3</bold>).n = 2
3 super(<bold>n</bold>);
2 D(int <bold>n</bold>) {
7 A a = new A(<bold>3</bold>);
9 a.setN(<bold>4</bold>);
16 n = <bold>1</bold>
24 A(3).n = <bold>2</bold>
+6
View File
@@ -0,0 +1,6 @@
class J {
void foo(int n) {
int y = n;
new K().bar(y);
}
}
+11
View File
@@ -0,0 +1,11 @@
// FLOW: OUT
class K {
fun bar(m: Int) {
val z = m
}
fun test() {
val x = <caret>1
J().foo(x)
}
}
@@ -0,0 +1,10 @@
8 val x = <bold>1</bold>
8 val <bold>x = 1</bold>
9 J().foo(<bold>x</bold>)
2 void foo(int <bold>n</bold>) {
3 int y = <bold>n</bold>;
3 int <bold>y = n;</bold>
4 new K().bar(<bold>y</bold>);
3 fun bar(<bold>m: Int</bold>) {
4 val z = <bold>m</bold>
4 val <bold>z = m</bold>
@@ -0,0 +1,13 @@
class J extends A {
J() {
}
J(int n) {
super();
}
void test() {
A a = new A();
}
}
@@ -0,0 +1,15 @@
// FLOW: OUT
open class A<caret>() {
constructor(n: Int) : this()
}
class B : A()
class C : A {
constructor() : super()
}
fun test() {
val x = A()
}
@@ -0,0 +1,9 @@
3 open class A<bold>()</bold> {
7 class B : <bold>A()</bold>
14 val x = <bold>A()</bold>
14 val <bold>x = A()</bold>
2 <bold>J() {</bold>
7 <bold>super</bold>();
4 constructor(n: Int) : <bold>this()</bold>
10 constructor() : <bold>super()</bold>
11 A a = new <bold>A</bold>();
@@ -0,0 +1,13 @@
interface A {
public int foo();
}
class B implements A {
public int foo() {
return 2;
}
}
interface C extends A {
public int foo();
}
@@ -0,0 +1,12 @@
// FLOW: OUT
class D : B(), C {
override fun foo() = <caret>4
}
fun test(a: A, b: B, c: C, d: D) {
val x = a.foo()
val y = b.foo()
val z = c.foo()
val u = d.foo()
}
@@ -0,0 +1,22 @@
4 override fun foo() = <bold>4</bold>
4 override fun <bold>foo() = 4</bold>
11 val u = d.<bold>foo()</bold>
11 val <bold>u = d.foo()</bold>
2 public int <bold>foo();</bold>
8 val x = a.<bold>foo()</bold>
8 val <bold>x = a.foo()</bold>
9 val y = b.<bold>foo()</bold>
9 val <bold>y = b.foo()</bold>
10 val z = c.<bold>foo()</bold>
10 val <bold>z = c.foo()</bold>
11 DUPLICATE: val u = d.<bold>foo()</bold>
6 public int <bold>foo() {</bold>
9 DUPLICATE: val y = b.<bold>foo()</bold>
11 DUPLICATE: val u = d.<bold>foo()</bold>
8 DUPLICATE: val x = a.<bold>foo()</bold>
10 DUPLICATE: val z = c.<bold>foo()</bold>
12 public int <bold>foo();</bold>
10 DUPLICATE: val z = c.<bold>foo()</bold>
11 DUPLICATE: val u = d.<bold>foo()</bold>
8 DUPLICATE: val x = a.<bold>foo()</bold>
9 DUPLICATE: val y = b.<bold>foo()</bold>
@@ -0,0 +1,15 @@
// FLOW: OUT
interface A {
public int foo();
}
interface C extends A {
public int foo();
}
class D extends B implements C {
public int foo() {
return 4;
}
}
@@ -0,0 +1,12 @@
// FLOW: OUT
open class B : A {
override fun foo() = <caret>2
}
fun test(a: A, b: B, c: C, d: D) {
val x = a.foo()
val y = b.foo()
val z = c.foo()
val u = d.foo()
}
@@ -0,0 +1,12 @@
4 override fun foo() = <bold>2</bold>
4 override fun <bold>foo() = 2</bold>
9 val y = b.<bold>foo()</bold>
9 val <bold>y = b.foo()</bold>
4 public int <bold>foo();</bold>
8 val x = a.<bold>foo()</bold>
8 val <bold>x = a.foo()</bold>
10 val z = c.<bold>foo()</bold>
10 val <bold>z = c.foo()</bold>
11 val u = d.<bold>foo()</bold>
11 val <bold>u = d.foo()</bold>
9 DUPLICATE: val y = b.<bold>foo()</bold>
@@ -0,0 +1,15 @@
interface A {
public int foo();
}
class B extends A {
public int foo() {
return 2;
}
}
class D extends B implements C {
public int foo() {
return 4;
}
}
@@ -0,0 +1,12 @@
// FLOW: OUT
interface C : A {
override fun foo() = <caret>3
}
fun test(a: A, b: B, c: C, d: D) {
val x = a.foo()
val y = b.foo()
val z = c.foo()
val u = d.foo()
}
@@ -0,0 +1,12 @@
4 override fun foo() = <bold>3</bold>
4 override fun <bold>foo() = 3</bold>
10 val z = c.<bold>foo()</bold>
10 val <bold>z = c.foo()</bold>
2 public int <bold>foo();</bold>
8 val x = a.<bold>foo()</bold>
8 val <bold>x = a.foo()</bold>
9 val y = b.<bold>foo()</bold>
9 val <bold>y = b.foo()</bold>
11 val u = d.<bold>foo()</bold>
11 val <bold>u = d.foo()</bold>
10 DUPLICATE: val z = c.<bold>foo()</bold>

Some files were not shown because too many files have changed in this diff Show More