From 4dc7b6dddcf71e92994888f8aa6c5409f00d2894 Mon Sep 17 00:00:00 2001 From: Mikhail Glukhikh Date: Thu, 10 Nov 2022 15:12:04 +0100 Subject: [PATCH] K2: fix/universalize logic to determine that member is from Java --- ...nosisCompilerFirTestdataTestGenerated.java | 6 +++ .../problems/isAncestor.fir.txt | 11 ++++ .../resolveWithStdlib/problems/isAncestor.kt | 53 +++++++++++++++++++ .../runners/FirDiagnosticTestGenerated.java | 6 +++ ...DiagnosticsWithLightTreeTestGenerated.java | 6 +++ ...JvmOverridesBackwardCompatibilityHelper.kt | 2 +- ...JavaGenericVarianceViolationTypeChecker.kt | 2 +- ...SamInterfaceConstructorReferenceChecker.kt | 2 +- ...FunInterfaceConstructorReferenceChecker.kt | 2 +- .../fir/backend/Fir2IrDeclarationStorage.kt | 5 +- .../generators/DelegatedMemberGenerator.kt | 2 +- .../fir/declarations/declarationUtils.kt | 17 ++++++ .../fir/declarations/deprecationUtils.kt | 1 - .../fir/resolve/calls/ResolutionStages.kt | 4 +- .../declarations/utils/FirDeclarationUtil.kt | 7 +-- 15 files changed, 109 insertions(+), 17 deletions(-) create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.fir.txt create mode 100644 compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt diff --git a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java index c725955c06d..1d4de171892 100644 --- a/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java +++ b/analysis/low-level-api-fir/tests/org/jetbrains/kotlin/analysis/low/level/api/fir/diagnostic/compiler/based/DiagnosisCompilerFirTestdataTestGenerated.java @@ -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 { diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.fir.txt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.fir.txt new file mode 100644 index 00000000000..4ce8c33513a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.fir.txt @@ -0,0 +1,11 @@ +FILE: test.kt + public final fun foo(): R|kotlin/Unit| { + lval externalsMap: R|kotlin/collections/MutableMap| = R|kotlin/collections/mutableMapOf|() + local final fun test(file: R|java/io/File|): R|kotlin/Unit| { + lval base: R|java/io/File!| = R|your/ContainerUtil.find|(R|/externalsMap|.R|SubstitutionOverride|>|, = find@fun (it: R|java/io/File!|): R|kotlin/Boolean| { + ^ R|my/FileUtil.isAncestor|(R|/it|, R|/file|, Boolean(false)) + } + ) + } + + } diff --git a/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt new file mode 100644 index 00000000000..518e9fd915a --- /dev/null +++ b/compiler/fir/analysis-tests/testData/resolveWithStdlib/problems/isAncestor.kt @@ -0,0 +1,53 @@ +// FILE: their/Condition.java + +package their; + +public interface Condition { + boolean value (T t); +} + +// FILE: your/ContainerUtil.java + +package your; + +import their.Condition; + +public final class ContainerUtil { + public static T find(Iterable iterable, Condition condition) { + return true; + } + + public static T find(Iterable 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() + fun test(file: File) { + val base = find(externalsMap.keys) { isAncestor(it, file, false) } + } +} diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java index 69da58110df..7fe0a4ce3de 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticTestGenerated.java @@ -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 { diff --git a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java index 435ee1544a1..9289aaa2a63 100644 --- a/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java +++ b/compiler/fir/analysis-tests/tests-gen/org/jetbrains/kotlin/test/runners/FirDiagnosticsWithLightTreeTestGenerated.java @@ -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 { diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/FirJvmOverridesBackwardCompatibilityHelper.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/FirJvmOverridesBackwardCompatibilityHelper.kt index 60368091fc4..b43cd5a66d4 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/FirJvmOverridesBackwardCompatibilityHelper.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/FirJvmOverridesBackwardCompatibilityHelper.kt @@ -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 diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt index 92113cf61dd..5b8599e175f 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaGenericVarianceViolationTypeChecker.kt @@ -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 diff --git a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaSamInterfaceConstructorReferenceChecker.kt b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaSamInterfaceConstructorReferenceChecker.kt index 6ce386257e4..065602f4335 100644 --- a/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaSamInterfaceConstructorReferenceChecker.kt +++ b/compiler/fir/checkers/checkers.jvm/src/org/jetbrains/kotlin/fir/analysis/jvm/checkers/expression/FirJavaSamInterfaceConstructorReferenceChecker.kt @@ -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 diff --git a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt index 4de1a100ae4..b8d63925e47 100644 --- a/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt +++ b/compiler/fir/checkers/src/org/jetbrains/kotlin/fir/analysis/checkers/expression/FirFunInterfaceConstructorReferenceChecker.kt @@ -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 diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt index 7a17d92201d..bf1f1e9a9e5 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrDeclarationStorage.kt @@ -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) diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt index a2b0151dce9..49bbe725c7f 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/generators/DelegatedMemberGenerator.kt @@ -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 } } } diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt index f611e5dbc91..e6283d3ab66 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/declarationUtils.kt @@ -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 + diff --git a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt index 9bf3479636f..2c41c6d50d9 100644 --- a/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt +++ b/compiler/fir/providers/src/org/jetbrains/kotlin/fir/declarations/deprecationUtils.kt @@ -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 diff --git a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt index 04fe299e054..52ab9ea0c83 100644 --- a/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt +++ b/compiler/fir/resolve/src/org/jetbrains/kotlin/fir/resolve/calls/ResolutionStages.kt @@ -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 { diff --git a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt index debf932e376..4f209fe9635 100644 --- a/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt +++ b/compiler/fir/tree/src/org/jetbrains/kotlin/fir/declarations/utils/FirDeclarationUtil.kt @@ -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 -