Introduce ClassDescriptor#getDefaultObjectDescriptor()

ClassDescriptor#getClassObjectDescriptor (with old semantics) is now a utility
Process usages and replace with calls to a new method where appropriate
This commit is contained in:
Pavel V. Talanov
2015-01-30 15:33:09 +03:00
parent 945072a129
commit f482768acf
26 changed files with 68 additions and 88 deletions
@@ -1915,7 +1915,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
Type type = typeMapper.mapType((ClassDescriptor) enumClass); Type type = typeMapper.mapType((ClassDescriptor) enumClass);
return StackValue.field(type, type, descriptor.getName().asString(), true, StackValue.none()); return StackValue.field(type, type, descriptor.getName().asString(), true, StackValue.none());
} }
ClassDescriptor classObjectDescriptor = classDescriptor.getClassObjectDescriptor(); ClassDescriptor classObjectDescriptor = classDescriptor.getDefaultObjectDescriptor();
if (classObjectDescriptor != null) { if (classObjectDescriptor != null) {
return StackValue.singleton(classObjectDescriptor, typeMapper); return StackValue.singleton(classObjectDescriptor, typeMapper);
} }
@@ -960,7 +960,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private void generateFieldForSingleton() { private void generateFieldForSingleton() {
if (isEnumEntry(descriptor) || isClassObject(descriptor)) return; if (isEnumEntry(descriptor) || isClassObject(descriptor)) return;
ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); ClassDescriptor classObjectDescriptor = descriptor.getDefaultObjectDescriptor();
ClassDescriptor fieldTypeDescriptor; ClassDescriptor fieldTypeDescriptor;
JetClassOrObject original; JetClassOrObject original;
if (isObject(descriptor)) { if (isObject(descriptor)) {
@@ -1022,7 +1022,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
private int putClassObjectInLocalVar(ExpressionCodegen codegen) { private int putClassObjectInLocalVar(ExpressionCodegen codegen) {
FrameMap frameMap = codegen.myFrameMap; FrameMap frameMap = codegen.myFrameMap;
ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); ClassDescriptor classObjectDescriptor = descriptor.getDefaultObjectDescriptor();
int classObjectIndex = frameMap.getIndex(classObjectDescriptor); int classObjectIndex = frameMap.getIndex(classObjectDescriptor);
if (classObjectIndex == -1) { if (classObjectIndex == -1) {
classObjectIndex = frameMap.enter(classObjectDescriptor, OBJECT_TYPE); classObjectIndex = frameMap.enter(classObjectDescriptor, OBJECT_TYPE);
@@ -62,8 +62,8 @@ public class ClassContext extends FieldOwnerContext<ClassDescriptor> {
@Nullable @Nullable
public CodegenContext getClassObjectContext() { public CodegenContext getClassObjectContext() {
if (getContextDescriptor().getClassObjectDescriptor() != null) { if (getContextDescriptor().getDefaultObjectDescriptor() != null) {
return findChildContext(getContextDescriptor().getClassObjectDescriptor()); return findChildContext(getContextDescriptor().getDefaultObjectDescriptor());
} }
return null; return null;
} }
@@ -38,7 +38,7 @@ public interface ClassDescriptorWithResolutionScopes extends ClassDescriptor {
@Nullable @Nullable
@Override @Override
ClassDescriptorWithResolutionScopes getClassObjectDescriptor(); ClassDescriptorWithResolutionScopes getDefaultObjectDescriptor();
@NotNull @NotNull
@ReadOnly @ReadOnly
@@ -92,7 +92,7 @@ public class MutableClassDescriptor extends ClassDescriptorBase implements Class
@Nullable @Nullable
@Override @Override
public MutableClassDescriptor getClassObjectDescriptor() { public MutableClassDescriptor getDefaultObjectDescriptor() {
return classObjectDescriptor; return classObjectDescriptor;
} }
@@ -100,8 +100,8 @@ public class DeclarationResolver {
Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors(); Collection<DeclarationDescriptor> allDescriptors = classDescriptor.getScopeForMemberLookup().getOwnDeclaredDescriptors();
ClassDescriptorWithResolutionScopes classObj = classDescriptor.getClassObjectDescriptor(); ClassDescriptorWithResolutionScopes classObj = classDescriptor.getDefaultObjectDescriptor();
if (classObj != null && DescriptorUtils.isClassObject(classObj)) { if (classObj != null) {
Collection<DeclarationDescriptor> classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors(); Collection<DeclarationDescriptor> classObjDescriptors = classObj.getScopeForMemberLookup().getOwnDeclaredDescriptors();
if (!classObjDescriptors.isEmpty()) { if (!classObjDescriptors.isEmpty()) {
allDescriptors = Lists.newArrayList(allDescriptors); allDescriptors = Lists.newArrayList(allDescriptors);
@@ -38,8 +38,8 @@ public class Importer {
allUnderImportScopes.add(descriptor.getStaticScope()) allUnderImportScopes.add(descriptor.getStaticScope())
allUnderImportScopes.add(descriptor.getUnsubstitutedInnerClassesScope()) allUnderImportScopes.add(descriptor.getUnsubstitutedInnerClassesScope())
val classObjectDescriptor = descriptor.getClassObjectDescriptor() val classObjectDescriptor = descriptor.getDefaultObjectDescriptor()
if (classObjectDescriptor != null && DescriptorUtils.isClassObject(classObjectDescriptor)) { if (classObjectDescriptor != null) {
allUnderImportScopes.add(classObjectDescriptor.getUnsubstitutedInnerClassesScope()) allUnderImportScopes.add(classObjectDescriptor.getUnsubstitutedInnerClassesScope())
} }
} }
@@ -276,8 +276,8 @@ public class QualifiedExpressionResolver {
results.add(lookupSimpleNameReference(selector, descriptor.getStaticScope(), lookupMode, true)); results.add(lookupSimpleNameReference(selector, descriptor.getStaticScope(), lookupMode, true));
ClassDescriptor classObject = descriptor.getClassObjectDescriptor(); ClassDescriptor classObject = descriptor.getDefaultObjectDescriptor();
if (classObject != null && !descriptor.getKind().isSingleton()) { if (classObject != null) {
addResultsForClass(results, selector, lookupMode, classObject); addResultsForClass(results, selector, lookupMode, classObject);
} }
} }
@@ -57,7 +57,6 @@ import java.util.*;
import static org.jetbrains.kotlin.diagnostics.Errors.*; import static org.jetbrains.kotlin.diagnostics.Errors.*;
import static org.jetbrains.kotlin.resolve.BindingContext.TYPE; import static org.jetbrains.kotlin.resolve.BindingContext.TYPE;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isSyntheticClassObject;
import static org.jetbrains.kotlin.resolve.ModifiersChecker.*; import static org.jetbrains.kotlin.resolve.ModifiersChecker.*;
import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement; import static org.jetbrains.kotlin.resolve.source.SourcePackage.toSourceElement;
@@ -130,9 +129,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
} }
boolean isLocal = classOrObject != null && JetPsiUtil.isLocal(classOrObject); boolean isLocal = classOrObject != null && JetPsiUtil.isLocal(classOrObject);
this.visibility = isSyntheticClassObject(this) this.visibility = isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
? DescriptorUtils.getSyntheticClassObjectVisibility()
: isLocal ? Visibilities.LOCAL : resolveVisibilityFromModifiers(modifierList, getDefaultClassVisibility(this));
this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this); this.isInner = isInnerClass(modifierList) && !ModifiersChecker.isIllegalInner(this);
StorageManager storageManager = c.getStorageManager(); StorageManager storageManager = c.getStorageManager();
@@ -269,8 +266,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
thisScope.setImplicitReceiver(this.getThisAsReceiverParameter()); thisScope.setImplicitReceiver(this.getThisAsReceiverParameter());
thisScope.changeLockLevel(WritableScope.LockLevel.READING); thisScope.changeLockLevel(WritableScope.LockLevel.READING);
//TODO: ClassDescriptor classObject = getDefaultObjectDescriptor();
ClassDescriptor classObject = getClassObjectDescriptor();
JetScope classObjectAdapterScope = (classObject != null) ? new ClassObjectMixinScope(classObject) : JetScope.Empty.INSTANCE$; JetScope classObjectAdapterScope = (classObject != null) ? new ClassObjectMixinScope(classObject) : JetScope.Empty.INSTANCE$;
return new ChainedScope( return new ChainedScope(
@@ -350,7 +346,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
} }
@Override @Override
public LazyClassDescriptor getClassObjectDescriptor() { public LazyClassDescriptor getDefaultObjectDescriptor() {
return classObjectDescriptor.invoke(); return classObjectDescriptor.invoke();
} }
@@ -381,26 +377,18 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
@Nullable @Nullable
private LazyClassDescriptor computeClassObjectDescriptor(@Nullable JetObjectDeclaration classObject) { private LazyClassDescriptor computeClassObjectDescriptor(@Nullable JetObjectDeclaration classObject) {
JetClassLikeInfo classObjectInfo = getClassObjectInfo(classObject); JetClassLikeInfo classObjectInfo = getClassObjectInfo(classObject);
if (classObjectInfo instanceof JetClassOrObjectInfo) { if (!(classObjectInfo instanceof JetClassOrObjectInfo)) {
Name name = ((JetClassOrObjectInfo) classObjectInfo).getName(); return null;
assert name != null;
ClassifierDescriptor classObjectDescriptor = getScopeForMemberLookup().getClassifier(name);
if (classObjectDescriptor instanceof LazyClassDescriptor) {
return (LazyClassDescriptor) classObjectDescriptor;
}
else {
return null;
}
} }
if (getKind() == ClassKind.CLASS_OBJECT || getKind() == ClassKind.OBJECT) { Name name = ((JetClassOrObjectInfo) classObjectInfo).getName();
return this; assert name != null;
ClassifierDescriptor classObjectDescriptor = getScopeForMemberLookup().getClassifier(name);
if (classObjectDescriptor instanceof LazyClassDescriptor) {
return (LazyClassDescriptor) classObjectDescriptor;
} }
if (getKind() == ClassKind.ENUM_ENTRY) { else {
DeclarationDescriptor containingDeclaration = getContainingDeclaration(); return null;
assert containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.ENUM_CLASS;
return (LazyClassDescriptor) containingDeclaration;
} }
return null;
} }
@Nullable @Nullable
@@ -473,8 +461,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
private void doForceResolveAllContents() { private void doForceResolveAllContents() {
resolveMemberHeaders(); resolveMemberHeaders();
//TODO: ClassDescriptor classObjectDescriptor = getDefaultObjectDescriptor();
ClassDescriptor classObjectDescriptor = getClassObjectDescriptor();
if (classObjectDescriptor != null) { if (classObjectDescriptor != null) {
ForceResolveUtil.forceResolveAllContents(classObjectDescriptor); ForceResolveUtil.forceResolveAllContents(classObjectDescriptor);
} }
@@ -490,7 +477,7 @@ public class LazyClassDescriptor extends ClassDescriptorBase implements ClassDes
ForceResolveUtil.forceResolveAllContents(getAnnotations()); ForceResolveUtil.forceResolveAllContents(getAnnotations());
ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations()); ForceResolveUtil.forceResolveAllContents(getDanglingAnnotations());
getClassObjectDescriptor(); getDefaultObjectDescriptor();
getDescriptorsForExtraClassObjects(); getDescriptorsForExtraClassObjects();
@@ -34,6 +34,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.getClassObjectReferenceTarget
import org.jetbrains.kotlin.psi.JetExpression import org.jetbrains.kotlin.psi.JetExpression
import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScopeAndDataFlowInfo import org.jetbrains.kotlin.resolve.bindingContextUtil.recordScopeAndDataFlowInfo
import kotlin.properties.Delegates import kotlin.properties.Delegates
import org.jetbrains.kotlin.resolve.descriptorUtil.classObjectDescriptor
public trait Qualifier: ReceiverValue { public trait Qualifier: ReceiverValue {
@@ -81,8 +82,8 @@ class QualifierReceiver (
if (classifier is ClassDescriptor) { if (classifier is ClassDescriptor) {
scopes.add(classifier.getStaticScope()) scopes.add(classifier.getStaticScope())
val classObjectDescriptor = classifier.getClassObjectDescriptor() val classObjectDescriptor = classifier.getDefaultObjectDescriptor()
if (classObjectDescriptor != null && DescriptorUtils.isClassObject(classObjectDescriptor)) { if (classObjectDescriptor != null) {
// non-static members are resolved through class object receiver // non-static members are resolved through class object receiver
scopes.add(DescriptorUtils.getStaticNestedClassesScope(classObjectDescriptor)) scopes.add(DescriptorUtils.getStaticNestedClassesScope(classObjectDescriptor))
} }
@@ -145,7 +146,7 @@ private fun QualifierReceiver.resolveAsReceiverInQualifiedExpression(context: Ex
if (classifier is TypeParameterDescriptor) { if (classifier is TypeParameterDescriptor) {
context.trace.report(TYPE_PARAMETER_ON_LHS_OF_DOT.on(referenceExpression, classifier as TypeParameterDescriptor)) context.trace.report(TYPE_PARAMETER_ON_LHS_OF_DOT.on(referenceExpression, classifier as TypeParameterDescriptor))
} }
else if (classifier is ClassDescriptor && classifier.getClassObjectDescriptor() != null) { else if (classifier is ClassDescriptor && classifier.classObjectDescriptor != null) {
context.trace.record(EXPRESSION_TYPE, referenceExpression, classifier.getClassObjectType()) context.trace.record(EXPRESSION_TYPE, referenceExpression, classifier.getClassObjectType())
} }
} }
@@ -173,7 +174,7 @@ private fun QualifierReceiver.resolveReferenceTarget(selector: DeclarationDescri
if (classifier != null && containingDeclaration is ClassDescriptor && classifier == containingDeclaration) { if (classifier != null && containingDeclaration is ClassDescriptor && classifier == containingDeclaration) {
return classifier return classifier
} }
if (classifier is ClassDescriptor && classifier.getClassObjectDescriptor() != null) { if (classifier is ClassDescriptor && classifier.classObjectDescriptor != null) {
return classifier.getClassObjectReferenceTarget() return classifier.getClassObjectReferenceTarget()
} }
@@ -30,7 +30,6 @@ import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler;
import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles; import org.jetbrains.kotlin.cli.jvm.compiler.EnvironmentConfigFiles;
import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment; import org.jetbrains.kotlin.cli.jvm.compiler.JetCoreEnvironment;
import org.jetbrains.kotlin.config.CompilerConfiguration; import org.jetbrains.kotlin.config.CompilerConfiguration;
import org.jetbrains.kotlin.descriptors.ClassDescriptor;
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor; import org.jetbrains.kotlin.descriptors.DeclarationDescriptor;
import org.jetbrains.kotlin.descriptors.PackageViewDescriptor; import org.jetbrains.kotlin.descriptors.PackageViewDescriptor;
import org.jetbrains.kotlin.resolve.BindingContext; import org.jetbrains.kotlin.resolve.BindingContext;
@@ -146,7 +145,6 @@ public class CompileKotlinAgainstCustomBinariesTest extends TestCaseWithTmpdir {
for (DeclarationDescriptor descriptor : allDescriptors) { for (DeclarationDescriptor descriptor : allDescriptors) {
assertTrue("Wrong name: " + descriptor, descriptor.getName().asString().equals("Lol")); assertTrue("Wrong name: " + descriptor, descriptor.getName().asString().equals("Lol"));
assertTrue("Should be an object: " + descriptor, isObject(descriptor)); assertTrue("Should be an object: " + descriptor, isObject(descriptor));
assertNotNull("Object should have a class object: " + descriptor, ((ClassDescriptor) descriptor).getClassObjectDescriptor());
} }
} }
@@ -201,7 +201,7 @@ public abstract class AbstractAnnotationDescriptorResolveTest extends JetLiteFix
@NotNull @NotNull
private static ClassDescriptor getClassObjectDescriptor(@NotNull ClassDescriptor classDescriptor) { private static ClassDescriptor getClassObjectDescriptor(@NotNull ClassDescriptor classDescriptor) {
ClassDescriptor objectDescriptor = classDescriptor.getClassObjectDescriptor(); ClassDescriptor objectDescriptor = classDescriptor.getDefaultObjectDescriptor();
assert objectDescriptor != null : "Cannot find class object for class " + classDescriptor.getName(); assert objectDescriptor != null : "Cannot find class object for class " + classDescriptor.getName();
return objectDescriptor; return objectDescriptor;
} }
@@ -85,8 +85,7 @@ class LazyJavaClassDescriptor(
override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null override fun getUnsubstitutedPrimaryConstructor(): ConstructorDescriptor? = null
override fun getClassObjectDescriptor(): ClassDescriptor? = null override fun getDefaultObjectDescriptor(): ClassDescriptor? = null
override fun getClassObjectType(): JetType? = getClassObjectDescriptor()?.let { d -> d.getDefaultType() }
override fun getConstructors() = scopeForMemberLookup.constructors() override fun getConstructors() = scopeForMemberLookup.constructors()
@@ -60,8 +60,11 @@ public interface ClassDescriptor extends ClassifierDescriptor, MemberDescriptor,
@Override @Override
JetType getClassObjectType(); JetType getClassObjectType();
/**
* @return nested object declared as 'default' if one is present.
*/
@Nullable @Nullable
ClassDescriptor getClassObjectDescriptor(); ClassDescriptor getDefaultObjectDescriptor();
@NotNull @NotNull
ClassKind getKind(); ClassKind getKind();
@@ -21,6 +21,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable; import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*; import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.name.Name; import org.jetbrains.kotlin.name.Name;
import org.jetbrains.kotlin.resolve.descriptorUtil.DescriptorUtilPackage;
import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper; import org.jetbrains.kotlin.resolve.scopes.InnerClassesScopeWrapper;
import org.jetbrains.kotlin.resolve.scopes.JetScope; import org.jetbrains.kotlin.resolve.scopes.JetScope;
import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope; import org.jetbrains.kotlin.resolve.scopes.SubstitutingScope;
@@ -31,8 +32,6 @@ import org.jetbrains.kotlin.types.*;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import static org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumClass;
public abstract class AbstractClassDescriptor implements ClassDescriptor { public abstract class AbstractClassDescriptor implements ClassDescriptor {
private final Name name; private final Name name;
protected final NotNullLazyValue<JetType> defaultType; protected final NotNullLazyValue<JetType> defaultType;
@@ -79,7 +78,7 @@ public abstract class AbstractClassDescriptor implements ClassDescriptor {
@Nullable @Nullable
@Override @Override
public JetType getClassObjectType() { public JetType getClassObjectType() {
ClassDescriptor classObject = getClassObjectDescriptor(); ClassDescriptor classObject = DescriptorUtilPackage.getClassObjectDescriptor(this);
return classObject == null ? null : classObject.getDefaultType(); return classObject == null ? null : classObject.getDefaultType();
} }
@@ -101,7 +101,7 @@ public class ClassDescriptorImpl extends ClassDescriptorBase {
@Nullable @Nullable
@Override @Override
public ClassDescriptor getClassObjectDescriptor() { public ClassDescriptor getDefaultObjectDescriptor() {
return null; return null;
} }
@@ -47,7 +47,6 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
private final ConstructorDescriptor primaryConstructor; private final ConstructorDescriptor primaryConstructor;
private final JetScope scope; private final JetScope scope;
private final JetScope staticScope = new StaticScopeForKotlinClass(this); private final JetScope staticScope = new StaticScopeForKotlinClass(this);
private final ClassDescriptor classObjectDescriptor;
private final NotNullLazyValue<Collection<Name>> enumMemberNames; private final NotNullLazyValue<Collection<Name>> enumMemberNames;
/** /**
@@ -88,8 +87,6 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
ConstructorDescriptorImpl primaryConstructor = DescriptorFactory.createPrimaryConstructorForObject(this, source); ConstructorDescriptorImpl primaryConstructor = DescriptorFactory.createPrimaryConstructorForObject(this, source);
primaryConstructor.setReturnType(getDefaultType()); primaryConstructor.setReturnType(getDefaultType());
this.primaryConstructor = primaryConstructor; this.primaryConstructor = primaryConstructor;
this.classObjectDescriptor = containingClass;
} }
@NotNull @NotNull
@@ -118,8 +115,8 @@ public class EnumEntrySyntheticClassDescriptor extends ClassDescriptorBase {
@Nullable @Nullable
@Override @Override
public ClassDescriptor getClassObjectDescriptor() { public ClassDescriptor getDefaultObjectDescriptor() {
return classObjectDescriptor; return null;
} }
@NotNull @NotNull
@@ -169,8 +169,8 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
} }
@Override @Override
public ClassDescriptor getClassObjectDescriptor() { public ClassDescriptor getDefaultObjectDescriptor() {
return original.getClassObjectDescriptor(); return original.getDefaultObjectDescriptor();
} }
@NotNull @NotNull
@@ -320,10 +320,6 @@ public class DescriptorUtils {
return superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny()); return superClassDescriptor.equals(KotlinBuiltIns.getInstance().getAny());
} }
public static boolean isSyntheticClassObject(@NotNull DeclarationDescriptor descriptor) {
return isClassObject(descriptor) && isSingleton(descriptor.getContainingDeclaration());
}
@NotNull @NotNull
public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) { public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
ClassKind classKind = classDescriptor.getKind(); ClassKind classKind = classDescriptor.getKind();
@@ -337,11 +333,6 @@ public class DescriptorUtils {
return Visibilities.PUBLIC; return Visibilities.PUBLIC;
} }
@NotNull
public static Visibility getSyntheticClassObjectVisibility() {
return Visibilities.PUBLIC;
}
@Nullable @Nullable
public static ClassDescriptor getInnerClassByName(@NotNull ClassDescriptor classDescriptor, @NotNull String innerClassName) { public static ClassDescriptor getInnerClassByName(@NotNull ClassDescriptor classDescriptor, @NotNull String innerClassName) {
ClassifierDescriptor classifier = classDescriptor.getDefaultType().getMemberScope().getClassifier(Name.identifier(innerClassName)); ClassifierDescriptor classifier = classDescriptor.getDefaultType().getMemberScope().getClassifier(Name.identifier(innerClassName));
@@ -22,12 +22,7 @@ import org.jetbrains.kotlin.descriptors.ClassKind.*
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.ClassId import org.jetbrains.kotlin.name.ClassId
public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor { public fun ClassDescriptor.getClassObjectReferenceTarget(): ClassDescriptor = getDefaultObjectDescriptor() ?: this
val classObjectDescriptor = getClassObjectDescriptor()
return if (classObjectDescriptor == null || hasSyntheticClassObject()) this else classObjectDescriptor
}
public fun ClassDescriptor.hasSyntheticClassObject(): Boolean = getKind() in setOf(ENUM_ENTRY, OBJECT)
public fun DeclarationDescriptor.getImportableDescriptor(): DeclarationDescriptor { public fun DeclarationDescriptor.getImportableDescriptor(): DeclarationDescriptor {
return when { return when {
@@ -60,3 +55,17 @@ public val ClassDescriptor.classId: ClassId
} }
throw IllegalStateException("Illegal container: $owner") throw IllegalStateException("Illegal container: $owner")
} }
/** If a literal of this class can be used as a value returns the class which represents the type of this value */
public val ClassDescriptor.classObjectDescriptor: ClassDescriptor?
get() {
return when (this.getKind()) {
CLASS_OBJECT, OBJECT -> this
ENUM_ENTRY -> {
val container = this.getContainingDeclaration()
assert(container is ClassDescriptor && container.getKind() == ENUM_CLASS)
container as ClassDescriptor
}
else -> getDefaultObjectDescriptor()
}
}
@@ -130,8 +130,8 @@ public class DescriptorSerializer {
} }
} }
ClassDescriptor classObject = classDescriptor.getClassObjectDescriptor(); ClassDescriptor classObject = classDescriptor.getDefaultObjectDescriptor();
if (classObject != null && isClassObject(classObject)) { if (classObject != null) {
builder.setClassObjectName(stringTable.getSimpleNameIndex(classObject.getName())); builder.setClassObjectName(stringTable.getSimpleNameIndex(classObject.getName()));
} }
@@ -110,16 +110,13 @@ public class DeserializedClassDescriptor(
} }
private fun computeClassObjectDescriptor(): ClassDescriptor? { private fun computeClassObjectDescriptor(): ClassDescriptor? {
if (getKind() == ClassKind.OBJECT || getKind() == ClassKind.CLASS_OBJECT) {
return this
}
if (!classProto.hasClassObjectName()) return null if (!classProto.hasClassObjectName()) return null
val classObjectName = c.nameResolver.getName(classProto.getClassObjectName()) val classObjectName = c.nameResolver.getName(classProto.getClassObjectName())
return memberScope.getClassifier(classObjectName) as? ClassDescriptor return memberScope.getClassifier(classObjectName) as? ClassDescriptor
} }
override fun getClassObjectDescriptor(): ClassDescriptor? = classObjectDescriptor() override fun getDefaultObjectDescriptor(): ClassDescriptor? = classObjectDescriptor()
private fun computeSuperTypes(): Collection<JetType> { private fun computeSuperTypes(): Collection<JetType> {
val supertypes = ArrayList<JetType>(classProto.getSupertypeCount()) val supertypes = ArrayList<JetType>(classProto.getSupertypeCount())
@@ -25,7 +25,6 @@ import org.jetbrains.kotlin.renderer.DescriptorRenderer
import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder import org.jetbrains.kotlin.renderer.DescriptorRendererBuilder
import java.util.* import java.util.*
import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry import org.jetbrains.kotlin.resolve.DescriptorUtils.isEnumEntry
import org.jetbrains.kotlin.resolve.DescriptorUtils.isSyntheticClassObject
import org.jetbrains.kotlin.types.error.MissingDependencyErrorClass import org.jetbrains.kotlin.types.error.MissingDependencyErrorClass
import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike import org.jetbrains.kotlin.resolve.dataClassUtils.isComponentLike
import org.jetbrains.kotlin.types.isFlexible import org.jetbrains.kotlin.types.isFlexible
@@ -147,8 +146,8 @@ private fun buildDecompiledText(packageFqName: FqName, descriptors: List<Declara
builder.append(" {\n") builder.append(" {\n")
var firstPassed = false var firstPassed = false
val subindent = indent + " " val subindent = indent + " "
val classObject = descriptor.getClassObjectDescriptor() val classObject = descriptor.getDefaultObjectDescriptor()
if (classObject != null && !descriptor.getKind().isSingleton() && !isSyntheticClassObject(classObject)) { if (classObject != null) {
firstPassed = true firstPassed = true
builder.append(subindent) builder.append(subindent)
appendDescriptor(classObject, subindent) appendDescriptor(classObject, subindent)
@@ -70,7 +70,7 @@ private class MissingDependencyErrorClassDescriptor(containing: DeclarationDescr
return this return this
} }
override fun getClassObjectDescriptor(): ClassDescriptor? { override fun getDefaultObjectDescriptor(): ClassDescriptor? {
//NOTE: only used in types and rendered fq name should be the same as of containing class //NOTE: only used in types and rendered fq name should be the same as of containing class
return MissingDependencyErrorClassDescriptor(this, fullFqName) return MissingDependencyErrorClassDescriptor(this, fullFqName)
} }
@@ -85,7 +85,7 @@ class StaticMembers(
classDescriptor.getStaticScope().getAllDescriptors().forEach(::processMember) classDescriptor.getStaticScope().getAllDescriptors().forEach(::processMember)
val classObject = classDescriptor.getClassObjectDescriptor() val classObject = classDescriptor.getDefaultObjectDescriptor()
if (classObject != null) { if (classObject != null) {
classObject.getDefaultType().getMemberScope().getAllDescriptors() classObject.getDefaultType().getMemberScope().getAllDescriptors()
.filter { !it.isExtension } .filter { !it.isExtension }
@@ -174,7 +174,7 @@ public final class ClassTranslator extends AbstractTranslator {
private TranslationContext fixContextForClassObjectAccessing(TranslationContext declarationContext) { private TranslationContext fixContextForClassObjectAccessing(TranslationContext declarationContext) {
// In Kotlin we can access to class object members without qualifier just by name, but we should translate it to access with FQ name. // In Kotlin we can access to class object members without qualifier just by name, but we should translate it to access with FQ name.
// So create alias for class object receiver parameter. // So create alias for class object receiver parameter.
ClassDescriptor classObjectDescriptor = descriptor.getClassObjectDescriptor(); ClassDescriptor classObjectDescriptor = descriptor.getDefaultObjectDescriptor();
if (classObjectDescriptor != null) { if (classObjectDescriptor != null) {
JsExpression referenceToClass = translateAsFQReference(classObjectDescriptor.getContainingDeclaration(), declarationContext); JsExpression referenceToClass = translateAsFQReference(classObjectDescriptor.getContainingDeclaration(), declarationContext);
JsExpression classObjectAccessor = Namer.getClassObjectAccessor(referenceToClass); JsExpression classObjectAccessor = Namer.getClassObjectAccessor(referenceToClass);