Support sealed class inheritors in the same file

#KT-11573 Fixed
This commit is contained in:
Stanislav Erokhin
2016-05-17 19:23:32 +03:00
parent 26be254fbe
commit 7332032bb6
22 changed files with 343 additions and 72 deletions
@@ -1,5 +1,5 @@
/*
* Copyright 2010-2015 JetBrains s.r.o.
* Copyright 2010-2016 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.
@@ -36,12 +36,28 @@ public class Visibilities {
return true;
}
private boolean inSameFile(@NotNull DeclarationDescriptor what, @NotNull DeclarationDescriptor from) {
SourceFile fromContainingFile = DescriptorUtils.getContainingSourceFile(from);
if (fromContainingFile != SourceFile.NO_SOURCE_FILE) {
return fromContainingFile.equals(DescriptorUtils.getContainingSourceFile(what));
}
return false;
}
@Override
public boolean isVisible(@Nullable ReceiverValue receiver, @NotNull DeclarationDescriptorWithVisibility what, @NotNull DeclarationDescriptor from) {
if (DescriptorUtils.isTopLevelDeclaration(what)) {
SourceFile fromContainingFile = DescriptorUtils.getContainingSourceFile(from);
if (fromContainingFile != SourceFile.NO_SOURCE_FILE) {
return fromContainingFile.equals(DescriptorUtils.getContainingSourceFile(what));
return inSameFile(what, from);
}
if (what instanceof ConstructorDescriptor) {
ClassDescriptor classDescriptor = ((ConstructorDescriptor) what).getContainingDeclaration();
if (DescriptorUtils.isSealedClass(classDescriptor)
&& DescriptorUtils.isTopLevelDeclaration(classDescriptor)
&& from instanceof ConstructorDescriptor
&& DescriptorUtils.isTopLevelDeclaration(from.getContainingDeclaration())
&& inSameFile(what, from)) {
return true;
}
}
@@ -129,8 +129,8 @@ public class DescriptorUtils {
return getFqNameFromTopLevelClass(containingDeclaration).child(name);
}
public static boolean isTopLevelDeclaration(@NotNull DeclarationDescriptor descriptor) {
return descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor;
public static boolean isTopLevelDeclaration(@Nullable DeclarationDescriptor descriptor) {
return descriptor != null && descriptor.getContainingDeclaration() instanceof PackageFragmentDescriptor;
}
public static boolean isExtension(@NotNull CallableDescriptor descriptor) {
@@ -276,6 +276,10 @@ public class DescriptorUtils {
return isKindOf(descriptor, ClassKind.OBJECT) && ((ClassDescriptor) descriptor).isCompanionObject();
}
public static boolean isSealedClass(@Nullable DeclarationDescriptor descriptor) {
return isKindOf(descriptor, ClassKind.CLASS) && ((ClassDescriptor) descriptor).getModality() == Modality.SEALED;
}
public static boolean isAnonymousObject(@NotNull DeclarationDescriptor descriptor) {
return isClass(descriptor) && descriptor.getName().equals(SpecialNames.NO_NAME_PROVIDED);
}
@@ -369,7 +373,7 @@ public class DescriptorUtils {
@NotNull
public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
ClassKind classKind = classDescriptor.getKind();
if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton() || classDescriptor.getModality() == Modality.SEALED) {
if (classKind == ClassKind.ENUM_CLASS || classKind.isSingleton() || isSealedClass(classDescriptor)) {
return Visibilities.PRIVATE;
}
if (isAnonymousObject(classDescriptor)) {
@@ -456,7 +460,7 @@ public class DescriptorUtils {
public static boolean classCanHaveAbstractMembers(@NotNull ClassDescriptor classDescriptor) {
return classDescriptor.getModality() == Modality.ABSTRACT
|| classDescriptor.getModality() == Modality.SEALED
|| isSealedClass(classDescriptor)
|| classDescriptor.getKind() == ClassKind.ENUM_CLASS;
}