Move DeclarationDescriptor.substitute to separate interface Substitutable

To get rid of pointless/confusing implementations in ModuleDescriptor,
PackageViewDescriptor, TypeParameterDescriptor and others.

Note that there are still implementations that do not make sense, for
example in those subclasses of VariableDescriptor which are not also
subclasses of CallableMemberDescriptor (e.g. ValueParameterDescriptor).
Those can be removed by making CallableMemberDescriptor (instead of
CallableDescriptor) inherit from Substitutable. However, that would
require more changes in the compiler because CallableDescriptor is used
rather often in places where in fact only CallableMemberDescriptor
instances can appear.

Explicit return types and casts are required in some places now because
there's no single non-trivial supertype for
ClassifierDescriptorWithTypeParameters and CallableDescriptor.
Previously it was DeclarationDescriptorWithVisibility, now it's both
that and Substitutable<...>
This commit is contained in:
Alexander Udalov
2017-04-12 15:11:47 +03:00
parent 9f037c3c62
commit bbdff8c7ce
24 changed files with 53 additions and 83 deletions
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor;
import org.jetbrains.kotlin.descriptors.annotations.Annotations;
import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.types.TypeSubstitutor;
public class RootContext extends CodegenContext<RootContext.FakeDescriptor> {
private final GenerationState state;
@@ -56,11 +55,6 @@ public class RootContext extends CodegenContext<RootContext.FakeDescriptor> {
throw new IllegalStateException();
}
@Override
public DeclarationDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
throw new IllegalStateException();
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
throw new IllegalStateException();
@@ -91,7 +91,7 @@ class OverloadResolver(
collectModulePackageMembersWithSameName(
packageMembersByName,
c.functions.values + c.declaredClasses.values + c.typeAliases.values,
(c.functions.values as Collection<DeclarationDescriptor>) + c.declaredClasses.values + c.typeAliases.values,
overloadFilter
) {
scope, name ->
@@ -31,7 +31,7 @@ object UnderscoreUsageChecker : CallChecker {
override fun check(resolvedCall: ResolvedCall<*>, reportOn: PsiElement, context: CallCheckerContext) {
if (resolvedCall is VariableAsFunctionResolvedCall) return
val descriptor = resolvedCall.resultingDescriptor
val namedDescriptor = if (descriptor is ConstructorDescriptor) descriptor.containingDeclaration else descriptor
val namedDescriptor: DeclarationDescriptor = (descriptor as? ConstructorDescriptor)?.containingDeclaration ?: descriptor
if (!namedDescriptor.name.asString().isUnderscoreOnlyName()) return
checkCallElement(resolvedCall.call.callElement, context)
}
@@ -38,7 +38,6 @@ import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
import org.jetbrains.kotlin.script.getScriptExternalDependencies
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.utils.Printer
data class FileScopes(val lexicalScope: LexicalScope, val importingScope: ImportingScope, val importResolver: ImportResolver)
@@ -236,7 +235,6 @@ class FileScopeFactory(
override fun getOriginal() = this
override val annotations: Annotations get() = Annotations.EMPTY
override fun substitute(substitutor: TypeSubstitutor) = this
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R {
throw UnsupportedOperationException()
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.resolve.lazy.LazyEntity
import org.jetbrains.kotlin.resolve.scopes.LexicalScope
import org.jetbrains.kotlin.resolve.source.toSourceElement
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.types.TypeSubstitutor
abstract class LazyAnnotationsContext(
val annotationResolver: AnnotationResolver,
@@ -172,7 +171,6 @@ class LazyAnnotationDescriptor(
override fun getName() = Name.special("< file descriptor for annotation resolution >")
private fun error(): Nothing = error("This method should not be called")
override fun substitute(substitutor: TypeSubstitutor): DeclarationDescriptor? = error()
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>?, data: D): R = error()
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) = error()
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.types.TypeSubstitutor
interface IrBuiltinsPackageFragmentDescriptor : PackageFragmentDescriptor
@@ -40,7 +39,6 @@ class IrBuiltinsPackageFragmentDescriptorImpl(
override fun getOriginal(): DeclarationDescriptorWithSource = this
override fun getSource(): SourceElement = SourceElement.NO_SOURCE
override val annotations: Annotations = Annotations.EMPTY
override fun substitute(substitutor: TypeSubstitutor): DeclarationDescriptor = throw UnsupportedOperationException()
override fun <R : Any?, D : Any?> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
return visitor.visitPackageFragmentDescriptor(this, data)
@@ -50,5 +48,3 @@ class IrBuiltinsPackageFragmentDescriptorImpl(
visitor.visitPackageFragmentDescriptor(this, null)
}
}
@@ -45,7 +45,6 @@ import org.jetbrains.kotlin.test.KotlinTestUtils.TestFileFactoryNoModules
import org.jetbrains.kotlin.test.util.DescriptorValidator.ValidationVisitor.errorTypesForbidden
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator
import org.jetbrains.kotlin.test.util.RecursiveDescriptorComparator.Configuration
import org.jetbrains.kotlin.types.TypeSubstitutor
import org.jetbrains.kotlin.utils.Printer
import org.jetbrains.kotlin.utils.sure
import java.io.File
@@ -221,7 +220,6 @@ abstract class AbstractJvmRuntimeDescriptorLoaderTest : TestCaseWithTmpdir() {
override fun getContainingDeclaration() = null
override fun getOriginal() = throw UnsupportedOperationException()
override fun substitute(substitutor: TypeSubstitutor) = throw UnsupportedOperationException()
override fun acceptVoid(visitor: DeclarationDescriptorVisitor<Void, Void>?) = throw UnsupportedOperationException()
override fun getName() = throw UnsupportedOperationException()
override val annotations: Annotations
@@ -20,12 +20,12 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.annotations.ReadOnly;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import java.util.Collection;
import java.util.List;
public interface CallableDescriptor extends DeclarationDescriptorWithVisibility, DeclarationDescriptorNonRoot {
public interface CallableDescriptor extends DeclarationDescriptorWithVisibility, DeclarationDescriptorNonRoot,
Substitutable<CallableDescriptor> {
@Nullable
ReceiverParameterDescriptor getExtensionReceiverParameter();
@@ -46,9 +46,6 @@ public interface CallableDescriptor extends DeclarationDescriptorWithVisibility,
@Override
CallableDescriptor getOriginal();
@Override
CallableDescriptor substitute(@NotNull TypeSubstitutor substitutor);
@NotNull
List<ValueParameterDescriptor> getValueParameters();
@@ -23,7 +23,6 @@ import org.jetbrains.kotlin.resolve.scopes.MemberScope;
import org.jetbrains.kotlin.types.SimpleType;
import org.jetbrains.kotlin.types.TypeProjection;
import org.jetbrains.kotlin.types.TypeSubstitution;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import java.util.Collection;
import java.util.List;
@@ -59,10 +58,6 @@ public interface ClassDescriptor extends ClassifierDescriptorWithTypeParameters,
@Override
SimpleType getDefaultType();
@NotNull
@Override
ClassDescriptor substitute(@NotNull TypeSubstitutor substitutor);
/**
* @return nested object declared as 'companion' if one is present.
*/
@@ -22,7 +22,8 @@ import org.jetbrains.annotations.ReadOnly;
import java.util.List;
public interface ClassifierDescriptorWithTypeParameters
extends ClassifierDescriptor, DeclarationDescriptorWithVisibility, MemberDescriptor {
extends ClassifierDescriptor, DeclarationDescriptorWithVisibility, MemberDescriptor,
Substitutable<ClassifierDescriptorWithTypeParameters> {
/**
* @return <code>true</code> if this class contains a reference to its outer class (as opposed to static nested class)
*/
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.annotations.Annotated;
import org.jetbrains.kotlin.types.TypeSubstitutor;
public interface DeclarationDescriptor extends Annotated, Named {
/**
@@ -34,9 +33,6 @@ public interface DeclarationDescriptor extends Annotated, Named {
@Nullable
DeclarationDescriptor getContainingDeclaration();
@Nullable
DeclarationDescriptor substitute(@NotNull TypeSubstitutor substitutor);
<R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data);
void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor);
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.TypeSubstitutor
interface ModuleDescriptor : DeclarationDescriptor {
override fun getContainingDeclaration(): DeclarationDescriptor? = null
@@ -28,10 +27,6 @@ interface ModuleDescriptor : DeclarationDescriptor {
fun shouldSeeInternalsOf(targetModule: ModuleDescriptor): Boolean
override fun substitute(substitutor: TypeSubstitutor): ModuleDescriptor {
return this
}
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R {
return visitor.visitModuleDeclaration(this, data)
}
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2017 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.TypeSubstitutor
interface Substitutable<out T : DeclarationDescriptorNonRoot> {
fun substitute(substitutor: TypeSubstitutor): T
}
@@ -18,7 +18,6 @@ package org.jetbrains.kotlin.descriptors
import org.jetbrains.kotlin.descriptors.impl.TypeAliasConstructorDescriptor
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.types.TypeSubstitutor
interface TypeAliasDescriptor : ClassifierDescriptorWithTypeParameters {
/// Right-hand side of the type alias definition.
@@ -33,7 +32,5 @@ interface TypeAliasDescriptor : ClassifierDescriptorWithTypeParameters {
override fun getOriginal(): TypeAliasDescriptor
override fun substitute(substitutor: TypeSubstitutor): TypeAliasDescriptor
val constructors: Collection<TypeAliasConstructorDescriptor>
}
@@ -19,7 +19,6 @@ package org.jetbrains.kotlin.descriptors;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.kotlin.types.KotlinType;
import org.jetbrains.kotlin.types.TypeConstructor;
import org.jetbrains.kotlin.types.TypeSubstitutor;
import org.jetbrains.kotlin.types.Variance;
import java.util.List;
@@ -37,11 +36,6 @@ public interface TypeParameterDescriptor extends ClassifierDescriptor {
@Override
TypeConstructor getTypeConstructor();
@NotNull
@Override
@Deprecated // Use the static method DescriptorSubstitutor.substituteTypeParameters()
TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor);
@NotNull
@Override
TypeParameterDescriptor getOriginal();
@@ -134,13 +134,6 @@ public abstract class AbstractTypeParameterDescriptor extends DeclarationDescrip
return (TypeParameterDescriptor) super.getOriginal();
}
@NotNull
@Override
@Deprecated
public TypeParameterDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
throw new UnsupportedOperationException("Don't call substitute() on type parameters");
}
@Override
public <R, D> R accept(DeclarationDescriptorVisitor<R, D> visitor, D data) {
return visitor.visitTypeParameterDescriptor(this, data);
@@ -16,7 +16,6 @@
package org.jetbrains.kotlin.descriptors.impl
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor
@@ -27,7 +26,6 @@ import org.jetbrains.kotlin.resolve.scopes.LazyScopeAdapter
import org.jetbrains.kotlin.resolve.scopes.MemberScope
import org.jetbrains.kotlin.storage.StorageManager
import org.jetbrains.kotlin.storage.getValue
import org.jetbrains.kotlin.types.TypeSubstitutor
class LazyPackageViewDescriptorImpl(
override val module: ModuleDescriptorImpl,
@@ -65,7 +63,5 @@ class LazyPackageViewDescriptorImpl(
return result
}
override fun substitute(substitutor: TypeSubstitutor): DeclarationDescriptor? = this
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R = visitor.visitPackageViewDescriptor(this, data)
}
@@ -16,18 +16,18 @@
package org.jetbrains.kotlin.descriptors.impl
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.descriptors.DeclarationDescriptorVisitor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PackageFragmentDescriptor
import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.descriptors.annotations.Annotations
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.types.TypeSubstitutor
abstract class PackageFragmentDescriptorImpl(
module: ModuleDescriptor,
final override val fqName: FqName
) : DeclarationDescriptorNonRootImpl(module, Annotations.EMPTY, fqName.shortNameOrSpecial(), SourceElement.NO_SOURCE),
PackageFragmentDescriptor {
override fun substitute(substitutor: TypeSubstitutor): DeclarationDescriptor? = this
override fun <R, D> accept(visitor: DeclarationDescriptorVisitor<R, D>, data: D): R =
visitor.visitPackageFragmentDescriptor(this, data)
@@ -17,6 +17,7 @@
package org.jetbrains.kotlin.resolve.scopes
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Substitutable
import org.jetbrains.kotlin.incremental.components.LookupLocation
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.calls.inference.wrapWithCapturingSubstitution
@@ -41,12 +42,15 @@ class SubstitutingScope(private val workerScope: MemberScope, givenSubstitutor:
substitutedDescriptors = HashMap<DeclarationDescriptor, DeclarationDescriptor>()
}
val substituted = substitutedDescriptors!!.getOrPut(descriptor, {
descriptor.substitute(substitutor).sure {
"We expect that no conflict should happen while substitution is guaranteed to generate invariant projection, " +
"but $descriptor substitution fails"
val substituted = substitutedDescriptors!!.getOrPut(descriptor) {
when (descriptor) {
is Substitutable<*> -> descriptor.substitute(substitutor).sure {
"We expect that no conflict should happen while substitution is guaranteed to generate invariant projection, " +
"but $descriptor substitution fails"
}
else -> error("Unknown descriptor in scope: $descriptor")
}
})
}
@Suppress("UNCHECKED_CAST")
return substituted as D
@@ -99,13 +99,6 @@ public class ErrorUtils {
@Override
public void acceptVoid(DeclarationDescriptorVisitor<Void, Void> visitor) {
}
@NotNull
@Override
public ModuleDescriptor substitute(@NotNull TypeSubstitutor substitutor) {
return this;
}
@Override
@@ -104,11 +104,12 @@ private fun findCandidateDeclarationsInIndex(
return KotlinFullClassNameIndex.getInstance().get(containingClass.fqNameSafe.asString(), project, scope)
}
val topLevelDeclaration = DescriptorUtils.getParentOfType(referencedDescriptor, PropertyDescriptor::class.java, false)
?: DescriptorUtils.getParentOfType(referencedDescriptor, TypeAliasConstructorDescriptor::class.java, false)?.typeAliasDescriptor
?: DescriptorUtils.getParentOfType(referencedDescriptor, FunctionDescriptor::class.java, false)
?: DescriptorUtils.getParentOfType(referencedDescriptor, TypeAliasDescriptor::class.java, false)
?: return emptyList()
val topLevelDeclaration =
DescriptorUtils.getParentOfType(referencedDescriptor, PropertyDescriptor::class.java, false) as DeclarationDescriptor?
?: DescriptorUtils.getParentOfType(referencedDescriptor, TypeAliasConstructorDescriptor::class.java, false)?.typeAliasDescriptor
?: DescriptorUtils.getParentOfType(referencedDescriptor, FunctionDescriptor::class.java, false)
?: DescriptorUtils.getParentOfType(referencedDescriptor, TypeAliasDescriptor::class.java, false)
?: return emptyList()
// filter out synthetic descriptors
if (!DescriptorUtils.isTopLevelDeclaration(topLevelDeclaration)) return emptyList()
@@ -208,11 +208,12 @@ fun<TDescriptor: DeclarationDescriptor?> MutableCollection<LookupElement>.addLoo
}
}
@Suppress("UNCHECKED_CAST")
private fun <T : DeclarationDescriptor?> T.substituteFixed(substitutor: TypeSubstitutor): T {
if (this is LocalVariableDescriptor || this is ValueParameterDescriptor || this is TypeParameterDescriptor) { // TODO: it's not implemented for them
if (this is LocalVariableDescriptor || this is ValueParameterDescriptor || this !is Substitutable<*>) {
return this
}
return this?.substitute(substitutor) as T
return this.substitute(substitutor) as T
}
private fun MutableCollection<LookupElement>.addLookupElementsForNullable(factory: () -> Collection<LookupElement>, matchedInfos: Collection<ExpectedInfo>) {
@@ -47,7 +47,7 @@ private enum class SourceKind { NONE, PRODUCTION, TEST }
fun ModuleDescriptor.hasDeclarationOf(descriptor: MemberDescriptor) = declarationOf(descriptor) != null
private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor) =
private fun ModuleDescriptor.declarationOf(descriptor: MemberDescriptor): DeclarationDescriptor? =
with (HeaderImplDeclarationChecker(this)) {
when (descriptor) {
is CallableMemberDescriptor ->
@@ -32,7 +32,7 @@ import java.awt.event.MouseEvent
fun ModuleDescriptor.hasImplementationsOf(descriptor: MemberDescriptor) =
implementationsOf(descriptor).isNotEmpty()
private fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor) =
private fun ModuleDescriptor.implementationsOf(descriptor: MemberDescriptor): List<DeclarationDescriptor> =
with (HeaderImplDeclarationChecker(this)) {
when (descriptor) {
is CallableMemberDescriptor -> descriptor.findNamesakesFromTheSameModule().filter { it.isImpl }