K2: fix/universalize logic to determine that member is from Java

This commit is contained in:
Mikhail Glukhikh
2022-11-10 15:12:04 +01:00
committed by Space Team
parent d35dedcb72
commit 4dc7b6dddc
15 changed files with 109 additions and 17 deletions
@@ -6085,6 +6085,12 @@ public class DiagnosisCompilerFirTestdataTestGenerated extends AbstractDiagnosis
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/invokePriorityComplex.kt");
}
@Test
@TestMetadata("isAncestor.kt")
public void testIsAncestor() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt");
}
@Test
@TestMetadata("KJKComplexHierarchyNestedLoop.kt")
public void testKJKComplexHierarchyNestedLoop() throws Exception {
@@ -0,0 +1,11 @@
FILE: test.kt
public final fun foo(): R|kotlin/Unit| {
lval externalsMap: R|kotlin/collections/MutableMap<java/io/File, kotlin/String?>| = R|kotlin/collections/mutableMapOf|<R|java/io/File|, R|kotlin/String?|>()
local final fun test(file: R|java/io/File|): R|kotlin/Unit| {
lval base: R|java/io/File!| = R|your/ContainerUtil.find|<R|java/io/File!|>(R|<local>/externalsMap|.R|SubstitutionOverride<kotlin/collections/MutableMap.keys: R|kotlin/collections/MutableSet<java/io/File>|>|, <L> = find@fun <anonymous>(it: R|java/io/File!|): R|kotlin/Boolean| <inline=NoInline> {
^ R|my/FileUtil.isAncestor|(R|<local>/it|, R|<local>/file|, Boolean(false))
}
)
}
}
@@ -0,0 +1,53 @@
// FILE: their/Condition.java
package their;
public interface Condition<T> {
boolean value (T t);
}
// FILE: your/ContainerUtil.java
package your;
import their.Condition;
public final class ContainerUtil {
public static <T> T find(Iterable<? extends T> iterable, Condition<? super T> condition) {
return true;
}
public static <T> T find(Iterable<? extends T> iterable, T equalTo) {
return true;
}
}
// FILE: my/FileUtil.java
package my;
import java.io.File;
public final class FileUtil {
public static boolean isAncestor(File ancestor, File file, boolean strict) {
return true;
}
public static boolean isAncestor(String ancestor, String file, boolean strict) {
return true;
}
}
// FILE: test.kt
import java.io.File
import my.FileUtil.*
import your.ContainerUtil.find
fun foo() {
val externalsMap = mutableMapOf<File, String?>()
fun test(file: File) {
val base = find(externalsMap.keys) { isAncestor(it, file, false) }
}
}
@@ -6085,6 +6085,12 @@ public class FirDiagnosticTestGenerated extends AbstractFirDiagnosticTest {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/invokePriorityComplex.kt");
}
@Test
@TestMetadata("isAncestor.kt")
public void testIsAncestor() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt");
}
@Test
@TestMetadata("KJKComplexHierarchyNestedLoop.kt")
public void testKJKComplexHierarchyNestedLoop() throws Exception {
@@ -6085,6 +6085,12 @@ public class FirDiagnosticsWithLightTreeTestGenerated extends AbstractFirDiagnos
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/invokePriorityComplex.kt");
}
@Test
@TestMetadata("isAncestor.kt")
public void testIsAncestor() throws Exception {
runTest("compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt");
}
@Test
@TestMetadata("KJKComplexHierarchyNestedLoop.kt")
public void testKJKComplexHierarchyNestedLoop() throws Exception {
@@ -13,10 +13,10 @@ import org.jetbrains.kotlin.fir.containingClassLookupTag
import org.jetbrains.kotlin.fir.declarations.FirProperty
import org.jetbrains.kotlin.fir.declarations.FirResolvePhase
import org.jetbrains.kotlin.fir.declarations.FirSimpleFunction
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.declarations.utils.isAbstract
import org.jetbrains.kotlin.fir.declarations.utils.isFinal
import org.jetbrains.kotlin.fir.declarations.utils.isInterface
import org.jetbrains.kotlin.fir.declarations.utils.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.dispatchReceiverClassTypeOrNull
import org.jetbrains.kotlin.fir.originalOrSelf
import org.jetbrains.kotlin.fir.resolve.toFirRegularClassSymbol
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.fir.StandardTypes
import org.jetbrains.kotlin.fir.analysis.checkers.context.CheckerContext
import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirFunctionCallChecker
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.declarations.utils.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.expressions.FirFunctionCall
import org.jetbrains.kotlin.fir.expressions.argumentMapping
import org.jetbrains.kotlin.fir.expressions.toResolvedCallableSymbol
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.fir.analysis.checkers.expression.FirQualifiedAccessE
import org.jetbrains.kotlin.fir.analysis.checkers.toRegularClassSymbol
import org.jetbrains.kotlin.fir.analysis.diagnostics.jvm.FirJvmErrors
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.declarations.utils.isFun
import org.jetbrains.kotlin.fir.declarations.utils.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.references.FirResolvedNamedReference
@@ -12,8 +12,8 @@ import org.jetbrains.kotlin.diagnostics.DiagnosticReporter
import org.jetbrains.kotlin.fir.analysis.diagnostics.FirErrors.FUN_INTERFACE_CONSTRUCTOR_REFERENCE
import org.jetbrains.kotlin.diagnostics.reportOn
import org.jetbrains.kotlin.fir.declarations.FirDeclarationOrigin
import org.jetbrains.kotlin.fir.declarations.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.declarations.utils.isFun
import org.jetbrains.kotlin.fir.declarations.utils.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.expressions.FirCallableReferenceAccess
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccessExpression
import org.jetbrains.kotlin.fir.resolved
@@ -496,7 +496,7 @@ class Fir2IrDeclarationStorage(
// It's necessary to understand that such methods do not belong to DefaultImpls but actually generated as default
// See org.jetbrains.kotlin.backend.jvm.lower.InheritedDefaultMethodsOnClassesLoweringKt.isDefinitelyNotDefaultImplsMethod
(irParent as? IrClass)?.origin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB &&
function.origin == FirDeclarationOrigin.Enhancement -> IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
function.isJavaOrEnhancement -> IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
else -> function.computeIrOrigin(predefinedOrigin)
}
// We don't generate signatures for local classes
@@ -1502,8 +1502,7 @@ class Fir2IrDeclarationStorage(
parentOrigin: IrDeclarationOrigin
): IrDeclarationOrigin = when {
symbol.fir.isIntersectionOverride || symbol.fir.isSubstitutionOverride -> IrDeclarationOrigin.FAKE_OVERRIDE
parentOrigin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB &&
(symbol.fir.origin is FirDeclarationOrigin.Enhancement || symbol.fir.origin is FirDeclarationOrigin.Java) -> {
parentOrigin == IrDeclarationOrigin.IR_EXTERNAL_DECLARATION_STUB && symbol.isJavaOrEnhancement -> {
IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB
}
symbol.origin is FirDeclarationOrigin.Plugin -> GeneratedByPlugin((symbol.origin as FirDeclarationOrigin.Plugin).key)
@@ -352,7 +352,7 @@ class DelegatedMemberGenerator(
originalForSubstitutionOverride!!.isDefaultJavaMethod()
else -> {
// Check that we have a non-abstract method from Java interface
origin == FirDeclarationOrigin.Enhancement && modality == Modality.OPEN
isJavaOrEnhancement && modality == Modality.OPEN
}
}
}
@@ -7,9 +7,11 @@ package org.jetbrains.kotlin.fir.declarations
import org.jetbrains.kotlin.descriptors.ClassKind
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.declarations.utils.isInline
import org.jetbrains.kotlin.fir.resolve.fullyExpandedType
import org.jetbrains.kotlin.fir.scopes.impl.declaredMemberScope
import org.jetbrains.kotlin.fir.scopes.impl.importedFromObjectOrStaticData
import org.jetbrains.kotlin.fir.symbols.FirBasedSymbol
import org.jetbrains.kotlin.fir.symbols.impl.*
import org.jetbrains.kotlin.fir.types.ConeClassLikeType
@@ -99,3 +101,18 @@ fun FirRegularClassSymbol.isInlineOrValueClass(): Boolean {
return isInline
}
@PrivateForInline
inline val FirDeclarationOrigin.isJavaOrEnhancement: Boolean
get() = this is FirDeclarationOrigin.Java || this == FirDeclarationOrigin.Enhancement
@OptIn(PrivateForInline::class)
val FirDeclaration.isJavaOrEnhancement: Boolean
get() = origin.isJavaOrEnhancement ||
(this as? FirCallableDeclaration)?.importedFromObjectOrStaticData?.original?.isJavaOrEnhancement == true
@OptIn(PrivateForInline::class)
inline val FirBasedSymbol<*>.isJavaOrEnhancement: Boolean
get() = origin.isJavaOrEnhancement ||
(fir as? FirCallableDeclaration)?.importedFromObjectOrStaticData?.original?.isJavaOrEnhancement == true
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.fir.FirAnnotationContainer
import org.jetbrains.kotlin.fir.FirElement
import org.jetbrains.kotlin.fir.FirSession
import org.jetbrains.kotlin.fir.caches.FirCachesFactory
import org.jetbrains.kotlin.fir.declarations.utils.isJavaOrEnhancement
import org.jetbrains.kotlin.fir.expressions.*
import org.jetbrains.kotlin.fir.languageVersionSettings
import org.jetbrains.kotlin.fir.references.FirNamedReference
@@ -463,7 +463,7 @@ internal object CheckArguments : CheckerStage() {
private fun Candidate.isJavaApplicableCandidate(): Boolean {
val symbol = symbol as? FirFunctionSymbol ?: return false
if (symbol.origin == FirDeclarationOrigin.Enhancement) return true
if (symbol.isJavaOrEnhancement) return true
if (originScope !is FirTypeScope) return false
// Note: constructor can also be Java applicable with enhancement origin, but it doesn't have overridden functions
// See samConstructorVsFun.kt diagnostic test
@@ -472,7 +472,7 @@ private fun Candidate.isJavaApplicableCandidate(): Boolean {
var result = false
originScope.processOverriddenFunctions(symbol) {
if (it.origin == FirDeclarationOrigin.Enhancement) {
if (it.isJavaOrEnhancement) {
result = true
ProcessorAction.STOP
} else {
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.fir.declarations.utils
import org.jetbrains.kotlin.fir.PrivateForInline
import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.expressions.FirQualifiedAccess
import org.jetbrains.kotlin.fir.resolvedSymbol
@@ -48,9 +49,3 @@ inline val FirDeclaration.isPrecompiled: Boolean
get() = origin == FirDeclarationOrigin.Precompiled
inline val FirDeclaration.isSynthetic: Boolean
get() = origin == FirDeclarationOrigin.Synthetic
inline val FirDeclaration.isJavaOrEnhancement: Boolean
get() = origin is FirDeclarationOrigin.Java || origin == FirDeclarationOrigin.Enhancement
inline val FirBasedSymbol<*>.isJavaOrEnhancement: Boolean
get() = origin is FirDeclarationOrigin.Java || origin == FirDeclarationOrigin.Enhancement