Add ModuleDescriptor.assertValid() for ensuring consistency

This commit is contained in:
Dmitry Jemerov
2017-08-04 18:45:58 +02:00
parent ac96c31a7d
commit 3415853cac
8 changed files with 32 additions and 4 deletions
@@ -96,7 +96,12 @@ class ResolverForProjectImpl<M : ModuleInfo>(
val moduleDescriptor: ModuleDescriptorImpl, val moduleDescriptor: ModuleDescriptorImpl,
val modificationTracker: ModificationTracker?, val modificationTracker: ModificationTracker?,
val modificationCount: Long? val modificationCount: Long?
) ) {
fun isOutOfDate(): Boolean {
val currentModCount = modificationTracker?.modificationCount
return currentModCount != null && currentModCount > modificationCount!!
}
}
private val descriptorByModule = mutableMapOf<M, ModuleData>() private val descriptorByModule = mutableMapOf<M, ModuleData>()
private val moduleInfoByDescriptor = mutableMapOf<ModuleDescriptorImpl, M>() private val moduleInfoByDescriptor = mutableMapOf<ModuleDescriptorImpl, M>()
@@ -171,8 +176,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
var moduleData = descriptorByModule.getOrPut(module) { var moduleData = descriptorByModule.getOrPut(module) {
createModuleDescriptor(module) createModuleDescriptor(module)
} }
val currentModCount = moduleData.modificationTracker?.modificationCount if (moduleData.isOutOfDate()) {
if (currentModCount != null && currentModCount > moduleData.modificationCount!!) {
moduleData = recreateModuleDescriptor(module) moduleData = recreateModuleDescriptor(module)
} }
moduleData.moduleDescriptor moduleData.moduleDescriptor
@@ -280,6 +280,7 @@ public class LazyDeclarationResolver {
if (isTopLevel) { // for top level declarations we search directly in package because of possible conflicts with imports if (isTopLevel) { // for top level declarations we search directly in package because of possible conflicts with imports
KtFile ktFile = (KtFile) declaration.getContainingFile(); KtFile ktFile = (KtFile) declaration.getContainingFile();
FqName fqName = ktFile.getPackageFqName(); FqName fqName = ktFile.getPackageFqName();
topLevelDescriptorProvider.assertValid();
LazyPackageDescriptor packageDescriptor = topLevelDescriptorProvider.getPackageFragment(fqName); LazyPackageDescriptor packageDescriptor = topLevelDescriptorProvider.getPackageFragment(fqName);
if (packageDescriptor == null) { if (packageDescriptor == null) {
if (topLevelDescriptorProvider instanceof LazyClassContext) { if (topLevelDescriptorProvider instanceof LazyClassContext) {
@@ -188,6 +188,7 @@ class LazyImportResolver(
} }
fun getImportScope(directive: KtImportDirective): ImportingScope { fun getImportScope(directive: KtImportDirective): ImportingScope {
moduleDescriptor.assertValid()
return importedScopesProvider(directive) ?: ImportingScope.Empty return importedScopesProvider(directive) ?: ImportingScope.Empty
} }
} }
@@ -308,6 +308,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
@Override @Override
@NotNull @NotNull
public DeclarationDescriptor resolveToDescriptor(@NotNull KtDeclaration declaration) { public DeclarationDescriptor resolveToDescriptor(@NotNull KtDeclaration declaration) {
assertValid();
if (!areDescriptorsCreatedForDeclaration(declaration)) { if (!areDescriptorsCreatedForDeclaration(declaration)) {
throw new IllegalStateException( throw new IllegalStateException(
"No descriptors are created for declarations of type " + declaration.getClass().getSimpleName() "No descriptors are created for declarations of type " + declaration.getClass().getSimpleName()
@@ -449,4 +450,9 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
public WrappedTypeFactory getWrappedTypeFactory() { public WrappedTypeFactory getWrappedTypeFactory() {
return wrappedTypeFactory; return wrappedTypeFactory;
} }
@Override
public void assertValid() {
module.assertValid();
}
} }
@@ -25,6 +25,8 @@ interface TopLevelDescriptorProvider {
fun getPackageFragment(fqName: FqName): LazyPackageDescriptor? fun getPackageFragment(fqName: FqName): LazyPackageDescriptor?
fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassifierDescriptor> fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassifierDescriptor>
fun assertValid()
} }
object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider { object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider {
@@ -37,4 +39,8 @@ object NoTopLevelDescriptorProvider : TopLevelDescriptorProvider {
override fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassifierDescriptor> { override fun getTopLevelClassifierDescriptors(fqName: FqName, location: LookupLocation): Collection<ClassifierDescriptor> {
shouldNotBeCalled() shouldNotBeCalled()
} }
override fun assertValid() {
shouldNotBeCalled()
}
} }
@@ -50,4 +50,6 @@ interface ModuleDescriptor : DeclarationDescriptor {
} }
val isValid: Boolean val isValid: Boolean
fun assertValid()
} }
@@ -48,8 +48,11 @@ class ModuleDescriptorImpl @JvmOverloads constructor(
private var packageFragmentProviderForModuleContent: PackageFragmentProvider? = null private var packageFragmentProviderForModuleContent: PackageFragmentProvider? = null
override var isValid: Boolean = true override var isValid: Boolean = true
set(value) {
field = value
}
private fun assertValid() { override fun assertValid() {
if (!isValid) { if (!isValid) {
throw IllegalStateException("Accessing invalid module descriptor $this") throw IllegalStateException("Accessing invalid module descriptor $this")
} }
@@ -127,6 +127,11 @@ public class ErrorUtils {
public boolean isValid() { public boolean isValid() {
return false; return false;
} }
@Override
public void assertValid() {
throw new IllegalStateException("ERROR_MODULE is not a valid module");
}
}; };
} }