Report ILLEGAL_MODIFIER on inappropriate 'inner' keyword usage
#KT-1174 In Progress
This commit is contained in:
@@ -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;
|
||||
|
||||
@@ -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<JetKeywordToken> availableModifiers, Collection<JetToken>... availableCombinations) {
|
||||
if (modifierList == null) return;
|
||||
Collection<JetKeywordToken> presentModifiers = Sets.newLinkedHashSet();
|
||||
|
||||
@@ -0,0 +1,41 @@
|
||||
<!ILLEGAL_MODIFIER!>inner<!> fun foo() {}
|
||||
<!ILLEGAL_MODIFIER!>inner<!> val prop = 42
|
||||
|
||||
<!ILLEGAL_MODIFIER!>inner<!> class A
|
||||
<!ILLEGAL_MODIFIER!>inner<!> trait B
|
||||
<!ILLEGAL_MODIFIER!>inner<!> object C
|
||||
|
||||
class D {
|
||||
inner class E
|
||||
<!ILLEGAL_MODIFIER!>inner<!> trait F
|
||||
<!ILLEGAL_MODIFIER!>inner<!> object G
|
||||
<!ILLEGAL_MODIFIER!>inner<!> enum class R
|
||||
<!ILLEGAL_MODIFIER!>inner<!> annotation class S
|
||||
<!ILLEGAL_MODIFIER!>inner<!> class object
|
||||
}
|
||||
|
||||
enum class H {
|
||||
<!ILLEGAL_MODIFIER!>inner<!> I {
|
||||
inner class II
|
||||
}
|
||||
|
||||
inner class J
|
||||
}
|
||||
|
||||
trait K {
|
||||
<!ILLEGAL_MODIFIER!>inner<!> class L
|
||||
}
|
||||
|
||||
object N {
|
||||
inner class O
|
||||
}
|
||||
|
||||
class P {
|
||||
class object {
|
||||
inner class Q
|
||||
}
|
||||
}
|
||||
|
||||
val R = object {
|
||||
inner class S
|
||||
}
|
||||
@@ -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");
|
||||
|
||||
Reference in New Issue
Block a user