Allow to use "static" part of class in own constructors by short name, including in primary constructor

This commit is contained in:
Zalim Bashorov
2015-12-08 20:57:45 +03:00
parent f319b1b93a
commit 5bf8b4d946
30 changed files with 1017 additions and 25 deletions
@@ -27,6 +27,9 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor {
@NotNull
LexicalScope getScopeForClassHeaderResolution();
@NotNull
LexicalScope getScopeForConstructorHeaderResolution();
@NotNull
LexicalScope getScopeForMemberDeclarationResolution();
@@ -239,7 +239,7 @@ public class BodyResolver {
resolveDelegationSpecifierList(c.getOuterDataFlowInfo(), classOrObject, descriptor,
descriptor.getUnsubstitutedPrimaryConstructor(),
descriptor.getScopeForClassHeaderResolution(),
descriptor.getScopeForConstructorHeaderResolution(),
descriptor.getScopeForMemberDeclarationResolution());
}
}
@@ -249,13 +249,13 @@ public class BodyResolver {
@NotNull KtClassOrObject jetClass,
@NotNull final ClassDescriptor descriptor,
@Nullable final ConstructorDescriptor primaryConstructor,
@NotNull LexicalScope scopeForSupertypeResolution,
@NotNull LexicalScope scopeForConstructorResolution,
@NotNull final LexicalScope scopeForMemberResolution
) {
final LexicalScope scopeForConstructor =
primaryConstructor == null
? null
: FunctionDescriptorUtil.getFunctionInnerScope(scopeForSupertypeResolution, primaryConstructor, trace);
: FunctionDescriptorUtil.getFunctionInnerScope(scopeForConstructorResolution, primaryConstructor, trace);
final ExpressionTypingServices typeInferrer = expressionTypingServices; // TODO : flow
final Map<KtTypeReference, KotlinType> supertypes = Maps.newLinkedHashMap();
@@ -556,7 +556,7 @@ public class BodyResolver {
if (unsubstitutedPrimaryConstructor != null) {
ForceResolveUtil.forceResolveAllContents(unsubstitutedPrimaryConstructor.getAnnotations());
LexicalScope parameterScope = getPrimaryConstructorParametersScope(classDescriptor.getScopeForClassHeaderResolution(),
LexicalScope parameterScope = getPrimaryConstructorParametersScope(classDescriptor.getScopeForConstructorHeaderResolution(),
unsubstitutedPrimaryConstructor);
valueParameterResolver.resolveValueParameters(klass.getPrimaryConstructorParameters(),
unsubstitutedPrimaryConstructor.getValueParameters(),
@@ -22,6 +22,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.psi.KtParameter
import org.jetbrains.kotlin.resolve.descriptorUtil.getSuperClassNotAny
import org.jetbrains.kotlin.resolve.scopes.*
import org.jetbrains.kotlin.resolve.scopes.utils.ThrowingLexicalScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.utils.addIfNotNull
import java.util.*
@@ -42,13 +43,17 @@ class ClassResolutionScopesSupport(
scopeWithGenerics(getOuterScope())
}
public val scopeForConstructorHeaderResolution: () -> LexicalScope = storageManager.createLazyValue {
scopeWithGenerics(scopeForStaticMemberDeclarationResolution())
}
private val inheritanceScope: () -> LexicalScope = storageManager.createLazyValueWithPostCompute(
{
classDescriptor.getAllSuperclassesAndMeWithoutAny().asReversed().fold(getOuterScope()) { scope, currentClass ->
createInheritanceScope(parent = scope, ownerDescriptor = classDescriptor, classDescriptor = currentClass)
}
},
{ createInheritanceScope(getOuterScope(), classDescriptor, classDescriptor) },
createThrowingLexicalScope,
{}
)
@@ -59,15 +64,19 @@ class ClassResolutionScopesSupport(
LexicalScopeKind.CLASS_MEMBER_SCOPE)
}
public val scopeForStaticMemberDeclarationResolution: () -> LexicalScope = storageManager.createLazyValue {
if (classDescriptor.kind.isSingleton) {
scopeForMemberDeclarationResolution()
}
else {
LexicalScopeImpl(inheritanceScope(), classDescriptor, false, null,
LexicalScopeKind.CLASS_STATIC_SCOPE)
}
}
public val scopeForStaticMemberDeclarationResolution: () -> LexicalScope = storageManager.createLazyValueWithPostCompute(
{
if (classDescriptor.kind.isSingleton) {
scopeForMemberDeclarationResolution()
}
else {
LexicalScopeImpl(inheritanceScope(), classDescriptor, false, null,
LexicalScopeKind.CLASS_STATIC_SCOPE)
}
},
createThrowingLexicalScope,
{}
)
public val scopeForInitializerResolution: () -> LexicalScope = storageManager.createLazyValue {
val primaryConstructor = classDescriptor.unsubstitutedPrimaryConstructor ?:
@@ -118,4 +127,7 @@ class ClassResolutionScopesSupport(
memberScopes = *staticScopes.toTypedArray(), isStaticScope = true)
}
}
companion object {
private val createThrowingLexicalScope: (Boolean) -> LexicalScope = { ThrowingLexicalScope() }
}
}
@@ -292,6 +292,12 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
return resolutionScopesSupport.getScopeForClassHeaderResolution().invoke();
}
@Override
@NotNull
public LexicalScope getScopeForConstructorHeaderResolution() {
return resolutionScopesSupport.getScopeForConstructorHeaderResolution().invoke();
}
@Override
@NotNull
public LexicalScope getScopeForMemberDeclarationResolution() {
@@ -221,7 +221,8 @@ public open class LazyClassMemberScope(
val parameter = primaryConstructorParameters.get(valueParameterDescriptor.index)
if (parameter.hasValOrVar()) {
val propertyDescriptor = c.descriptorResolver.resolvePrimaryConstructorParameterToAProperty(
thisDescriptor, valueParameterDescriptor, thisDescriptor.getScopeForClassHeaderResolution(), parameter, trace)
// TODO: can't test because we get types from cache for this case
thisDescriptor, valueParameterDescriptor, thisDescriptor.scopeForConstructorHeaderResolution, parameter, trace)
result.add(propertyDescriptor)
}
}
@@ -281,7 +282,7 @@ public open class LazyClassMemberScope(
if (DescriptorUtils.canHaveDeclaredConstructors(thisDescriptor) || hasPrimaryConstructor) {
val constructor = c.functionDescriptorResolver.resolvePrimaryConstructorDescriptor(
thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, classOrObject, trace)
thisDescriptor.scopeForConstructorHeaderResolution, thisDescriptor, classOrObject, trace)
constructor ?: return null
setDeferredReturnType(constructor)
return constructor
@@ -298,7 +299,7 @@ public open class LazyClassMemberScope(
return classOrObject.getSecondaryConstructors().map { constructor ->
val descriptor = c.functionDescriptorResolver.resolveSecondaryConstructorDescriptor(
thisDescriptor.getScopeForClassHeaderResolution(), thisDescriptor, constructor, trace
thisDescriptor.scopeForConstructorHeaderResolution, thisDescriptor, constructor, trace
)
setDeferredReturnType(descriptor)
descriptor
@@ -55,6 +55,7 @@ interface LexicalScope: HierarchicalScope {
enum class LexicalScopeKind(val withLocalDescriptors: Boolean) {
EMPTY(false),
THROWING(false),
CLASS_HEADER(false),
CLASS_INHERITANCE(false),
@@ -147,4 +148,4 @@ abstract class BaseImportingScope(parent: ImportingScope?) : BaseHierarchicalSco
override fun getContributedSyntheticExtensionProperties(receiverTypes: Collection<KotlinType>): Collection<PropertyDescriptor> = emptyList()
override fun getContributedSyntheticExtensionFunctions(receiverTypes: Collection<KotlinType>): Collection<FunctionDescriptor> = emptyList()
}
}
@@ -245,3 +245,32 @@ fun chainImportingScopes(scopes: List<ImportingScope>, tail: ImportingScope? = n
scope.withParent(current)
}
}
class ThrowingLexicalScope : LexicalScope {
override val parent: HierarchicalScope
get() = throw IllegalStateException()
override val ownerDescriptor: DeclarationDescriptor
get() = throw IllegalStateException()
override val isOwnerDescriptorAccessibleByLabel: Boolean
get() = throw IllegalStateException()
override val implicitReceiver: ReceiverParameterDescriptor?
get() = throw IllegalStateException()
override val kind: LexicalScopeKind
get() = LexicalScopeKind.THROWING
override fun printStructure(p: Printer) =
throw IllegalStateException()
override fun getContributedClassifier(name: Name, location: LookupLocation): ClassifierDescriptor? =
throw IllegalStateException()
override fun getContributedVariables(name: Name, location: LookupLocation): Collection<VariableDescriptor> =
throw IllegalStateException()
override fun getContributedFunctions(name: Name, location: LookupLocation): Collection<FunctionDescriptor> =
throw IllegalStateException()
override fun getContributedDescriptors(kindFilter: DescriptorKindFilter, nameFilter: (Name) -> Boolean): Collection<DeclarationDescriptor> =
throw IllegalStateException()
}