Fix visibility checker for import.
This commit is contained in:
@@ -117,14 +117,14 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
importDirective: JetImportDirective,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
trace: BindingTrace,
|
||||
shouldBeVisibleFrom: DeclarationDescriptor // todo
|
||||
packageFragmentForVisibilityCheck: PackageFragmentDescriptor?
|
||||
): JetScope {
|
||||
val importedReference = importDirective.importedReference ?: return JetScope.Empty
|
||||
val path = importedReference.asQualifierPartList(trace)
|
||||
val lastPart = path.lastOrNull() ?: return JetScope.Empty
|
||||
|
||||
if (importDirective.isAllUnder) {
|
||||
val packageOrClassDescriptor = resolveToPackageOrClass(path, moduleDescriptor, trace, shouldBeVisibleFrom,
|
||||
val packageOrClassDescriptor = resolveToPackageOrClass(path, moduleDescriptor, trace, packageFragmentForVisibilityCheck,
|
||||
scopeForFirstPart = null, inImport = true) ?: return JetScope.Empty
|
||||
if (packageOrClassDescriptor is ClassDescriptor && packageOrClassDescriptor.kind.isSingleton) {
|
||||
trace.report(Errors.CANNOT_IMPORT_MEMBERS_FROM_SINGLETON.on(lastPart.expression, packageOrClassDescriptor)) // todo report on star
|
||||
@@ -136,12 +136,12 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
else {
|
||||
val aliasName = JetPsiUtil.getAliasName(importDirective)
|
||||
if (aliasName == null) { // import kotlin.
|
||||
resolveToPackageOrClass(path, moduleDescriptor, trace, shouldBeVisibleFrom, scopeForFirstPart = null, inImport = true)
|
||||
resolveToPackageOrClass(path, moduleDescriptor, trace, packageFragmentForVisibilityCheck, scopeForFirstPart = null, inImport = true)
|
||||
return JetScope.Empty
|
||||
}
|
||||
|
||||
val packageOrClassDescriptor = resolveToPackageOrClass(path.subList(0, path.size() - 1), moduleDescriptor,
|
||||
trace, shouldBeVisibleFrom, scopeForFirstPart = null, inImport = true)
|
||||
trace, packageFragmentForVisibilityCheck, scopeForFirstPart = null, inImport = true)
|
||||
?: return JetScope.Empty
|
||||
val descriptors = SmartList<DeclarationDescriptor>()
|
||||
|
||||
@@ -167,7 +167,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
else -> throw IllegalStateException("Should be class or package: $packageOrClassDescriptor")
|
||||
}
|
||||
if (descriptors.isNotEmpty()) {
|
||||
storageResult(trace, lastPart.expression, descriptors, shouldBeVisibleFrom, inImport = true, isQualifier = false)
|
||||
storageResult(trace, lastPart.expression, descriptors, packageFragmentForVisibilityCheck, inImport = true, isQualifier = false)
|
||||
}
|
||||
else {
|
||||
tryResolveDescriptorsWhichCannotBeImported(trace, moduleDescriptor, packageOrClassDescriptor, lastPart)
|
||||
@@ -249,7 +249,7 @@ public class QualifiedExpressionResolver(val symbolUsageValidator: SymbolUsageVa
|
||||
path: List<QualifierPart>,
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
trace: BindingTrace,
|
||||
shouldBeVisibleFrom: DeclarationDescriptor,
|
||||
shouldBeVisibleFrom: DeclarationDescriptor?,
|
||||
scopeForFirstPart: LexicalScope?,
|
||||
inImport: Boolean
|
||||
): DeclarationDescriptor? {
|
||||
|
||||
@@ -60,10 +60,13 @@ public class FileScopeProviderImpl(
|
||||
val packageFragment = topLevelDescriptorProvider.getPackageFragment(file.getPackageFqName())
|
||||
.sure { "Could not find fragment ${file.getPackageFqName()} for file ${file.getName()}" }
|
||||
|
||||
val aliasImportResolver = LazyImportResolver(storageManager, qualifiedExpressionResolver, this, moduleDescriptor, AliasImportsIndexed(imports), bindingTrace)
|
||||
val allUnderImportResolver = LazyImportResolver(storageManager, qualifiedExpressionResolver, this, moduleDescriptor, AllUnderImportsIndexed(imports), bindingTrace)
|
||||
val defaultAliasImportResolver = LazyImportResolver(storageManager, qualifiedExpressionResolver, this, moduleDescriptor, AliasImportsIndexed(defaultImports), tempTrace)
|
||||
val defaultAllUnderImportResolver = LazyImportResolver(storageManager, qualifiedExpressionResolver, this, moduleDescriptor, AllUnderImportsIndexed(defaultImports), tempTrace)
|
||||
fun createImportResolver(indexedImports: IndexedImports, trace: BindingTrace)
|
||||
= LazyImportResolver(storageManager, qualifiedExpressionResolver, this, moduleDescriptor, indexedImports, trace, packageFragment)
|
||||
|
||||
val aliasImportResolver = createImportResolver(AliasImportsIndexed(imports), bindingTrace)
|
||||
val allUnderImportResolver = createImportResolver(AllUnderImportsIndexed(imports), bindingTrace)
|
||||
val defaultAliasImportResolver = createImportResolver(AliasImportsIndexed(defaultImports), tempTrace)
|
||||
val defaultAllUnderImportResolver = createImportResolver(AllUnderImportsIndexed(defaultImports), tempTrace)
|
||||
|
||||
val scopeChain = ArrayList<JetScope>()
|
||||
|
||||
|
||||
@@ -70,7 +70,8 @@ class LazyImportResolver(
|
||||
val fileScopeProvider: FileScopeProvider,
|
||||
val moduleDescriptor: ModuleDescriptor,
|
||||
val indexedImports: IndexedImports,
|
||||
private val traceForImportResolve: BindingTrace
|
||||
private val traceForImportResolve: BindingTrace,
|
||||
private val packageFragment: PackageFragmentDescriptor
|
||||
) {
|
||||
private val importedScopesProvider = storageManager.createMemoizedFunction {
|
||||
directive: JetImportDirective -> ImportDirectiveResolveCache(directive)
|
||||
@@ -99,9 +100,8 @@ class LazyImportResolver(
|
||||
directiveUnderResolve = directive
|
||||
|
||||
try {
|
||||
// todo use packageViewFragment for visibility
|
||||
val directiveImportScope = qualifiedExpressionResolver.processImportReference(
|
||||
directive, moduleDescriptor, traceForImportResolve, moduleDescriptor)
|
||||
directive, moduleDescriptor, traceForImportResolve, packageFragment)
|
||||
val descriptors = if (directive.isAllUnder()) emptyList() else directiveImportScope.getAllDescriptors()
|
||||
|
||||
PlatformTypesMappedToKotlinChecker.checkPlatformTypesMappedToKotlin(moduleDescriptor, traceForImportResolve, directive, descriptors)
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
// FILE: j/JavaPublic.java
|
||||
package j;
|
||||
|
||||
public class JavaPublic {
|
||||
public static void javaM() {}
|
||||
public static int javaP = 4;
|
||||
static int javaPackageLocal = 5;
|
||||
}
|
||||
|
||||
// FILE: j/JavaPackageLocal.java
|
||||
package j;
|
||||
|
||||
class JavaPackageLocal {
|
||||
static void javaMPackage() {}
|
||||
static int javaPPackage = 4;
|
||||
}
|
||||
|
||||
// FILE: j/JavaProtected.java
|
||||
package j;
|
||||
|
||||
public class JavaProtected {
|
||||
protected static void javaMProtected() {}
|
||||
protected static int javaPProtected = 4;
|
||||
}
|
||||
|
||||
// FILE: j/JavaPrivate.java
|
||||
package j;
|
||||
|
||||
public class JavaPrivate {
|
||||
private static void javaMPrivate() {}
|
||||
private static int javaPPrivate = 4;
|
||||
}
|
||||
|
||||
|
||||
// FILE: k1.kt
|
||||
package k
|
||||
|
||||
import j.JavaPublic
|
||||
import j.JavaPublic.javaM
|
||||
import j.JavaPublic.javaP
|
||||
import j.JavaPublic.<!INVISIBLE_REFERENCE!>javaPackageLocal<!>
|
||||
|
||||
import j.<!INVISIBLE_REFERENCE!>JavaPackageLocal<!>
|
||||
import j.<!INVISIBLE_REFERENCE!>JavaPackageLocal<!>.<!INVISIBLE_REFERENCE!>javaMPackage<!>
|
||||
import j.<!INVISIBLE_REFERENCE!>JavaPackageLocal<!>.<!INVISIBLE_REFERENCE!>javaPPackage<!>
|
||||
|
||||
import j.JavaProtected
|
||||
import j.JavaProtected.javaMProtected
|
||||
import j.JavaProtected.javaPProtected
|
||||
|
||||
import j.JavaPrivate
|
||||
import j.JavaPrivate.<!INVISIBLE_REFERENCE!>javaMPrivate<!>
|
||||
import j.JavaPrivate.<!INVISIBLE_REFERENCE!>javaPPrivate<!>
|
||||
|
||||
// FILE: k2.kt
|
||||
package j
|
||||
|
||||
import j.JavaPublic
|
||||
import j.JavaPublic.javaM
|
||||
import j.JavaPublic.javaP
|
||||
import j.JavaPublic.javaPackageLocal
|
||||
|
||||
import j.JavaPackageLocal
|
||||
import j.JavaPackageLocal.javaMPackage
|
||||
import j.JavaPackageLocal.javaPPackage
|
||||
|
||||
import j.JavaProtected
|
||||
import j.JavaProtected.javaMProtected
|
||||
import j.JavaProtected.javaPProtected
|
||||
|
||||
import j.JavaPrivate
|
||||
import j.JavaPrivate.<!INVISIBLE_REFERENCE!>javaMPrivate<!>
|
||||
import j.JavaPrivate.<!INVISIBLE_REFERENCE!>javaPPrivate<!>
|
||||
@@ -0,0 +1,52 @@
|
||||
package
|
||||
|
||||
package j {
|
||||
|
||||
public/*package*/ open class JavaPackageLocal {
|
||||
public/*package*/ constructor JavaPackageLocal()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public/*package*/ final var javaPPackage: kotlin.Int
|
||||
public/*package*/ open fun javaMPackage(): kotlin.Unit
|
||||
}
|
||||
|
||||
public open class JavaPrivate {
|
||||
public constructor JavaPrivate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
private final var javaPPrivate: kotlin.Int
|
||||
private open fun javaMPrivate(): kotlin.Unit
|
||||
}
|
||||
|
||||
public open class JavaProtected {
|
||||
public constructor JavaProtected()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
protected/*protected static*/ final var javaPProtected: kotlin.Int
|
||||
protected/*protected static*/ open fun javaMProtected(): kotlin.Unit
|
||||
}
|
||||
|
||||
public open class JavaPublic {
|
||||
public constructor JavaPublic()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
// Static members
|
||||
public final var javaP: kotlin.Int
|
||||
public/*package*/ final var javaPackageLocal: kotlin.Int
|
||||
public open fun javaM(): kotlin.Unit
|
||||
}
|
||||
}
|
||||
|
||||
package k {
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
// MODULE: m1
|
||||
// FILE: k1.kt
|
||||
package k
|
||||
|
||||
private class KPrivate
|
||||
internal class KInternal
|
||||
public class KPublic
|
||||
|
||||
class A {
|
||||
protected class KProtected
|
||||
}
|
||||
|
||||
// FILE: k2.kt
|
||||
package k2
|
||||
|
||||
import k.<!INVISIBLE_REFERENCE!>KPrivate<!>
|
||||
import k.KInternal
|
||||
import k.KPublic
|
||||
import k.A.KProtected
|
||||
|
||||
// MODULE: m2(m1)
|
||||
// FILE: k3.kt
|
||||
package k3
|
||||
|
||||
import k.<!INVISIBLE_REFERENCE!>KPrivate<!>
|
||||
import k.<!INVISIBLE_REFERENCE!>KInternal<!>
|
||||
import k.KPublic
|
||||
import k.A.KProtected
|
||||
@@ -0,0 +1,74 @@
|
||||
// -- Module: <m1> --
|
||||
package
|
||||
|
||||
package k {
|
||||
|
||||
public final class A {
|
||||
public constructor A()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
|
||||
protected final class KProtected {
|
||||
public constructor KProtected()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
internal final class KInternal {
|
||||
public constructor KInternal()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
private final class KPrivate {
|
||||
public constructor KPrivate()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
|
||||
public final class KPublic {
|
||||
public constructor KPublic()
|
||||
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||
}
|
||||
}
|
||||
|
||||
package k2 {
|
||||
}
|
||||
|
||||
|
||||
// -- Module: <m2> --
|
||||
package
|
||||
|
||||
package k {
|
||||
|
||||
public final class A {
|
||||
// -- Module: <m1> --
|
||||
}
|
||||
|
||||
internal final class KInternal {
|
||||
// -- Module: <m1> --
|
||||
}
|
||||
|
||||
private final class KPrivate {
|
||||
// -- Module: <m1> --
|
||||
}
|
||||
|
||||
public final class KPublic {
|
||||
// -- Module: <m1> --
|
||||
}
|
||||
}
|
||||
|
||||
package k2 {
|
||||
}
|
||||
|
||||
package k3 {
|
||||
}
|
||||
|
||||
|
||||
@@ -6537,6 +6537,18 @@ public class JetDiagnosticsTestGenerated extends AbstractJetDiagnosticsTest {
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CheckJavaVisibility.kt")
|
||||
public void testCheckJavaVisibility() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/CheckJavaVisibility.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("CheckVisibility.kt")
|
||||
public void testCheckVisibility() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/CheckVisibility.kt");
|
||||
doTest(fileName);
|
||||
}
|
||||
|
||||
@TestMetadata("ClassClash.kt")
|
||||
public void testClassClash() throws Exception {
|
||||
String fileName = JetTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/imports/ClassClash.kt");
|
||||
|
||||
@@ -74,6 +74,7 @@ public fun JetElement.analyzeFullyAndGetResult(vararg extraFiles: JetFile): Anal
|
||||
return KotlinCacheService.getInstance(getProject()).getResolutionFacade(listOf(this) + extraFiles.toList()).analyzeFullyAndGetResult(listOf(this))
|
||||
}
|
||||
|
||||
// this method don't check visibility and collect all descriptors with given fqName
|
||||
public fun ResolutionFacade.resolveImportReference(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
fqName: FqName
|
||||
@@ -81,7 +82,7 @@ public fun ResolutionFacade.resolveImportReference(
|
||||
val importDirective = JetPsiFactory(project).createImportDirective(ImportPath(fqName, false))
|
||||
val qualifiedExpressionResolver = this.getFrontendService(moduleDescriptor, QualifiedExpressionResolver::class.java)
|
||||
return qualifiedExpressionResolver.processImportReference(
|
||||
importDirective, moduleDescriptor, BindingTraceContext(), moduleDescriptor).getAllDescriptors()
|
||||
importDirective, moduleDescriptor, BindingTraceContext(), packageFragmentForVisibilityCheck = null).getAllDescriptors()
|
||||
}
|
||||
|
||||
//NOTE: idea default API returns module search scope for file under module but not in source or production source (for example, test data )
|
||||
|
||||
Reference in New Issue
Block a user