Prohibit objects inside inner classes

#KT-16232 Fixed
This commit is contained in:
Denis Zharkov
2017-02-10 16:46:46 +03:00
parent 5b9b003e02
commit d1b17f050b
6 changed files with 32 additions and 1 deletions
@@ -892,6 +892,7 @@ public interface Errors {
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<KtClass> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
DiagnosticFactory0<KtObjectDeclaration> NESTED_OBJECT_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
//Inline and inlinable parameters
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> NON_PUBLIC_CALL_FROM_PUBLIC_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
@@ -437,6 +437,7 @@ public class DefaultErrorMessages {
MAP.put(INACCESSIBLE_OUTER_CLASS_EXPRESSION, "Expression is inaccessible from a nested class ''{0}'', use ''inner'' keyword to make the class inner", NAME);
MAP.put(NESTED_CLASS_NOT_ALLOWED, "Nested class is not allowed here, use 'inner' keyword to make the class inner");
MAP.put(NESTED_OBJECT_NOT_ALLOWED, "Objects inside inner classes are prohibited");
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);
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
import java.util.*;
import static org.jetbrains.kotlin.diagnostics.Errors.NESTED_CLASS_NOT_ALLOWED;
import static org.jetbrains.kotlin.diagnostics.Errors.NESTED_OBJECT_NOT_ALLOWED;
import static org.jetbrains.kotlin.lexer.KtTokens.*;
import static org.jetbrains.kotlin.psi.KtStubbedPsiUtil.getContainingDeclaration;
@@ -219,10 +220,20 @@ public class ModifiersChecker {
public void checkModifiersForDeclaration(@NotNull KtDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
checkNestedClassAllowed(modifierListOwner, descriptor);
checkObjectInsideInnerClass(modifierListOwner, descriptor);
checkTypeParametersModifiers(modifierListOwner);
checkModifierListCommon(modifierListOwner, descriptor);
}
private void checkObjectInsideInnerClass(@NotNull KtDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
if (modifierListOwner instanceof KtObjectDeclaration) {
KtObjectDeclaration ktObject = (KtObjectDeclaration) modifierListOwner;
if (!ktObject.isLocal() && !ktObject.isCompanion() && isIllegalNestedClass(descriptor)) {
trace.report(NESTED_OBJECT_NOT_ALLOWED.on(ktObject));
}
}
}
private void checkModifierListCommon(@NotNull KtDeclaration modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
AnnotationUseSiteTargetChecker.INSTANCE.check(modifierListOwner, descriptor, trace);
runDeclarationCheckers(modifierListOwner, descriptor);
@@ -0,0 +1,12 @@
// SKIP_TXT
class Outer {
inner class Inner1 {
<!NESTED_OBJECT_NOT_ALLOWED!>object Obj1<!>
<!WRONG_MODIFIER_CONTAINING_DECLARATION!>companion<!> object Obj2
inner class Inner2 {
<!NESTED_OBJECT_NOT_ALLOWED!>object Obj3<!>
}
}
}
@@ -61,7 +61,7 @@ enum class MyEnum {
class Outer {
inner class Inner {
object C {
<!NESTED_OBJECT_NOT_ALLOWED!>object C<!> {
const val a = 18
}
}
@@ -11425,6 +11425,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
doTest(fileName);
}
@TestMetadata("nestedObject.kt")
public void testNestedObject() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/nestedObject.kt");
doTest(fileName);
}
@TestMetadata("nestedVsInnerAccessOuterMember.kt")
public void testNestedVsInnerAccessOuterMember() throws Exception {
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt");