Prohibit inner classes in objects

Using inner classes in objects makes little sense since objects have single static instance
This commit is contained in:
Pavel V. Talanov
2015-02-19 19:39:33 +03:00
parent 460c1e328f
commit ca3096a948
7 changed files with 20 additions and 16 deletions
@@ -614,7 +614,8 @@ public interface Errors {
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<JetClass> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
DiagnosticFactory0<JetClass> INNER_CLASS_IN_TRAIT = DiagnosticFactory0.create(ERROR, PositioningStrategies.INNER_MODIFIER);
DiagnosticFactory0<JetModifierListOwner> INNER_CLASS_IN_TRAIT = DiagnosticFactory0.create(ERROR, PositioningStrategies.INNER_MODIFIER);
DiagnosticFactory0<JetModifierListOwner> INNER_CLASS_IN_OBJECT = DiagnosticFactory0.create(ERROR, PositioningStrategies.INNER_MODIFIER);
//Inline and inlinable parameters
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
@@ -326,6 +326,7 @@ public class DefaultErrorMessages {
MAP.put(NESTED_CLASS_NOT_ALLOWED, "Nested class is not allowed here, use ''inner'' keyword to make the class inner");
MAP.put(INNER_CLASS_IN_TRAIT, "Inner classes are not allowed in traits");
MAP.put(INNER_CLASS_IN_OBJECT, "Inner classes are not allowed in objects");
MAP.put(HAS_NEXT_MISSING, "hasNext() cannot be called on iterator() of type ''{0}''", RENDER_TYPE);
MAP.put(HAS_NEXT_FUNCTION_AMBIGUITY, "hasNext() is ambiguous for iterator() of type ''{0}''", RENDER_TYPE);
@@ -202,9 +202,10 @@ public class ModifiersChecker {
checkIllegalInThisContextModifiers(modifierListOwner, Collections.singletonList(INNER_KEYWORD));
break;
case IN_TRAIT:
if (modifierListOwner instanceof JetClass) {
trace.report(INNER_CLASS_IN_TRAIT.on((JetClass) modifierListOwner));
}
trace.report(INNER_CLASS_IN_TRAIT.on(modifierListOwner));
break;
case IN_OBJECT:
trace.report(INNER_CLASS_IN_OBJECT.on(modifierListOwner));
break;
}
return;
@@ -225,19 +226,26 @@ public class ModifiersChecker {
private enum InnerModifierCheckResult {
ALLOWED,
ILLEGAL_POSITION,
IN_TRAIT
IN_TRAIT,
IN_OBJECT,
}
@NotNull
private static InnerModifierCheckResult checkIllegalInner(DeclarationDescriptor descriptor) {
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION;
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
if (((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) {
if (DescriptorUtils.isTrait(containingDeclaration)) {
return InnerModifierCheckResult.IN_TRAIT;
}
else if (DescriptorUtils.isClassObject(containingDeclaration) || DescriptorUtils.isObject(containingDeclaration)) {
return InnerModifierCheckResult.IN_OBJECT;
}
else {
return InnerModifierCheckResult.ALLOWED;
}
@@ -27,12 +27,12 @@ trait K {
}
object N {
inner class O
<!INNER_CLASS_IN_OBJECT!>inner<!> class O
}
class P {
class object {
inner class Q
<!INNER_CLASS_IN_OBJECT!>inner<!> class Q
}
}
@@ -136,7 +136,7 @@ internal object N {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final inner class O {
internal final class O {
public constructor O()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -156,7 +156,7 @@ internal final class P {
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
internal final inner class Q {
internal final class Q {
public constructor Q()
public open override /*1*/ /*fake_override*/ fun equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
@@ -5,7 +5,5 @@ annotation class Anno
class Class {
class object {
Anno class Nested
Anno inner class Inner
}
}
@@ -10,10 +10,6 @@ internal final class Class {
internal class object Default {
/*primary*/ private constructor Default()
test.Anno() internal final inner class Inner {
/*primary*/ public constructor Inner()
}
test.Anno() internal final class Nested {
/*primary*/ public constructor Nested()
}