Prohibit objects inside inner classes
#KT-16232 Fixed
This commit is contained in:
@@ -892,6 +892,7 @@ public interface Errors {
|
|||||||
|
|
||||||
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
|
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
|
||||||
DiagnosticFactory0<KtClass> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
|
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
|
//Inline and inlinable parameters
|
||||||
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> NON_PUBLIC_CALL_FROM_PUBLIC_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
DiagnosticFactory2<KtElement, DeclarationDescriptor, DeclarationDescriptor> NON_PUBLIC_CALL_FROM_PUBLIC_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
|
||||||
|
|||||||
+1
@@ -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(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_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_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);
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import org.jetbrains.kotlin.resolve.checkers.UnderscoreChecker;
|
|||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
import static org.jetbrains.kotlin.diagnostics.Errors.NESTED_CLASS_NOT_ALLOWED;
|
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.lexer.KtTokens.*;
|
||||||
import static org.jetbrains.kotlin.psi.KtStubbedPsiUtil.getContainingDeclaration;
|
import static org.jetbrains.kotlin.psi.KtStubbedPsiUtil.getContainingDeclaration;
|
||||||
|
|
||||||
@@ -219,10 +220,20 @@ public class ModifiersChecker {
|
|||||||
|
|
||||||
public void checkModifiersForDeclaration(@NotNull KtDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
|
public void checkModifiersForDeclaration(@NotNull KtDeclaration modifierListOwner, @NotNull MemberDescriptor descriptor) {
|
||||||
checkNestedClassAllowed(modifierListOwner, descriptor);
|
checkNestedClassAllowed(modifierListOwner, descriptor);
|
||||||
|
checkObjectInsideInnerClass(modifierListOwner, descriptor);
|
||||||
checkTypeParametersModifiers(modifierListOwner);
|
checkTypeParametersModifiers(modifierListOwner);
|
||||||
checkModifierListCommon(modifierListOwner, descriptor);
|
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) {
|
private void checkModifierListCommon(@NotNull KtDeclaration modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
|
||||||
AnnotationUseSiteTargetChecker.INSTANCE.check(modifierListOwner, descriptor, trace);
|
AnnotationUseSiteTargetChecker.INSTANCE.check(modifierListOwner, descriptor, trace);
|
||||||
runDeclarationCheckers(modifierListOwner, descriptor);
|
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 {
|
class Outer {
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
object C {
|
<!NESTED_OBJECT_NOT_ALLOWED!>object C<!> {
|
||||||
const val a = 18
|
const val a = 18
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11425,6 +11425,12 @@ public class DiagnosticsTestGenerated extends AbstractDiagnosticsTest {
|
|||||||
doTest(fileName);
|
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")
|
@TestMetadata("nestedVsInnerAccessOuterMember.kt")
|
||||||
public void testNestedVsInnerAccessOuterMember() throws Exception {
|
public void testNestedVsInnerAccessOuterMember() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/diagnostics/tests/inner/nestedVsInnerAccessOuterMember.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user