@@ -41,13 +41,14 @@ import org.jetbrains.kotlin.resolve.CompilerEnvironment
41
41
import org.jetbrains.kotlin.resolve.MultiTargetPlatform
42
42
import org.jetbrains.kotlin.resolve.TargetEnvironment
43
43
import org.jetbrains.kotlin.resolve.TargetPlatform
44
+ import org.jetbrains.kotlin.storage.NotNullLazyValue
44
45
import org.jetbrains.kotlin.utils.keysToMap
45
46
import java.util.*
46
47
import kotlin.coroutines.experimental.buildSequence
47
48
48
49
class ResolverForModule (
49
- val packageFragmentProvider : PackageFragmentProvider ,
50
- val componentProvider : ComponentProvider
50
+ val packageFragmentProvider : PackageFragmentProvider ,
51
+ val componentProvider : ComponentProvider
51
52
)
52
53
53
54
abstract class ResolverForProject <M : ModuleInfo > {
@@ -84,7 +85,7 @@ class ResolverForProjectImpl<M : ModuleInfo>(
84
85
return resolverForModuleDescriptor(doGetDescriptorForModule(moduleInfo))
85
86
}
86
87
87
- internal val resolverByModuleDescriptor: MutableMap <ModuleDescriptor , () - > ResolverForModule > = HashMap ()
88
+ internal val resolverByModuleDescriptor: MutableMap <ModuleDescriptor , NotNullLazyValue < ResolverForModule > > = HashMap ()
88
89
89
90
override val allModules: Collection <M > by lazy {
90
91
(descriptorByModule.keys + delegateResolver.allModules).toSet()
@@ -168,7 +169,8 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
168
169
delegateResolver : ResolverForProject <M > = EmptyResolverForProject (),
169
170
packagePartProviderFactory : (M , ModuleContent ) -> PackagePartProvider = { _, _ -> PackagePartProvider .Empty },
170
171
firstDependency : M ? = null,
171
- modulePlatforms : (M ) -> MultiTargetPlatform ?
172
+ modulePlatforms : (M ) -> MultiTargetPlatform ? ,
173
+ packageOracleFactory : PackageOracleFactory = PackageOracleFactory .OptimisticFactory
172
174
): ResolverForProject <M > {
173
175
val storageManager = projectContext.storageManager
174
176
@@ -212,18 +214,20 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
212
214
213
215
for (module in modules) {
214
216
val descriptor = resolverForProject.descriptorForModule(module)
217
+ val content = modulesContent(module)
215
218
val computeResolverForModule = storageManager.createLazyValue {
216
219
ResolverForModuleComputationTracker .getInstance(projectContext.project)?.onResolverComputed(module)
217
220
218
- val content = modulesContent(module)
219
221
analyzerFacade(module).createResolverForModule(
220
222
module, descriptor, projectContext.withModule(descriptor), modulesContent(module),
221
223
platformParameters, targetEnvironment, resolverForProject,
222
224
packagePartProviderFactory(module, content)
223
225
)
224
226
}
225
227
226
- descriptor.initialize(DelegatingPackageFragmentProvider { computeResolverForModule().packageFragmentProvider })
228
+ DelegatingPackageFragmentProvider (content, packageOracleFactory.createOracle(module), computeResolverForModule)
229
+ .let { descriptor.initialize(it) }
230
+
227
231
resolverForProject.resolverByModuleDescriptor[descriptor] = computeResolverForModule
228
232
}
229
233
@@ -245,17 +249,45 @@ abstract class AnalyzerFacade<in P : PlatformAnalysisParameters> {
245
249
abstract val targetPlatform: TargetPlatform
246
250
}
247
251
248
- // NOTE: relies on delegate to be lazily computed and cached
249
252
private class DelegatingPackageFragmentProvider (
250
- private val delegate : () -> PackageFragmentProvider
253
+ moduleContent : ModuleContent ,
254
+ private val packageOracle : PackageOracle ,
255
+ private val resolverForModule : NotNullLazyValue <ResolverForModule >
251
256
) : PackageFragmentProvider {
257
+ private val syntheticFilePackages = moduleContent.syntheticFiles.map { it.packageFqName }.toSet()
252
258
253
259
override fun getPackageFragments (fqName : FqName ): List <PackageFragmentDescriptor > {
254
- return delegate().getPackageFragments(fqName)
260
+ if (certainlyDoesNotExist(fqName)) return emptyList()
261
+
262
+ return resolverForModule().packageFragmentProvider.getPackageFragments(fqName)
255
263
}
256
264
257
265
override fun getSubPackagesOf (fqName : FqName , nameFilter : (Name ) -> Boolean ): Collection <FqName > {
258
- return delegate().getSubPackagesOf(fqName, nameFilter)
266
+ if (certainlyDoesNotExist(fqName)) return emptyList()
267
+
268
+ return resolverForModule().packageFragmentProvider.getSubPackagesOf(fqName, nameFilter)
269
+ }
270
+
271
+ private fun certainlyDoesNotExist (fqName : FqName ): Boolean {
272
+ if (resolverForModule.isComputed()) return false // let this request get cached inside delegate
273
+
274
+ return ! packageOracle.packageExists(fqName) && fqName !in syntheticFilePackages
275
+ }
276
+ }
277
+
278
+ interface PackageOracle {
279
+ fun packageExists (fqName : FqName ): Boolean
280
+
281
+ object Optimistic : PackageOracle {
282
+ override fun packageExists (fqName : FqName ): Boolean = true
283
+ }
284
+ }
285
+
286
+ interface PackageOracleFactory {
287
+ fun createOracle (moduleInfo : ModuleInfo ): PackageOracle
288
+
289
+ object OptimisticFactory : PackageOracleFactory {
290
+ override fun createOracle (moduleInfo : ModuleInfo ) = PackageOracle .Optimistic
259
291
}
260
292
}
261
293
0 commit comments