diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java index 730f493690b..f7320f3c81a 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DescriptorUtils.java @@ -23,6 +23,7 @@ import org.jetbrains.jet.lang.descriptors.*; import org.jetbrains.jet.lang.descriptors.annotations.AnnotationDescriptor; import org.jetbrains.jet.lang.psi.JetElement; import org.jetbrains.jet.lang.psi.JetFunction; +import org.jetbrains.jet.lang.psi.JetPsiUtil; import org.jetbrains.jet.lang.resolve.constants.CompileTimeConstant; import org.jetbrains.jet.lang.resolve.name.FqName; import org.jetbrains.jet.lang.resolve.name.FqNameUnsafe; diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java index 9cabb0973e3..ce15a1bb20d 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ModifiersChecker.java @@ -31,6 +31,7 @@ import org.jetbrains.jet.lexer.JetKeywordToken; import org.jetbrains.jet.lexer.JetToken; import java.util.Collection; +import java.util.Collections; import java.util.Map; import static org.jetbrains.jet.lexer.JetTokens.*; @@ -57,6 +58,7 @@ public class ModifiersChecker { JetModifierList modifierList = modifierListOwner.getModifierList(); checkModalityModifiers(modifierList); checkVisibilityModifiers(modifierList, descriptor); + checkInnerModifier(modifierListOwner, descriptor); } public void checkModifiersForLocalDeclaration(@NotNull JetModifierListOwner modifierListOwner) { @@ -93,6 +95,25 @@ public class ModifiersChecker { checkCompatibility(modifierList, VISIBILITY_MODIFIERS); } + private void checkInnerModifier(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) { + JetModifierList modifierList = modifierListOwner.getModifierList(); + + if (modifierList != null && modifierList.hasModifier(INNER_KEYWORD)) { + if (isIllegalInner(descriptor)) { + checkIllegalInThisContextModifiers(modifierList, Collections.singletonList(INNER_KEYWORD)); + } + } + } + + private static boolean isIllegalInner(@NotNull DeclarationDescriptor descriptor) { + if (!(descriptor instanceof ClassDescriptor)) return true; + ClassDescriptor classDescriptor = (ClassDescriptor) descriptor; + if (classDescriptor.getKind() != ClassKind.CLASS) return true; + DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration(); + if (!(containingDeclaration instanceof ClassDescriptor)) return true; + return ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT; + } + private void checkCompatibility(@Nullable JetModifierList modifierList, Collection availableModifiers, Collection... availableCombinations) { if (modifierList == null) return; Collection presentModifiers = Sets.newLinkedHashSet(); diff --git a/compiler/testData/diagnostics/tests/inner/illegalModifier.kt b/compiler/testData/diagnostics/tests/inner/illegalModifier.kt new file mode 100644 index 00000000000..2c98ac6fead --- /dev/null +++ b/compiler/testData/diagnostics/tests/inner/illegalModifier.kt @@ -0,0 +1,41 @@ +inner fun foo() {} +inner val prop = 42 + +inner class A +inner trait B +inner object C + +class D { + inner class E + inner trait F + inner object G + inner enum class R + inner annotation class S + inner class object +} + +enum class H { + inner I { + inner class II + } + + inner class J +} + +trait K { + inner class L +} + +object N { + inner class O +} + +class P { + class object { + inner class Q + } +} + +val R = object { + inner class S +} diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 17a11037c32..c2f4951dcee 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -2419,6 +2419,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage doTest("compiler/testData/diagnostics/tests/inner/extensionFun.kt"); } + @TestMetadata("illegalModifier.kt") + public void testIllegalModifier() throws Exception { + doTest("compiler/testData/diagnostics/tests/inner/illegalModifier.kt"); + } + @TestMetadata("innerThisSuper.kt") public void testInnerThisSuper() throws Exception { doTest("compiler/testData/diagnostics/tests/inner/innerThisSuper.kt");