Constructors for enum entries and class objects have private visibility in frontend.

Introduce DescriptorUtils#getDefaultConstructorVisibility.
DescriptorResolver: remove exception wrapping.
Hardcode package-private visibility for enum entries in JetTypeMapper.

Refactoring:
DescriptorResolver: rename createPrimaryConstructorForObject -> createAndRecordPrimaryConstructorForObject, createPrimaryConstructorForObject now a separate method.
JavaDescriptorResolver: extract containingDeclaration variable.
JetTypeMapper: rename variable declaration -> containingDeclaration.
This commit is contained in:
Pavel V. Talanov
2012-08-28 16:56:23 +04:00
parent bb3bef41ce
commit 00a12bd013
6 changed files with 67 additions and 44 deletions
@@ -44,6 +44,8 @@ import java.util.List;
import java.util.Map;
import static org.jetbrains.asm4.Opcodes.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isClassObject;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.isEnumEntry;
import static org.jetbrains.jet.codegen.context.CodegenBinding.*;
import static org.jetbrains.jet.lang.resolve.BindingContextUtils.descriptorToDeclaration;
@@ -980,8 +982,8 @@ public class JetTypeMapper {
public static int getAccessModifiers(@NotNull MemberDescriptor p, int defaultFlags) {
DeclarationDescriptor declaration = p.getContainingDeclaration();
if (CodegenUtil.isInterface(declaration)) {
DeclarationDescriptor containingDeclaration = p.getContainingDeclaration();
if (CodegenUtil.isInterface(containingDeclaration)) {
return ACC_PUBLIC;
}
if (p.getVisibility() == Visibilities.PUBLIC) {
@@ -991,10 +993,13 @@ public class JetTypeMapper {
return ACC_PROTECTED;
}
else if (p.getVisibility() == Visibilities.PRIVATE) {
if (DescriptorUtils.isClassObject(declaration)) {
if (isClassObject(containingDeclaration)) {
return defaultFlags;
}
if (p.getContainingDeclaration() instanceof NamespaceDescriptor) {
if (p instanceof ConstructorDescriptor && isEnumEntry(containingDeclaration)) {
return 0;
}
if (containingDeclaration instanceof NamespaceDescriptor) {
return 0;
}
return ACC_PRIVATE;
@@ -56,8 +56,7 @@ import org.jetbrains.jet.utils.ExceptionUtils;
import javax.inject.Inject;
import java.util.*;
import static org.jetbrains.jet.lang.resolve.DescriptorResolver.createEnumClassObjectValueOfMethod;
import static org.jetbrains.jet.lang.resolve.DescriptorResolver.createEnumClassObjectValuesMethod;
import static org.jetbrains.jet.lang.resolve.DescriptorResolver.*;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getClassObjectName;
/**
@@ -445,22 +444,17 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
PsiClass psiClass = classData.psiClass;
ClassDescriptorFromJvmBytecode containingClass = classData.classDescriptor;
TypeVariableResolver resolverForTypeParameters = TypeVariableResolvers.classTypeVariableResolver(
classData.classDescriptor, "class " + psiClass.getQualifiedName());
containingClass, "class " + psiClass.getQualifiedName());
List<TypeParameterDescriptor> typeParameters = classData.classDescriptor.getTypeConstructor().getParameters();
List<TypeParameterDescriptor> typeParameters = containingClass.getTypeConstructor().getParameters();
PsiMethod[] psiConstructors = psiClass.getConstructors();
boolean isStatic = psiClass.hasModifierProperty(PsiModifier.STATIC);
if (classData.classDescriptor.getKind() == ClassKind.OBJECT || classData.classDescriptor.getKind() == ClassKind.CLASS_OBJECT) {
// TODO: wrong: class objects do not need visible constructors
ConstructorDescriptorImpl constructor = new ConstructorDescriptorImpl(classData.classDescriptor, new ArrayList<AnnotationDescriptor>(0), true);
Visibility visibility = psiConstructors.length != 0
? resolveVisibility(psiConstructors[0], new PsiMethodWrapper(psiConstructors[0]).getJetConstructor())
: Visibilities.PUBLIC;
constructor.initialize(new ArrayList<TypeParameterDescriptor>(0), new ArrayList<ValueParameterDescriptor>(0), visibility);
constructors.add(constructor);
if (containingClass.getKind() == ClassKind.OBJECT || containingClass.getKind() == ClassKind.CLASS_OBJECT) {
constructors.add(createPrimaryConstructorForObject(containingClass));
}
else if (psiConstructors.length == 0) {
// We need to create default constructors for classes and abstract classes.
@@ -469,17 +463,18 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
// abstract public class Java {}
if (!psiClass.isInterface()) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
classData.classDescriptor,
containingClass,
Collections.<AnnotationDescriptor>emptyList(),
false);
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), classData.classDescriptor.getVisibility(), isStatic);
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), containingClass
.getVisibility(), isStatic);
constructors.add(constructorDescriptor);
trace.record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
}
if (psiClass.isAnnotationType()) {
// A constructor for an annotation type takes all the "methods" in the @interface as parameters
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(
classData.classDescriptor,
containingClass,
Collections.<AnnotationDescriptor>emptyList(),
false);
@@ -512,7 +507,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}
}
constructorDescriptor.initialize(typeParameters, valueParameters, classData.classDescriptor.getVisibility(), isStatic);
constructorDescriptor.initialize(typeParameters, valueParameters, containingClass.getVisibility(), isStatic);
constructors.add(constructorDescriptor);
trace.record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
}
@@ -527,7 +522,7 @@ public class JavaDescriptorResolver implements DependencyClassByQualifiedNameRes
}
for (ConstructorDescriptor constructor : constructors) {
((ConstructorDescriptorImpl) constructor).setReturnType(classData.classDescriptor.getDefaultType());
((ConstructorDescriptorImpl) constructor).setReturnType(containingClass.getDefaultType());
}
return constructors;
@@ -25,7 +25,6 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.jet.lang.diagnostics.DiagnosticUtils;
import org.jetbrains.jet.lang.psi.*;
import org.jetbrains.jet.lang.resolve.calls.autocasts.DataFlowInfo;
import org.jetbrains.jet.lang.resolve.name.Name;
@@ -49,6 +48,8 @@ import java.util.*;
import static org.jetbrains.jet.lang.diagnostics.Errors.*;
import static org.jetbrains.jet.lang.resolve.BindingContext.CONSTRUCTOR;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getDefaultConstructorVisibility;
import static org.jetbrains.jet.lang.resolve.DescriptorUtils.getExpectedThisObjectIfNeeded;
import static org.jetbrains.jet.lexer.JetTokens.OVERRIDE_KEYWORD;
/**
@@ -282,7 +283,7 @@ public class DescriptorResolver {
boolean isInline = (modifierList != null) && modifierList.hasModifier(JetTokens.INLINE_KEYWORD);
functionDescriptor.initialize(
receiverType,
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDescriptor),
getExpectedThisObjectIfNeeded(containingDescriptor),
typeParameterDescriptors,
valueParameterDescriptors,
returnType,
@@ -429,30 +430,29 @@ public class DescriptorResolver {
return typeParameterDescriptor;
}
public static ConstructorDescriptorImpl createPrimaryConstructorForObject(
@NotNull
public static ConstructorDescriptorImpl createAndRecordPrimaryConstructorForObject(
@Nullable PsiElement object,
@NotNull ClassDescriptor classDescriptor,
@NotNull BindingTrace trace
) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(classDescriptor, Collections
.<AnnotationDescriptor>emptyList(), true);
// TODO : make the constructor private?
// TODO check set classDescriptor.getVisibility()
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
Collections.<ValueParameterDescriptor>emptyList(), Visibilities.INTERNAL);
ConstructorDescriptorImpl constructorDescriptor = createPrimaryConstructorForObject(classDescriptor);
if (object != null) {
try {
trace.record(CONSTRUCTOR, object, constructorDescriptor);
}
catch (RuntimeException e) {
throw new RuntimeException(e.getMessage() + " at " + DiagnosticUtils.atLocation(object), e);
}
trace.record(CONSTRUCTOR, object, constructorDescriptor);
}
return constructorDescriptor;
}
@NotNull
public static ConstructorDescriptorImpl createPrimaryConstructorForObject(@NotNull ClassDescriptor containingClass) {
ConstructorDescriptorImpl constructorDescriptor =
new ConstructorDescriptorImpl(containingClass, Collections.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(),
Collections.<ValueParameterDescriptor>emptyList(),
getDefaultConstructorVisibility(containingClass));
return constructorDescriptor;
}
static final class UpperBoundCheckerTask {
JetTypeReference upperBound;
JetType upperBoundType;
@@ -702,7 +702,7 @@ public class DescriptorResolver {
CallableMemberDescriptor.Kind.DECLARATION
);
propertyDescriptor.setType(classDescriptor.getDefaultType(), Collections.<TypeParameterDescriptor>emptyList(),
DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration), ReceiverDescriptor.NO_RECEIVER);
getExpectedThisObjectIfNeeded(containingDeclaration), ReceiverDescriptor.NO_RECEIVER);
propertyDescriptor.initialize(createDefaultGetter(propertyDescriptor), null);
trace.record(BindingContext.OBJECT_DECLARATION_CLASS, propertyDescriptor, classDescriptor);
JetObjectDeclarationName nameAsDeclaration = objectDeclaration.getNameAsDeclaration();
@@ -809,7 +809,7 @@ public class DescriptorResolver {
JetType type = getVariableType(propertyScope, property, DataFlowInfo.EMPTY, true, trace);
propertyDescriptor.setType(type, typeParameterDescriptors, DescriptorUtils.getExpectedThisObjectIfNeeded(containingDeclaration),
propertyDescriptor.setType(type, typeParameterDescriptors, getExpectedThisObjectIfNeeded(containingDeclaration),
receiverDescriptor);
PropertyGetterDescriptor getter = resolvePropertyGetterDescriptor(scopeWithTypeParameters, property, propertyDescriptor, trace);
@@ -1022,7 +1022,7 @@ public class DescriptorResolver {
constructorDescriptor,
parameterScope,
valueParameters, trace),
ModifiersChecker.resolveVisibilityFromModifiers(modifierList, Visibilities.PUBLIC));
ModifiersChecker.resolveVisibilityFromModifiers(modifierList, getDefaultConstructorVisibility(classDescriptor)));
}
@Nullable
@@ -1071,7 +1071,7 @@ public class DescriptorResolver {
CallableMemberDescriptor.Kind.DECLARATION
);
propertyDescriptor.setType(type, Collections.<TypeParameterDescriptor>emptyList(),
DescriptorUtils.getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
getExpectedThisObjectIfNeeded(classDescriptor), ReceiverDescriptor.NO_RECEIVER);
PropertyGetterDescriptor getter = createDefaultGetter(propertyDescriptor);
PropertySetterDescriptor setter = propertyDescriptor.isVar() ? createDefaultSetter(propertyDescriptor) : null;
@@ -283,6 +283,11 @@ public class DescriptorUtils {
&& ((ClassDescriptor) descriptor).getKind() == ClassKind.CLASS_OBJECT;
}
public static boolean isEnumEntry(@NotNull DeclarationDescriptor descriptor) {
return descriptor instanceof ClassDescriptor
&& ((ClassDescriptor) descriptor).getKind() == ClassKind.ENUM_ENTRY;
}
@NotNull
public static List<ClassDescriptor> getSuperclassDescriptors(@NotNull ClassDescriptor classDescriptor) {
Collection<? extends JetType> superclassTypes = classDescriptor.getTypeConstructor().getSupertypes();
@@ -358,4 +363,22 @@ public class DescriptorUtils {
return ((containingDeclaration instanceof ClassDescriptor) &&
((ClassDescriptor) containingDeclaration).getKind() == ClassKind.ENUM_CLASS);
}
@NotNull
public static Visibility getDefaultConstructorVisibility(@NotNull ClassDescriptor classDescriptor) {
ClassKind classKind = classDescriptor.getKind();
if (classKind == ClassKind.ENUM_CLASS) {
//TODO: should be PRIVATE
// see http://youtrack.jetbrains.com/issue/KT-2680
return Visibilities.PROTECTED;
}
if (classKind == ClassKind.ENUM_ENTRY || classKind == ClassKind.CLASS_OBJECT) {
return Visibilities.PRIVATE;
}
if (classKind == ClassKind.OBJECT) {
return Visibilities.INTERNAL;
}
assert classKind == ClassKind.CLASS || classKind == ClassKind.TRAIT || classKind == ClassKind.ANNOTATION_CLASS;
return Visibilities.PUBLIC;
}
}
@@ -350,7 +350,7 @@ public class TypeHierarchyResolver {
MutableClassDescriptor mutableClassDescriptor
) {
ConstructorDescriptorImpl constructorDescriptor = DescriptorResolver
.createPrimaryConstructorForObject(object, mutableClassDescriptor, trace);
.createAndRecordPrimaryConstructorForObject(object, mutableClassDescriptor, trace);
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor, trace);
return constructorDescriptor;
}
@@ -299,7 +299,7 @@ public class LazyClassMemberScope extends AbstractLazyMemberScope<LazyClassDescr
}
else {
ConstructorDescriptorImpl constructor =
DescriptorResolver.createPrimaryConstructorForObject(classOrObject, thisDescriptor, resolveSession.getTrace());
DescriptorResolver.createAndRecordPrimaryConstructorForObject(classOrObject, thisDescriptor, resolveSession.getTrace());
setDeferredReturnType(constructor);
primaryConstructor = constructor;
}