Modality and ClassKinds introduced

This commit is contained in:
Andrey Breslav
2011-09-09 14:26:12 +04:00
parent 91e75cb4d9
commit 704a876537
29 changed files with 191 additions and 212 deletions
@@ -797,7 +797,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
isInterface = psiElement.isInterface();
}
else
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).isObject());
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT);
}
v.visitMethodInsn(isStatic ? Opcodes.INVOKESTATIC : isInterface ? Opcodes.INVOKEINTERFACE : Opcodes.INVOKEVIRTUAL, owner, functionDescriptor.getName(), typeMapper.mapSignature(functionDescriptor.getName(),functionDescriptor).getDescriptor());
@@ -832,7 +832,7 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> {
}
else {
owner = typeMapper.getOwner(propertyDescriptor, OwnerKind.INTERFACE);
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).isObject());
isInterface = !(containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.OBJECT);
}
return StackValue.property(propertyDescriptor.getName(), owner, typeMapper.mapType(propertyDescriptor.getOutType()), isStatic, isInterface, getter, setter);
@@ -196,7 +196,7 @@ public class ImplementationBodyCodegen extends ClassBodyCodegen {
}
final ClassDescriptor outerDescriptor = getOuterClassDescriptor();
if (outerDescriptor != null && !outerDescriptor.isObject()) {
if (outerDescriptor != null && outerDescriptor.getKind() != ClassKind.OBJECT) {
final Type type = JetTypeMapper.jetImplementationType(outerDescriptor);
String interfaceDesc = type.getDescriptor();
final String fieldName = "this$0";
@@ -204,7 +204,7 @@ public class JetTypeMapper {
}
private static String jetJvmName(ClassDescriptor jetClass, OwnerKind kind) {
if (jetClass.isObject()) {
if (jetClass.getKind() == ClassKind.OBJECT) {
return jvmNameForImplementation(jetClass);
}
if (kind == OwnerKind.INTERFACE) {
@@ -272,7 +272,7 @@ public class JetTypeMapper {
if (kind instanceof OwnerKind.DelegateKind) {
kind = OwnerKind.INTERFACE;
}
else if (classDescriptor.isObject()) {
else if (classDescriptor.getKind() == ClassKind.OBJECT) {
kind = OwnerKind.IMPLEMENTATION;
}
owner = jvmName(classDescriptor, kind);
@@ -48,8 +48,9 @@ public interface ClassDescriptor extends ClassifierDescriptor {
@Nullable
JetType getClassObjectType();
boolean isObject();
@NotNull
ClassKind getKind();
@NotNull
ClassModifiers getModifiers();
Modality getModality();
}
@@ -120,9 +120,10 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
return null;
}
@NotNull
@Override
public boolean isObject() {
return false;
public ClassKind getKind() {
return ClassKind.CLASS;
}
@Override
@@ -147,7 +148,7 @@ public class ClassDescriptorImpl extends DeclarationDescriptorImpl implements Cl
@Override
@NotNull
public ClassModifiers getModifiers() {
return ClassModifiers.DEFAULT_MODIFIERS;
public Modality getModality() {
return Modality.FINAL;
}
}
@@ -0,0 +1,12 @@
package org.jetbrains.jet.lang.descriptors;
/**
* @author abreslav
*/
public enum ClassKind {
CLASS,
TRAIT,
ENUM_CLASS,
ANNOTATION_CLASS,
OBJECT
}
@@ -1,31 +0,0 @@
package org.jetbrains.jet.lang.descriptors;
/**
* @author svtk
*/
public class ClassModifiers extends Modifiers {
public static final ClassModifiers DEFAULT_MODIFIERS = new ClassModifiers(false, false, false, false);
private boolean open;
private boolean trait;
private boolean isEnum;
public ClassModifiers(boolean anAbstract, boolean open, boolean trait, boolean isEnum) {
super(anAbstract);
this.open = open;
this.trait = trait;
this.isEnum = isEnum;
}
public boolean isOpen() {
return open;
}
public boolean isTrait() {
return trait;
}
public boolean isEnum() {
return isEnum;
}
}
@@ -28,13 +28,13 @@ public class ConstructorDescriptorImpl extends FunctionDescriptorImpl implements
@Override
@Deprecated
public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, MemberModifiers modifiers) {
public FunctionDescriptorImpl initialize(@Nullable JetType receiverType, @NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, @Nullable JetType unsubstitutedReturnType, Modality modality) {
assert receiverType == null;
return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modifiers);
return super.initialize(null, typeParameters, unsubstitutedValueParameters, unsubstitutedReturnType, modality);
}
public ConstructorDescriptorImpl initialize(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, MemberModifiers modifiers) {
super.initialize(null, typeParameters, unsubstitutedValueParameters, null, modifiers);
public ConstructorDescriptorImpl initialize(@NotNull List<TypeParameterDescriptor> typeParameters, @NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters, Modality modality) {
super.initialize(null, typeParameters, unsubstitutedValueParameters, null, modality);
return this;
}
@@ -23,7 +23,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
private JetType unsubstitutedReturnType;
private JetType receiverType;
private MemberModifiers modifiers;
private Modality modality;
private final Set<FunctionDescriptor> overriddenFunctions = Sets.newLinkedHashSet();
private final FunctionDescriptor original;
@@ -48,12 +48,12 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
@NotNull List<TypeParameterDescriptor> typeParameters,
@NotNull List<ValueParameterDescriptor> unsubstitutedValueParameters,
@Nullable JetType unsubstitutedReturnType,
@Nullable MemberModifiers modifiers) {
@Nullable Modality modality) {
this.receiverType = receiverType;
this.typeParameters = typeParameters;
this.unsubstitutedValueParameters = unsubstitutedValueParameters;
this.unsubstitutedReturnType = unsubstitutedReturnType;
this.modifiers = modifiers;
this.modality = modality;
return this;
}
@@ -74,8 +74,8 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
@NotNull
@Override
public MemberModifiers getModifiers() {
return modifiers;
public Modality getModality() {
return modality;
}
public void addOverriddenFunction(@NotNull FunctionDescriptor overriddenFunction) {
@@ -140,7 +140,7 @@ public class FunctionDescriptorImpl extends DeclarationDescriptorImpl implements
substitutedTypeParameters,
substitutedValueParameters,
substitutedReturnType,
modifiers
modality
);
return substitutedDescriptor;
}
@@ -144,15 +144,16 @@ public class LazySubstitutingClassDescriptor implements ClassDescriptor {
return original.getClassObjectType();
}
@NotNull
@Override
public boolean isObject() {
return original.isObject();
public ClassKind getKind() {
return original.getKind();
}
@Override
@NotNull
public ClassModifiers getModifiers() {
return original.getModifiers();
public Modality getModality() {
return original.getModality();
}
@Override
@@ -7,5 +7,5 @@ import org.jetbrains.annotations.NotNull;
*/
public interface MemberDescriptor {
@NotNull
MemberModifiers getModifiers();
Modality getModality();
}
@@ -1,26 +0,0 @@
package org.jetbrains.jet.lang.descriptors;
/**
* @author abreslav
*/
public class MemberModifiers extends Modifiers {
public static final MemberModifiers DEFAULT_MODIFIERS = new MemberModifiers(false, false, false);
private final boolean isVirtual;
private final boolean isOverride;
public MemberModifiers(boolean isAbstract, boolean isVirtual, boolean isOverride) {
super(isAbstract);
this.isVirtual = isVirtual;
this.isOverride = isOverride;
}
public boolean isVirtual() {
return isVirtual;
}
public boolean isOverride() {
return isOverride;
}
}
@@ -0,0 +1,26 @@
package org.jetbrains.jet.lang.descriptors;
/**
* @author abreslav
*/
public enum Modality {
FINAL(false),
OPEN(true),
ABSTRACT(true);
private final boolean open;
private Modality(boolean open) {
this.open = open;
}
public boolean isOpen() {
return open;
}
public static Modality convertFromFlags(boolean _abstract, boolean open) {
if (_abstract) return ABSTRACT;
if (open) return OPEN;
return FINAL;
}
}
@@ -22,7 +22,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private List<TypeParameterDescriptor> typeParameters = Lists.newArrayList();
private Collection<JetType> supertypes = Lists.newArrayList();
private ClassModifiers classModifiers;
private Modality modality;
private TypeConstructor typeConstructor;
private final WritableScope scopeForMemberResolution;
private final WritableScope scopeForMemberLookup;
@@ -31,19 +31,19 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
private MutableClassDescriptor classObjectDescriptor;
private JetType classObjectType;
private JetType defaultType;
private final boolean isObject;
private final ClassKind kind;
private JetType superclassType;
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope) {
this(trace, containingDeclaration, outerScope, false);
this(trace, containingDeclaration, outerScope, ClassKind.CLASS);
}
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, boolean isObject) {
public MutableClassDescriptor(@NotNull BindingTrace trace, @NotNull DeclarationDescriptor containingDeclaration, @NotNull JetScope outerScope, ClassKind kind) {
super(containingDeclaration);
this.scopeForMemberLookup = new WritableScopeImpl(JetScope.EMPTY, this, trace.getErrorHandler()).setDebugName("MemberLookup");
this.scopeForSupertypeResolution = new WritableScopeImpl(outerScope, this, trace.getErrorHandler()).setDebugName("SupertypeResolution");
this.scopeForMemberResolution = new WritableScopeImpl(new ChainedScope(this, scopeForMemberLookup, scopeForSupertypeResolution), this, trace.getErrorHandler()).setDebugName("MemberResolution");
this.isObject = isObject;
this.kind = kind;
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
@@ -51,7 +51,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
if (this.classObjectDescriptor != null) return ClassObjectStatus.DUPLICATE;
assert classObjectDescriptor.isObject();
assert classObjectDescriptor.getKind() == ClassKind.OBJECT;
this.classObjectDescriptor = classObjectDescriptor;
return ClassObjectStatus.OK;
}
@@ -153,7 +153,7 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
this.typeConstructor = new TypeConstructorImpl(
this,
Collections.<AnnotationDescriptor>emptyList(), // TODO : pass annotations from the class?
!classModifiers.isOpen(),
!modality.isOpen(),
getName(),
typeParameters,
supertypes);
@@ -244,9 +244,10 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
return !constructors.isEmpty();
}
@NotNull
@Override
public boolean isObject() {
return isObject;
public ClassKind getKind() {
return kind;
}
@NotNull
@@ -260,14 +261,14 @@ public class MutableClassDescriptor extends MutableDeclarationDescriptor impleme
}
public void setClassModifiers(ClassModifiers classModifiers) {
this.classModifiers = classModifiers;
public void setModality(Modality modality) {
this.modality = modality;
}
@Override
@NotNull
public ClassModifiers getModifiers() {
return classModifiers;
public Modality getModality() {
return modality;
}
@Override
@@ -14,17 +14,17 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
private final boolean hasBody;
private final boolean isDefault;
private final MemberModifiers modifiers;
private final Modality modality;
protected PropertyAccessorDescriptor(
@NotNull MemberModifiers modifiers,
@NotNull Modality modality,
@NotNull PropertyDescriptor correspondingProperty,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull String name,
boolean hasBody,
boolean isDefault) {
super(correspondingProperty.getContainingDeclaration(), annotations, name);
this.modifiers = modifiers;
this.modality = modality;
this.hasBody = hasBody;
this.isDefault = isDefault;
}
@@ -57,7 +57,7 @@ public abstract class PropertyAccessorDescriptor extends DeclarationDescriptorIm
@NotNull
@Override
public MemberModifiers getModifiers() {
return modifiers;
public Modality getModality() {
return modality;
}
}
@@ -15,7 +15,7 @@ import java.util.List;
*/
public class PropertyDescriptor extends VariableDescriptorImpl implements MemberDescriptor {
private final MemberModifiers memberModifiers;
private final Modality modality;
private final boolean isVar;
private final JetType receiverType;
private final List<TypeParameterDescriptor> typeParemeters = Lists.newArrayListWithCapacity(0);
@@ -27,7 +27,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
@Nullable PropertyDescriptor original,
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull MemberModifiers memberModifiers,
@NotNull Modality modality,
boolean isVar,
@Nullable JetType receiverType,
@NotNull String name,
@@ -37,7 +37,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
assert !isVar || inType != null;
// assert outType != null;
this.isVar = isVar;
this.memberModifiers = memberModifiers;
this.modality = modality;
this.receiverType = receiverType;
this.original = original == null ? this : original.getOriginal();
}
@@ -45,13 +45,13 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
public PropertyDescriptor(
@NotNull DeclarationDescriptor containingDeclaration,
@NotNull List<AnnotationDescriptor> annotations,
@NotNull MemberModifiers memberModifiers,
@NotNull Modality modality,
boolean isVar,
@Nullable JetType receiverType,
@NotNull String name,
@Nullable JetType inType,
@NotNull JetType outType) {
this(null, containingDeclaration, annotations, memberModifiers, isVar, receiverType, name, inType, outType);
this(null, containingDeclaration, annotations, modality, isVar, receiverType, name, inType, outType);
}
private PropertyDescriptor(
@@ -63,7 +63,7 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
original,
original.getContainingDeclaration(),
original.getAnnotations(), // TODO : substitute?
original.getModifiers(),
original.getModality(),
original.isVar,
receiverType,
original.getName(),
@@ -101,8 +101,8 @@ public class PropertyDescriptor extends VariableDescriptorImpl implements Member
@NotNull
@Override
public MemberModifiers getModifiers() {
return memberModifiers;
public Modality getModality() {
return modality;
}
@Nullable
@@ -17,8 +17,8 @@ public class PropertyGetterDescriptor extends PropertyAccessorDescriptor {
private final Set<PropertyGetterDescriptor> overriddenGetters = Sets.newHashSet();
private JetType returnType;
public PropertyGetterDescriptor(@NotNull MemberModifiers modifiers, @NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations, @Nullable JetType returnType, boolean hasBody, boolean isDefault) {
super(modifiers, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody, isDefault);
public PropertyGetterDescriptor(@NotNull Modality modality, @NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations, @Nullable JetType returnType, boolean hasBody, boolean isDefault) {
super(modality, correspondingProperty, annotations, "get-" + correspondingProperty.getName(), hasBody, isDefault);
this.returnType = returnType == null ? correspondingProperty.getOutType() : returnType;
}
@@ -18,8 +18,8 @@ public class PropertySetterDescriptor extends PropertyAccessorDescriptor {
private MutableValueParameterDescriptor parameter;
private final Set<PropertySetterDescriptor> overriddenSetters = Sets.newHashSet();
public PropertySetterDescriptor(@NotNull MemberModifiers modifiers, @NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations, boolean hasBody, boolean isDefault) {
super(modifiers, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault);
public PropertySetterDescriptor(@NotNull Modality modality, @NotNull PropertyDescriptor correspondingProperty, @NotNull List<AnnotationDescriptor> annotations, boolean hasBody, boolean isDefault) {
super(modality, correspondingProperty, annotations, "set-" + correspondingProperty.getName(), hasBody, isDefault);
}
public void initialize(@NotNull MutableValueParameterDescriptor parameter) {
@@ -16,7 +16,7 @@ public class VariableAsFunctionDescriptor extends FunctionDescriptorImpl {
assert outType != null;
assert JetStandardClasses.isFunctionType(outType);
VariableAsFunctionDescriptor result = new VariableAsFunctionDescriptor(variableDescriptor);
result.initialize(JetStandardClasses.getReceiverType(outType), Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType), MemberModifiers.DEFAULT_MODIFIERS);
result.initialize(JetStandardClasses.getReceiverType(outType), Collections.<TypeParameterDescriptor>emptyList(), JetStandardClasses.getValueParameters(result, outType), JetStandardClasses.getReturnType(outType), Modality.FINAL);
return result;
}
@@ -47,7 +47,7 @@ public interface BindingContext {
return jetParameter.getValOrVarNode() != null ||
backingFieldRequired;
}
if (propertyDescriptor.getModifiers().isAbstract()) return false;
if (propertyDescriptor.getModality() == Modality.ABSTRACT) return false;
PropertyGetterDescriptor getter = propertyDescriptor.getGetter();
PropertySetterDescriptor setter = propertyDescriptor.getSetter();
if (getter == null) {
@@ -56,10 +56,10 @@ public interface BindingContext {
else if (propertyDescriptor.isVar() && setter == null) {
return true;
}
else if (setter != null && !setter.hasBody() && !setter.getModifiers().isAbstract()) {
else if (setter != null && !setter.hasBody() && setter.getModality() != Modality.ABSTRACT) {
return true;
}
else if (!getter.hasBody() && !getter.getModifiers().isAbstract()) {
else if (!getter.hasBody() && getter.getModality() != Modality.ABSTRACT) {
return true;
}
return backingFieldRequired;
@@ -141,7 +141,8 @@ public class ClassDescriptorResolver {
index++;
}
descriptor.setTypeParameterDescriptors(typeParameters);
descriptor.setClassModifiers(resolveClassModifiers(classElement.getModifierList()));
Modality defaultModality = descriptor.getKind() == ClassKind.TRAIT ? Modality.ABSTRACT : Modality.FINAL;
descriptor.setModality(resolveModalityFromModifiers(classElement.getModifierList(), defaultModality));
trace.record(BindingContext.CLASS, classElement, descriptor);
}
@@ -221,21 +222,21 @@ public class ClassDescriptorResolver {
returnType = ErrorUtils.createErrorType("No type, no body");
}
}
MemberModifiers defaultModifiers;
Modality defaultModality;
if (containingDescriptor instanceof ClassDescriptor) {
boolean isDefinitelyAbstract = ((ClassDescriptor) containingDescriptor).getModifiers().isTrait() && function.getBodyExpression() == null;
defaultModifiers = new MemberModifiers(isDefinitelyAbstract, isDefinitelyAbstract, false);
boolean isDefinitelyAbstract = ((ClassDescriptor) containingDescriptor).getKind() == ClassKind.TRAIT && function.getBodyExpression() == null;
defaultModality = isDefinitelyAbstract ? Modality.ABSTRACT : Modality.FINAL;
} else {
defaultModifiers = MemberModifiers.DEFAULT_MODIFIERS;
defaultModality = Modality.FINAL;
}
MemberModifiers memberModifiers = resolveMemberModifiers(function.getModifierList(), defaultModifiers);
Modality modality = resolveModalityFromModifiers(function.getModifierList(), defaultModality);
functionDescriptor.initialize(
receiverType,
typeParameterDescriptors,
valueParameterDescriptors,
returnType,
memberModifiers);
modality);
trace.record(BindingContext.FUNCTION, function, functionDescriptor);
return functionDescriptor;
@@ -468,7 +469,7 @@ public class ClassDescriptorResolver {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
annotationResolver.createAnnotationStubs(modifierList),
resolveMemberModifiers(modifierList), // TODO : default modifiers differ in different contexts
resolveModalityFromModifiers(modifierList), // TODO : default modifiers differ in different contexts
false,
null,
JetPsiUtil.safeName(objectDeclaration.getName()),
@@ -518,7 +519,7 @@ public class ClassDescriptorResolver {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
annotationResolver.resolveAnnotations(scope, modifierList),
resolveMemberModifiers(modifierList), // TODO : default modifiers differ in different contexts
resolveModalityFromModifiers(modifierList), // TODO : default modifiers differ in different contexts
isVar,
receiverType,
JetPsiUtil.safeName(property.getName()),
@@ -564,39 +565,30 @@ public class ClassDescriptorResolver {
return typeResolver.resolveType(scope, propertyTypeRef);
}
}
private static ClassModifiers resolveClassModifiers(@Nullable JetModifierList modifierList) {
if (modifierList == null) return ClassModifiers.DEFAULT_MODIFIERS;
boolean abstractModifier = modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD);
boolean traitModifier = modifierList.hasModifier(JetTokens.TRAIT_KEYWORD);
boolean enumModifier = modifierList.hasModifier(JetTokens.ENUM_KEYWORD);
boolean openModifier = modifierList.hasModifier(JetTokens.OPEN_KEYWORD);
return new ClassModifiers(
abstractModifier || traitModifier,
openModifier || abstractModifier || traitModifier,
traitModifier,
enumModifier
);
}
@NotNull
private MemberModifiers resolveMemberModifiers(@Nullable JetModifierList modifierList, @NotNull MemberModifiers defaultModifiers) {
if (modifierList == null) return defaultModifiers;
boolean abstractModifier = modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD);
boolean virtualModifier = modifierList.hasModifier(JetTokens.VIRTUAL_KEYWORD);
boolean overrideModifier = modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD);
return new MemberModifiers(
abstractModifier || defaultModifiers.isAbstract(),
virtualModifier || abstractModifier || overrideModifier || defaultModifiers.isVirtual(),
overrideModifier || defaultModifiers.isOverride()
);
}
@NotNull
private MemberModifiers resolveMemberModifiers(@Nullable JetModifierList modifierList) {
return resolveMemberModifiers(modifierList, MemberModifiers.DEFAULT_MODIFIERS);
private Modality resolveModalityFromModifiers(@Nullable JetModifierList modifierList) {
return resolveModalityFromModifiers(modifierList, Modality.FINAL);
}
@NotNull
private Modality resolveModalityFromModifiers(@Nullable JetModifierList modifierList, @NotNull Modality defaultModality) {
if (modifierList == null) return defaultModality;
if (modifierList.hasModifier(JetTokens.ABSTRACT_KEYWORD)) {
return Modality.ABSTRACT;
}
if (modifierList.hasModifier(JetTokens.OPEN_KEYWORD)) {
return Modality.OPEN;
}
if (modifierList.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
return Modality.OPEN;
}
if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) {
return Modality.FINAL;
}
return defaultModality;
}
@Nullable
private PropertySetterDescriptor resolvePropertySetterDescriptor(@NotNull JetScope scope, @NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) {
JetPropertyAccessor setter = property.getSetter();
@@ -606,7 +598,7 @@ public class ClassDescriptorResolver {
JetParameter parameter = setter.getParameter();
setterDescriptor = new PropertySetterDescriptor(
resolveMemberModifiers(setter.getModifierList()), // TODO : default modifiers differ in different contexts
resolveModalityFromModifiers(setter.getModifierList()), // TODO : default modifiers differ in different contexts
propertyDescriptor, annotations, setter.getBodyExpression() != null, false);
if (parameter != null) {
if (parameter.isRef()) {
@@ -644,7 +636,7 @@ public class ClassDescriptorResolver {
}
else if (property.isVar()) {
setterDescriptor = new PropertySetterDescriptor(
propertyDescriptor.getModifiers(),
propertyDescriptor.getModality(),
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), false, true);
}
@@ -670,13 +662,13 @@ public class ClassDescriptorResolver {
}
getterDescriptor = new PropertyGetterDescriptor(
resolveMemberModifiers(getter.getModifierList()), // TODO : default modifiers differ in different contexts
resolveModalityFromModifiers(getter.getModifierList()), // TODO : default modifiers differ in different contexts
propertyDescriptor, annotations, returnType, getter.getBodyExpression() != null, false);
trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor);
}
else {
getterDescriptor = new PropertyGetterDescriptor(
propertyDescriptor.getModifiers(),
propertyDescriptor.getModality(),
propertyDescriptor, Collections.<AnnotationDescriptor>emptyList(), propertyDescriptor.getOutType(), false, true);
}
return getterDescriptor;
@@ -710,7 +702,7 @@ public class ClassDescriptorResolver {
constructorDescriptor,
new WritableScopeImpl(scope, classDescriptor, trace.getErrorHandler()).setDebugName("Scope with value parameters of a constructor"),
valueParameters),
MemberModifiers.DEFAULT_MODIFIERS);
Modality.FINAL);
}
@Nullable
@@ -745,7 +737,7 @@ public class ClassDescriptorResolver {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
classDescriptor,
annotationResolver.resolveAnnotations(scope, modifierList),
resolveMemberModifiers(modifierList),
resolveModalityFromModifiers(modifierList),
isMutable,
null,
name == null ? "<no name>" : name,
@@ -170,9 +170,9 @@ public class TopDownAnalyzer {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope);
if (klass.hasModifier(JetTokens.ENUM_KEYWORD)) {
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(trace, mutableClassDescriptor, outerScope, true);
MutableClassDescriptor classObjectDescriptor = new MutableClassDescriptor(trace, mutableClassDescriptor, outerScope, ClassKind.OBJECT);
classObjectDescriptor.setName("class-object-for-" + klass.getName());
classObjectDescriptor.setClassModifiers(ClassModifiers.DEFAULT_MODIFIERS);
classObjectDescriptor.setModality(Modality.FINAL);
classObjectDescriptor.createTypeConstructor();
createPrimaryConstructor(classObjectDescriptor);
mutableClassDescriptor.setClassObjectDescriptor(classObjectDescriptor);
@@ -213,7 +213,7 @@ public class TopDownAnalyzer {
}
private MutableClassDescriptor createClassDescriptorForObject(@NotNull JetClassOrObject declaration, @NotNull NamespaceLike owner) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope, true) {
MutableClassDescriptor mutableClassDescriptor = new MutableClassDescriptor(trace, owner, outerScope, ClassKind.OBJECT) {
@Override
public ClassObjectStatus setClassObjectDescriptor(@NotNull MutableClassDescriptor classObjectDescriptor) {
return ClassObjectStatus.NOT_ALLOWED;
@@ -228,7 +228,7 @@ public class TopDownAnalyzer {
private void createPrimaryConstructor(MutableClassDescriptor mutableClassDescriptor) {
ConstructorDescriptorImpl constructorDescriptor = new ConstructorDescriptorImpl(mutableClassDescriptor, Collections.<AnnotationDescriptor>emptyList(), true);
constructorDescriptor.initialize(Collections.<TypeParameterDescriptor>emptyList(), Collections.<ValueParameterDescriptor>emptyList(),
MemberModifiers.DEFAULT_MODIFIERS);
Modality.FINAL);
// TODO : make the constructor private?
mutableClassDescriptor.setPrimaryConstructor(constructorDescriptor);
}
@@ -331,7 +331,7 @@ public class TopDownAnalyzer {
}
for (Map.Entry<JetObjectDeclaration, MutableClassDescriptor> entry : objects.entrySet()) {
MutableClassDescriptor descriptor = entry.getValue();
descriptor.setClassModifiers(ClassModifiers.DEFAULT_MODIFIERS);
descriptor.setModality(Modality.FINAL);
descriptor.createTypeConstructor();
}
}
@@ -487,7 +487,7 @@ public class TopDownAnalyzer {
private void processPrimaryConstructor(MutableClassDescriptor classDescriptor, JetClass klass) {
if (!klass.hasPrimaryConstructor()) return;
if (classDescriptor.getModifiers().isTrait()) {
if (classDescriptor.getKind() == ClassKind.TRAIT) {
trace.getErrorHandler().genericError(klass.getPrimaryConstructorParameterList().getNode(), "A trait may not have a constructor");
}
@@ -509,7 +509,7 @@ public class TopDownAnalyzer {
}
private void processSecondaryConstructor(MutableClassDescriptor classDescriptor, JetConstructor constructor) {
if (classDescriptor.getModifiers().isTrait()) {
if (classDescriptor.getKind() == ClassKind.TRAIT) {
trace.getErrorHandler().genericError(constructor.getNameNode(), "A trait may not have a constructor");
}
ConstructorDescriptor constructorDescriptor = classDescriptorResolver.resolveSecondaryConstructorDescriptor(
@@ -559,7 +559,7 @@ public class TopDownAnalyzer {
for (JetType supertype : classDescriptor.getTypeConstructor().getSupertypes()) {
FunctionDescriptor overridden = findFunctionOverridableBy(declaredFunction, supertype);
if (overridden != null) {
if (hasOverrideModifier && !overridden.getModifiers().isVirtual() && !foundError) {
if (hasOverrideModifier && !overridden.getModality().isOpen() && !foundError) {
trace.getErrorHandler().genericError(overrideNode, "Method " + overridden.getName() + " in " + overridden.getContainingDeclaration().getName() + " is final and can not be overridden");
foundError = true;
}
@@ -635,7 +635,7 @@ public class TopDownAnalyzer {
@Override
public void visitDelegationByExpressionSpecifier(JetDelegatorByExpressionSpecifier specifier) {
if (descriptor.getModifiers().isTrait()) {
if (descriptor.getKind() == ClassKind.TRAIT) {
trace.getErrorHandler().genericError(specifier.getNode(), "Traits can not use delegation");
}
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, specifier.getTypeReference());
@@ -656,7 +656,7 @@ public class TopDownAnalyzer {
public void visitDelegationToSuperCallSpecifier(JetDelegatorToSuperCall call) {
JetValueArgumentList valueArgumentList = call.getValueArgumentList();
ASTNode node = valueArgumentList == null ? call.getNode() : valueArgumentList.getNode();
if (descriptor.getModifiers().isTrait()) {
if (descriptor.getKind() == ClassKind.TRAIT) {
trace.getErrorHandler().genericError(node, "Traits can not initialize supertypes");
}
JetTypeReference typeReference = call.getTypeReference();
@@ -667,7 +667,7 @@ public class TopDownAnalyzer {
recordSupertype(typeReference, supertype);
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
if (classDescriptor.getModifiers().isTrait()) {
if (classDescriptor.getKind() == ClassKind.TRAIT) {
trace.getErrorHandler().genericError(node, "A trait may not have a constructor");
}
}
@@ -676,7 +676,7 @@ public class TopDownAnalyzer {
recordSupertype(typeReference, trace.getBindingContext().get(BindingContext.TYPE, typeReference));
}
}
else if (!descriptor.getModifiers().isTrait()) {
else if (descriptor.getKind() != ClassKind.TRAIT) {
JetType supertype = trace.getBindingContext().get(BindingContext.TYPE, typeReference);
recordSupertype(typeReference, supertype);
@@ -695,8 +695,8 @@ public class TopDownAnalyzer {
if (supertype != null) {
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
if (!descriptor.getModifiers().isTrait()) {
if (classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && !classDescriptor.getModifiers().isTrait()) {
if (descriptor.getKind() != ClassKind.TRAIT) {
if (classDescriptor.hasConstructors() && !ErrorUtils.isError(classDescriptor.getTypeConstructor()) && classDescriptor.getKind() != ClassKind.TRAIT) {
trace.getErrorHandler().genericError(specifier.getNode(), "This type has a constructor, and thus must be initialized here");
}
}
@@ -738,7 +738,7 @@ public class TopDownAnalyzer {
ClassDescriptor classDescriptor = TypeUtils.getClassDescriptor(supertype);
if (classDescriptor != null) {
if (!classDescriptor.getModifiers().isTrait()) {
if (classDescriptor.getKind() != ClassKind.TRAIT) {
if (classAppeared) {
trace.getErrorHandler().genericError(typeReference.getNode(), "Only one class may appear in a supertype list");
}
@@ -984,13 +984,13 @@ public class TopDownAnalyzer {
JetPropertyAccessor setter = property.getSetter();
PsiElement nameIdentifier = property.getNameIdentifier();
ASTNode nameNode = nameIdentifier == null ? property.getNode() : nameIdentifier.getNode();
if (propertyDescriptor.getModifiers().isAbstract()) {
if (propertyDescriptor.getModality() == Modality.ABSTRACT) {
if (classDescriptor == null) {
trace.getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
"Global property can not be abstract");
return;
}
if (!classDescriptor.getModifiers().isAbstract()) {
if (classDescriptor.getModality() != Modality.ABSTRACT) {
trace.getErrorHandler().genericError(property.getModifierList().getModifierNode(JetTokens.ABSTRACT_KEYWORD),
"Abstract property " + property.getName() + " in non-abstract class " + classDescriptor.getName());
return;
@@ -1011,7 +1011,7 @@ public class TopDownAnalyzer {
if (initializer == null && !trace.getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
if (classDescriptor == null || (getter != null && getter.getBodyExpression() != null) || (setter != null && setter.getBodyExpression() != null)) {
trace.getErrorHandler().genericError(nameNode, "Property must be initialized");
} else if (!classDescriptor.getModifiers().isTrait()) {
} else if (classDescriptor.getKind() != ClassKind.TRAIT) {
trace.getErrorHandler().genericError(nameNode, "Property must be initialized or be abstract");
}
}
@@ -1030,9 +1030,9 @@ public class TopDownAnalyzer {
boolean hasAbstractModifier = abstractNode != null;
if (containingDescriptor instanceof ClassDescriptor) {
ClassDescriptor classDescriptor = (ClassDescriptor) containingDescriptor;
boolean inTrait = classDescriptor.getModifiers().isTrait();
boolean inEnum = classDescriptor.getModifiers().isEnum();
boolean inAbstractClass = classDescriptor.getModifiers().isAbstract();
boolean inTrait = classDescriptor.getKind() == ClassKind.TRAIT;
boolean inEnum = classDescriptor.getKind() == ClassKind.ENUM_CLASS;
boolean inAbstractClass = classDescriptor.getModality() == Modality.ABSTRACT;
if (hasAbstractModifier && !inAbstractClass && !inTrait && !inEnum) {
trace.getErrorHandler().genericError(abstractNode, "Abstract method " + function.getName() + " in non-abstract class " + classDescriptor.getName());
}
@@ -101,8 +101,8 @@ public class CallResolver {
@Override
public <D extends CallableDescriptor> boolean performAdvancedChecks(D descriptor, BindingTrace trace, TracingStrategy tracing) {
if (descriptor instanceof ConstructorDescriptor) {
ClassModifiers modifiers = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModifiers();
if (modifiers.isAbstract()) {
Modality modality = ((ConstructorDescriptor) descriptor).getContainingDeclaration().getModality();
if (modality == Modality.ABSTRACT) {
tracing.reportOverallResolutionError(trace, "Can not create an instance of an abstract class");
return false;
}
@@ -20,20 +20,22 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
private JavaClassMembersScope unsubstitutedMemberScope;
private JetType classObjectType;
private final WritableFunctionGroup constructors = new WritableFunctionGroup("<init>");
private ClassModifiers modifiers;
private Modality modality;
private JetType superclassType;
private final ClassKind kind;
public JavaClassDescriptor(DeclarationDescriptor containingDeclaration) {
public JavaClassDescriptor(DeclarationDescriptor containingDeclaration, @NotNull ClassKind kind) {
super(containingDeclaration);
this.kind = kind;
}
public void setTypeConstructor(TypeConstructor typeConstructor) {
this.typeConstructor = typeConstructor;
}
public void setModifiers(boolean isAbstract, boolean isOpen, boolean isTrait, boolean isEnum) {
this.modifiers = new ClassModifiers(isAbstract, isOpen, isTrait, isEnum);
public void setModality(Modality modality) {
this.modality = modality;
}
public void setUnsubstitutedMemberScope(JavaClassMembersScope memberScope) {
@@ -132,15 +134,16 @@ public class JavaClassDescriptor extends MutableDeclarationDescriptor implements
return false;
}
@NotNull
@Override
public boolean isObject() {
return false;
public ClassKind getKind() {
return kind;
}
@Override
@NotNull
public ClassModifiers getModifiers() {
return modifiers;
public Modality getModality() {
return modality;
}
@Override
@@ -90,7 +90,7 @@ public class JavaDescriptorResolver {
String name = psiClass.getName();
JavaClassDescriptor classDescriptor = new JavaClassDescriptor(
JAVA_ROOT
JAVA_ROOT, psiClass.isInterface() ? ClassKind.TRAIT : ClassKind.CLASS
);
classDescriptor.setName(name);
@@ -106,11 +106,9 @@ public class JavaDescriptorResolver {
supertypes
));
classDescriptor.setModifiers(
psiClass.hasModifierProperty(PsiModifier.ABSTRACT),
!psiClass.hasModifierProperty(PsiModifier.FINAL),
psiClass.isInterface(),
psiClass.isEnum()
classDescriptor.setModality(Modality.convertFromFlags(
psiClass.hasModifierProperty(PsiModifier.ABSTRACT) || psiClass.isInterface(),
!psiClass.hasModifierProperty(PsiModifier.FINAL))
);
classDescriptorCache.put(psiClass.getQualifiedName(), classDescriptor);
classDescriptor.setUnsubstitutedMemberScope(new JavaClassMembersScope(classDescriptor, psiClass, semanticServices, false));
@@ -137,7 +135,7 @@ public class JavaDescriptorResolver {
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(),
false);
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), MemberModifiers.DEFAULT_MODIFIERS);
constructorDescriptor.initialize(typeParameters, Collections.<ValueParameterDescriptor>emptyList(), Modality.FINAL);
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, psiClass, constructorDescriptor);
@@ -149,7 +147,7 @@ public class JavaDescriptorResolver {
classDescriptor,
Collections.<AnnotationDescriptor>emptyList(), // TODO
false);
constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), MemberModifiers.DEFAULT_MODIFIERS);
constructorDescriptor.initialize(typeParameters, resolveParameterDescriptors(constructorDescriptor, constructor.getParameterList().getParameters()), Modality.FINAL);
constructorDescriptor.setReturnType(classDescriptor.getDefaultType());
classDescriptor.addConstructor(constructorDescriptor);
semanticServices.getTrace().record(BindingContext.CONSTRUCTOR, constructor, constructorDescriptor);
@@ -292,7 +290,7 @@ public class JavaDescriptorResolver {
PropertyDescriptor propertyDescriptor = new PropertyDescriptor(
containingDeclaration,
Collections.<AnnotationDescriptor>emptyList(),
new MemberModifiers(false, false, false),
Modality.FINAL,
!isFinal,
null,
field.getName(),
@@ -361,7 +359,7 @@ public class JavaDescriptorResolver {
resolveTypeParameters(functionDescriptorImpl, method.getTypeParameters()),
semanticServices.getDescriptorResolver().resolveParameterDescriptors(functionDescriptorImpl, parameters),
semanticServices.getTypeTransformer().transformToType(returnType),
new MemberModifiers(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL), false)
Modality.convertFromFlags(method.hasModifierProperty(PsiModifier.ABSTRACT), !method.hasModifierProperty(PsiModifier.FINAL))
);
semanticServices.getTrace().record(BindingContext.FUNCTION, method, functionDescriptorImpl);
FunctionDescriptor substitutedFunctionDescriptor = functionDescriptorImpl;
@@ -111,7 +111,7 @@ public class ErrorUtils {
private static final VariableDescriptor ERROR_PROPERTY = new PropertyDescriptor(
ERROR_CLASS,
Collections.<AnnotationDescriptor>emptyList(),
new MemberModifiers(false, false, false),
Modality.OPEN,
true,
null,
"<ERROR PROPERTY>",
@@ -124,7 +124,7 @@ public class ErrorUtils {
typeParameters,
getValueParameters(functionDescriptor, positionedValueArgumentTypes),
createErrorType("<ERROR FUNCTION RETURN>"),
MemberModifiers.DEFAULT_MODIFIERS
Modality.OPEN
);
}
@@ -134,7 +134,7 @@ public class ErrorUtils {
Collections.<TypeParameterDescriptor>emptyList(), // TODO
Collections.<ValueParameterDescriptor>emptyList(), // TODO
createErrorType("<ERROR FUNCTION RETURN TYPE>"),
MemberModifiers.DEFAULT_MODIFIERS
Modality.OPEN
);
}
@@ -932,7 +932,7 @@ public class JetTypeInferrer {
else {
effectiveReceiverType = receiverType;
}
functionDescriptor.initialize(effectiveReceiverType, Collections.<TypeParameterDescriptor>emptyList(), valueParameterDescriptors, null, MemberModifiers.DEFAULT_MODIFIERS);
functionDescriptor.initialize(effectiveReceiverType, Collections.<TypeParameterDescriptor>emptyList(), valueParameterDescriptors, null, Modality.FINAL);
context.trace.record(BindingContext.FUNCTION, expression, functionDescriptor);
JetType returnType = NO_EXPECTED_TYPE;
@@ -56,6 +56,7 @@ public interface JetTokens {
JetKeywordToken WHILE_KEYWORD = JetKeywordToken.keyword("while");
JetKeywordToken DO_KEYWORD = JetKeywordToken.keyword("do");
JetKeywordToken WHEN_KEYWORD = JetKeywordToken.keyword("when");
JetKeywordToken TRAIT_KEYWORD = JetKeywordToken.keyword("trait");
// TODO: Discuss "This" keyword
JetKeywordToken CAPITALIZED_THIS_KEYWORD = JetKeywordToken.keyword("This");
@@ -136,9 +137,9 @@ public interface JetTokens {
JetKeywordToken PROTECTED_KEYWORD = JetKeywordToken.softKeyword("protected");
JetKeywordToken CATCH_KEYWORD = JetKeywordToken.softKeyword("catch");
JetKeywordToken OUT_KEYWORD = JetKeywordToken.softKeyword("out");
JetKeywordToken TRAIT_KEYWORD = JetKeywordToken.softKeyword("trait");
JetKeywordToken FINALLY_KEYWORD = JetKeywordToken.softKeyword("finally");
JetKeywordToken FINAL_KEYWORD = JetKeywordToken.softKeyword("final");
// TODO: support this as an annotation on arguments. Then, they it probably can not be a soft keyword
JetKeywordToken REF_KEYWORD = JetKeywordToken.softKeyword("ref");
@@ -149,18 +150,18 @@ public interface JetTokens {
TRUE_KEYWORD, FALSE_KEYWORD, IS_KEYWORD,
IN_KEYWORD, THROW_KEYWORD, RETURN_KEYWORD, BREAK_KEYWORD, CONTINUE_KEYWORD, OBJECT_KEYWORD, IF_KEYWORD,
ELSE_KEYWORD, WHILE_KEYWORD, DO_KEYWORD, TRY_KEYWORD, WHEN_KEYWORD,
NOT_IN, NOT_IS, CAPITALIZED_THIS_KEYWORD, AS_SAFE
NOT_IN, NOT_IS, CAPITALIZED_THIS_KEYWORD, AS_SAFE, TRAIT_KEYWORD
);
TokenSet SOFT_KEYWORDS = TokenSet.create(WRAPS_KEYWORD, IMPORT_KEYWORD, WHERE_KEYWORD, BY_KEYWORD, GET_KEYWORD,
SET_KEYWORD, ABSTRACT_KEYWORD, VIRTUAL_KEYWORD, ENUM_KEYWORD, OPEN_KEYWORD, ATTRIBUTE_KEYWORD,
OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD, PROTECTED_KEYWORD,
CATCH_KEYWORD, FINALLY_KEYWORD, REF_KEYWORD, OUT_KEYWORD, TRAIT_KEYWORD
CATCH_KEYWORD, FINALLY_KEYWORD, REF_KEYWORD, OUT_KEYWORD, FINAL_KEYWORD
);
TokenSet MODIFIER_KEYWORDS = TokenSet.create(ABSTRACT_KEYWORD, VIRTUAL_KEYWORD, ENUM_KEYWORD,
OPEN_KEYWORD, ATTRIBUTE_KEYWORD, OVERRIDE_KEYWORD, PRIVATE_KEYWORD, PUBLIC_KEYWORD, INTERNAL_KEYWORD,
PROTECTED_KEYWORD, REF_KEYWORD, OUT_KEYWORD, IN_KEYWORD, TRAIT_KEYWORD
PROTECTED_KEYWORD, REF_KEYWORD, OUT_KEYWORD, IN_KEYWORD, FINAL_KEYWORD
);
TokenSet WHITE_SPACE_OR_COMMENT_BIT_SET = TokenSet.create(WHITE_SPACE, BLOCK_COMMENT, EOL_COMMENT, DOC_COMMENT);
TokenSet WHITESPACES = TokenSet.create(TokenType.WHITE_SPACE);
@@ -251,7 +251,7 @@ public class DescriptorRenderer {
@Override
public Void visitClassDescriptor(ClassDescriptor descriptor, StringBuilder builder) {
String keyword = descriptor.getModifiers().isTrait() ? "trait class" : "class";
String keyword = descriptor.getKind() == ClassKind.TRAIT ? "trait class" : "class";
renderClassDescriptor(descriptor, builder, keyword);
return super.visitClassDescriptor(descriptor, builder);
}