Introduce 'SupertypeLoopsResolver' and inject it's impls

This commit is contained in:
Denis Zharkov
2015-10-29 09:01:14 +03:00
parent 0bc5043c75
commit 18097c0ab7
10 changed files with 92 additions and 20 deletions
@@ -47,6 +47,12 @@ public fun StorageComponentContainer.configureModule(
for (extension in StorageComponentContainerContributor.getInstances(moduleContext.project)) { for (extension in StorageComponentContainerContributor.getInstances(moduleContext.project)) {
extension.addDeclarations(this, platform) extension.addDeclarations(this, platform)
} }
configurePlatformIndependentComponents()
}
private fun StorageComponentContainer.configurePlatformIndependentComponents() {
useImpl<SupertypeLoopCheckerImpl>()
} }
public fun StorageComponentContainer.configureModule( public fun StorageComponentContainer.configureModule(
@@ -78,6 +78,7 @@ public class DescriptorResolver {
@NotNull private final StorageManager storageManager; @NotNull private final StorageManager storageManager;
@NotNull private final KotlinBuiltIns builtIns; @NotNull private final KotlinBuiltIns builtIns;
@NotNull private final ConstantExpressionEvaluator constantExpressionEvaluator; @NotNull private final ConstantExpressionEvaluator constantExpressionEvaluator;
@NotNull private final SupertypeLoopChecker supertypeLoopsResolver;
public DescriptorResolver( public DescriptorResolver(
@NotNull AnnotationResolver annotationResolver, @NotNull AnnotationResolver annotationResolver,
@@ -86,7 +87,8 @@ public class DescriptorResolver {
@NotNull ExpressionTypingServices expressionTypingServices, @NotNull ExpressionTypingServices expressionTypingServices,
@NotNull StorageManager storageManager, @NotNull StorageManager storageManager,
@NotNull TypeResolver typeResolver, @NotNull TypeResolver typeResolver,
@NotNull ConstantExpressionEvaluator constantExpressionEvaluator @NotNull ConstantExpressionEvaluator constantExpressionEvaluator,
@NotNull SupertypeLoopChecker supertypeLoopsResolver
) { ) {
this.annotationResolver = annotationResolver; this.annotationResolver = annotationResolver;
this.builtIns = builtIns; this.builtIns = builtIns;
@@ -95,6 +97,7 @@ public class DescriptorResolver {
this.storageManager = storageManager; this.storageManager = storageManager;
this.typeResolver = typeResolver; this.typeResolver = typeResolver;
this.constantExpressionEvaluator = constantExpressionEvaluator; this.constantExpressionEvaluator = constantExpressionEvaluator;
this.supertypeLoopsResolver = supertypeLoopsResolver;
} }
public List<KotlinType> resolveSupertypes( public List<KotlinType> resolveSupertypes(
@@ -17,25 +17,28 @@
@file:JvmName("FindLoopsInSupertypes") @file:JvmName("FindLoopsInSupertypes")
package org.jetbrains.kotlin.resolve package org.jetbrains.kotlin.resolve
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor import org.jetbrains.kotlin.types.TypeConstructor
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
fun findLoopsInSupertypesAndDisconnect( class SupertypeLoopCheckerImpl : SupertypeLoopChecker {
currentTypeConstructor: TypeConstructor, override fun findLoopsInSupertypesAndDisconnect(
superTypes: MutableCollection<KotlinType>, currentTypeConstructor: TypeConstructor,
neighbors: (TypeConstructor) -> Iterable<KotlinType>, superTypes: MutableCollection<KotlinType>,
reportLoopAt: (KotlinType) -> Unit neighbors: (TypeConstructor) -> Iterable<KotlinType>,
) { reportLoop: (KotlinType) -> Unit
) {
val graph = DFS.Neighbors<TypeConstructor> { node -> neighbors(node).map { it.constructor } } val graph = DFS.Neighbors<TypeConstructor> { node -> neighbors(node).map { it.constructor } }
val iterator = superTypes.iterator() val iterator = superTypes.iterator()
while (iterator.hasNext()) { while (iterator.hasNext()) {
val item = iterator.next() val item = iterator.next()
if (isReachable(item.constructor, currentTypeConstructor, graph)) { if (isReachable(item.constructor, currentTypeConstructor, graph)) {
iterator.remove() iterator.remove()
reportLoopAt(item) reportLoop(item)
}
} }
} }
} }
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.lazy package org.jetbrains.kotlin.resolve.lazy
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
import org.jetbrains.kotlin.resolve.* import org.jetbrains.kotlin.resolve.*
import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory import org.jetbrains.kotlin.resolve.lazy.declarations.DeclarationProviderFactory
@@ -34,4 +35,5 @@ public interface LazyClassContext {
val declarationProviderFactory: DeclarationProviderFactory val declarationProviderFactory: DeclarationProviderFactory
val annotationResolver: AnnotationResolver val annotationResolver: AnnotationResolver
val lookupTracker: LookupTracker val lookupTracker: LookupTracker
val supertypeLoopChecker: SupertypeLoopChecker
} }
@@ -79,6 +79,7 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
private DeclarationScopeProvider declarationScopeProvider; private DeclarationScopeProvider declarationScopeProvider;
private LookupTracker lookupTracker; private LookupTracker lookupTracker;
private LocalDescriptorResolver localDescriptorResolver; private LocalDescriptorResolver localDescriptorResolver;
private SupertypeLoopChecker supertypeLoopsResolver;
@Inject @Inject
public void setJetImportFactory(KtImportsFactory jetImportFactory) { public void setJetImportFactory(KtImportsFactory jetImportFactory) {
@@ -411,6 +412,17 @@ public class ResolveSession implements KotlinCodeAnalyzer, LazyClassContext {
return lookupTracker; return lookupTracker;
} }
@NotNull
@Override
public SupertypeLoopChecker getSupertypeLoopChecker() {
return supertypeLoopsResolver;
}
@Inject
public void setSupertypeLoopsResolver(@NotNull SupertypeLoopChecker supertypeLoopsResolver) {
this.supertypeLoopsResolver = supertypeLoopsResolver;
}
@Inject @Inject
public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) { public void setLocalDescriptorResolver(@NotNull LocalDescriptorResolver localDescriptorResolver) {
this.localDescriptorResolver = localDescriptorResolver; this.localDescriptorResolver = localDescriptorResolver;
@@ -582,7 +582,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
} }
private void findAndDisconnectLoopsInTypeHierarchy(@Mutable Collection<KotlinType> supertypes) { private void findAndDisconnectLoopsInTypeHierarchy(@Mutable Collection<KotlinType> supertypes) {
FindLoopsInSupertypes.findLoopsInSupertypesAndDisconnect( c.getSupertypeLoopChecker().findLoopsInSupertypesAndDisconnect(
typeConstructor, supertypes, typeConstructor, supertypes,
new Function1<TypeConstructor, Iterable<? extends KotlinType>>() { new Function1<TypeConstructor, Iterable<? extends KotlinType>>() {
@Override @Override
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.context.withProject
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.frontend.di.createContainerForLazyLocalClassifierAnalyzer import org.jetbrains.kotlin.frontend.di.createContainerForLazyLocalClassifierAnalyzer
import org.jetbrains.kotlin.incremental.components.LookupLocation import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.incremental.components.LookupTracker import org.jetbrains.kotlin.incremental.components.LookupTracker
@@ -54,7 +55,8 @@ public class LocalClassifierAnalyzer(
private val typeResolver: TypeResolver, private val typeResolver: TypeResolver,
private val annotationResolver: AnnotationResolver, private val annotationResolver: AnnotationResolver,
private val platform: TargetPlatform, private val platform: TargetPlatform,
private val dynamicTypesSettings: DynamicTypesSettings private val dynamicTypesSettings: DynamicTypesSettings,
private val supertypeLoopChecker: SupertypeLoopChecker
) { ) {
fun processClassOrObject( fun processClassOrObject(
scope: LexicalWritableScope?, scope: LexicalWritableScope?,
@@ -78,7 +80,8 @@ public class LocalClassifierAnalyzer(
descriptorResolver, descriptorResolver,
funcionDescriptorResolver, funcionDescriptorResolver,
typeResolver, typeResolver,
annotationResolver annotationResolver,
supertypeLoopChecker
) )
) )
@@ -100,7 +103,8 @@ class LocalClassDescriptorHolder(
val descriptorResolver: DescriptorResolver, val descriptorResolver: DescriptorResolver,
val functionDescriptorResolver: FunctionDescriptorResolver, val functionDescriptorResolver: FunctionDescriptorResolver,
val typeResolver: TypeResolver, val typeResolver: TypeResolver,
val annotationResolver: AnnotationResolver val annotationResolver: AnnotationResolver,
val supertypeLoopChecker: SupertypeLoopChecker
) { ) {
// We do not need to synchronize here, because this code is used strictly from one thread // We do not need to synchronize here, because this code is used strictly from one thread
private var classDescriptor: ClassDescriptor? = null private var classDescriptor: ClassDescriptor? = null
@@ -132,6 +136,7 @@ class LocalClassDescriptorHolder(
} }
override val annotationResolver = this@LocalClassDescriptorHolder.annotationResolver override val annotationResolver = this@LocalClassDescriptorHolder.annotationResolver
override val lookupTracker: LookupTracker = LookupTracker.DO_NOTHING override val lookupTracker: LookupTracker = LookupTracker.DO_NOTHING
override val supertypeLoopChecker = this@LocalClassDescriptorHolder.supertypeLoopChecker
} }
, ,
containingDeclaration, containingDeclaration,
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackagePartProvider import org.jetbrains.kotlin.descriptors.PackagePartProvider
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.load.java.JavaClassFinder import org.jetbrains.kotlin.load.java.JavaClassFinder
import org.jetbrains.kotlin.load.java.components.ExternalAnnotationResolver import org.jetbrains.kotlin.load.java.components.ExternalAnnotationResolver
import org.jetbrains.kotlin.load.java.components.ExternalSignatureResolver import org.jetbrains.kotlin.load.java.components.ExternalSignatureResolver
@@ -47,7 +48,8 @@ class JavaResolverComponents(
val samConversionResolver: SamConversionResolver, val samConversionResolver: SamConversionResolver,
val sourceElementFactory: JavaSourceElementFactory, val sourceElementFactory: JavaSourceElementFactory,
val moduleClassResolver: ModuleClassResolver, val moduleClassResolver: ModuleClassResolver,
val packageMapper: PackagePartProvider val packageMapper: PackagePartProvider,
val supertypeLoopChecker: SupertypeLoopChecker
) )
open class LazyJavaResolverContext( open class LazyJavaResolverContext(
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.load.kotlin.reflect
import org.jetbrains.kotlin.builtins.ReflectionTypes import org.jetbrains.kotlin.builtins.ReflectionTypes
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.ModuleParameters import org.jetbrains.kotlin.descriptors.ModuleParameters
import org.jetbrains.kotlin.descriptors.SupertypeLoopChecker
import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl import org.jetbrains.kotlin.descriptors.impl.ModuleDescriptorImpl
import org.jetbrains.kotlin.load.java.components.* import org.jetbrains.kotlin.load.java.components.*
import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents import org.jetbrains.kotlin.load.java.lazy.JavaResolverComponents
@@ -57,7 +58,7 @@ public class RuntimeModuleData private constructor(public val deserialization: D
storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver, storageManager, ReflectJavaClassFinder(classLoader), reflectKotlinClassFinder, deserializedDescriptorResolver,
ExternalAnnotationResolver.EMPTY, ExternalSignatureResolver.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY, ExternalAnnotationResolver.EMPTY, ExternalSignatureResolver.DO_NOTHING, RuntimeErrorReporter, JavaResolverCache.EMPTY,
JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver, JavaPropertyInitializerEvaluator.DoNothing, SamConversionResolver, RuntimeSourceElementFactory, singleModuleClassResolver,
runtimePackageFacadeProvider runtimePackageFacadeProvider, SupertypeLoopChecker.EMPTY
) )
val lazyJavaPackageFragmentProvider = val lazyJavaPackageFragmentProvider =
@@ -0,0 +1,38 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.TypeConstructor
interface SupertypeLoopChecker {
fun findLoopsInSupertypesAndDisconnect(
currentTypeConstructor: TypeConstructor,
superTypes: MutableCollection<KotlinType>,
neighbors: (TypeConstructor) -> Iterable<KotlinType>,
reportLoop: (KotlinType) -> Unit
)
object EMPTY : SupertypeLoopChecker {
override fun findLoopsInSupertypesAndDisconnect(
currentTypeConstructor: TypeConstructor,
superTypes: MutableCollection<KotlinType>,
neighbors: (TypeConstructor) -> Iterable<KotlinType>,
reportLoop: (KotlinType) -> Unit) {
}
}
}