Fix visibility checker for import.

This commit is contained in:
Stanislav Erokhin
2015-09-18 17:16:41 +03:00
parent e5334ed9b8
commit 1360f3cd43
9 changed files with 257 additions and 14 deletions
@@ -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 )