Prohibit inner classes in objects
Using inner classes in objects makes little sense since objects have single static instance
This commit is contained in:
@@ -614,7 +614,8 @@ public interface Errors {
|
|||||||
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory0<JetClass> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
|
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
|
//Inline and inlinable parameters
|
||||||
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
||||||
|
|||||||
+1
@@ -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(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_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_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);
|
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));
|
checkIllegalInThisContextModifiers(modifierListOwner, Collections.singletonList(INNER_KEYWORD));
|
||||||
break;
|
break;
|
||||||
case IN_TRAIT:
|
case IN_TRAIT:
|
||||||
if (modifierListOwner instanceof JetClass) {
|
trace.report(INNER_CLASS_IN_TRAIT.on(modifierListOwner));
|
||||||
trace.report(INNER_CLASS_IN_TRAIT.on((JetClass) modifierListOwner));
|
break;
|
||||||
}
|
case IN_OBJECT:
|
||||||
|
trace.report(INNER_CLASS_IN_OBJECT.on(modifierListOwner));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
@@ -225,19 +226,26 @@ public class ModifiersChecker {
|
|||||||
private enum InnerModifierCheckResult {
|
private enum InnerModifierCheckResult {
|
||||||
ALLOWED,
|
ALLOWED,
|
||||||
ILLEGAL_POSITION,
|
ILLEGAL_POSITION,
|
||||||
IN_TRAIT
|
IN_TRAIT,
|
||||||
|
IN_OBJECT,
|
||||||
}
|
}
|
||||||
|
|
||||||
@NotNull
|
@NotNull
|
||||||
private static InnerModifierCheckResult checkIllegalInner(DeclarationDescriptor descriptor) {
|
private static InnerModifierCheckResult checkIllegalInner(DeclarationDescriptor descriptor) {
|
||||||
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||||
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
|
||||||
|
|
||||||
if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||||
|
|
||||||
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
|
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
|
||||||
if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
|
||||||
if (((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) {
|
|
||||||
|
if (DescriptorUtils.isTrait(containingDeclaration)) {
|
||||||
return InnerModifierCheckResult.IN_TRAIT;
|
return InnerModifierCheckResult.IN_TRAIT;
|
||||||
}
|
}
|
||||||
|
else if (DescriptorUtils.isClassObject(containingDeclaration) || DescriptorUtils.isObject(containingDeclaration)) {
|
||||||
|
return InnerModifierCheckResult.IN_OBJECT;
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
return InnerModifierCheckResult.ALLOWED;
|
return InnerModifierCheckResult.ALLOWED;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,12 +27,12 @@ trait K {
|
|||||||
}
|
}
|
||||||
|
|
||||||
object N {
|
object N {
|
||||||
inner class O
|
<!INNER_CLASS_IN_OBJECT!>inner<!> class O
|
||||||
}
|
}
|
||||||
|
|
||||||
class P {
|
class P {
|
||||||
class object {
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
internal final inner class O {
|
internal final class O {
|
||||||
public constructor 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 equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
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 hashCode(): kotlin.Int
|
||||||
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
public open override /*1*/ /*fake_override*/ fun toString(): kotlin.String
|
||||||
|
|
||||||
internal final inner class Q {
|
internal final class Q {
|
||||||
public constructor 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 equals(/*0*/ other: kotlin.Any?): kotlin.Boolean
|
||||||
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
public open override /*1*/ /*fake_override*/ fun hashCode(): kotlin.Int
|
||||||
|
|||||||
@@ -5,7 +5,5 @@ annotation class Anno
|
|||||||
class Class {
|
class Class {
|
||||||
class object {
|
class object {
|
||||||
Anno class Nested
|
Anno class Nested
|
||||||
|
|
||||||
Anno inner class Inner
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,10 +10,6 @@ internal final class Class {
|
|||||||
internal class object Default {
|
internal class object Default {
|
||||||
/*primary*/ private constructor Default()
|
/*primary*/ private constructor Default()
|
||||||
|
|
||||||
test.Anno() internal final inner class Inner {
|
|
||||||
/*primary*/ public constructor Inner()
|
|
||||||
}
|
|
||||||
|
|
||||||
test.Anno() internal final class Nested {
|
test.Anno() internal final class Nested {
|
||||||
/*primary*/ public constructor Nested()
|
/*primary*/ public constructor Nested()
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user