Improve error message for inner class in trait

This commit is contained in:
Pavel V. Talanov
2015-02-19 19:02:54 +03:00
parent 2053da91dd
commit 460c1e328f
5 changed files with 39 additions and 8 deletions
@@ -614,6 +614,8 @@ public interface Errors {
DiagnosticFactory1<PsiElement, ClassDescriptor> INACCESSIBLE_OUTER_CLASS_EXPRESSION = DiagnosticFactory1.create(ERROR);
DiagnosticFactory0<JetClass> NESTED_CLASS_NOT_ALLOWED = DiagnosticFactory0.create(ERROR, DECLARATION_NAME);
DiagnosticFactory0<JetClass> INNER_CLASS_IN_TRAIT = DiagnosticFactory0.create(ERROR, PositioningStrategies.INNER_MODIFIER);
//Inline and inlinable parameters
DiagnosticFactory2<JetElement, DeclarationDescriptor, DeclarationDescriptor> INVISIBLE_MEMBER_FROM_INLINE = DiagnosticFactory2.create(ERROR, CALL_ELEMENT);
DiagnosticFactory3<JetElement, JetElement, DeclarationDescriptor, DeclarationDescriptor> NON_LOCAL_RETURN_NOT_ALLOWED = DiagnosticFactory3.create(ERROR, CALL_ELEMENT);
@@ -159,6 +159,8 @@ public object PositioningStrategies {
public val ABSTRACT_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.ABSTRACT_KEYWORD)
public val INNER_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.INNER_KEYWORD)
public val OVERRIDE_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.OVERRIDE_KEYWORD)
public val FINAL_MODIFIER: PositioningStrategy<JetModifierListOwner> = modifierSetPosition(JetTokens.FINAL_KEYWORD)
@@ -325,6 +325,8 @@ 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(INNER_CLASS_IN_TRAIT, "Inner classes are not allowed in traits");
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_NONE_APPLICABLE, "None of the hasNext() functions is applicable for iterator() of type ''{0}''", RENDER_TYPE);
@@ -26,7 +26,7 @@ import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.kotlin.descriptors.*;
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor;
import org.jetbrains.kotlin.diagnostics.Errors;
import org.jetbrains.kotlin.diagnostics.*;
import org.jetbrains.kotlin.lexer.JetModifierKeywordToken;
import org.jetbrains.kotlin.lexer.JetTokens;
import org.jetbrains.kotlin.name.FqName;
@@ -195,8 +195,17 @@ public class ModifiersChecker {
private void checkInnerModifier(@NotNull JetModifierListOwner modifierListOwner, @NotNull DeclarationDescriptor descriptor) {
if (modifierListOwner.hasModifier(INNER_KEYWORD)) {
if (isIllegalInner(descriptor)) {
checkIllegalInThisContextModifiers(modifierListOwner, Collections.singletonList(INNER_KEYWORD));
switch (checkIllegalInner(descriptor)) {
case ALLOWED:
break;
case ILLEGAL_POSITION:
checkIllegalInThisContextModifiers(modifierListOwner, Collections.singletonList(INNER_KEYWORD));
break;
case IN_TRAIT:
if (modifierListOwner instanceof JetClass) {
trace.report(INNER_CLASS_IN_TRAIT.on((JetClass) modifierListOwner));
}
break;
}
return;
}
@@ -210,12 +219,28 @@ public class ModifiersChecker {
}
public static boolean isIllegalInner(@NotNull DeclarationDescriptor descriptor) {
if (!(descriptor instanceof ClassDescriptor)) return true;
return checkIllegalInner(descriptor) != InnerModifierCheckResult.ALLOWED;
}
private enum InnerModifierCheckResult {
ALLOWED,
ILLEGAL_POSITION,
IN_TRAIT
}
@NotNull
private static InnerModifierCheckResult checkIllegalInner(DeclarationDescriptor descriptor) {
if (!(descriptor instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
ClassDescriptor classDescriptor = (ClassDescriptor) descriptor;
if (classDescriptor.getKind() != ClassKind.CLASS) return true;
if (classDescriptor.getKind() != ClassKind.CLASS) return InnerModifierCheckResult.ILLEGAL_POSITION;
DeclarationDescriptor containingDeclaration = classDescriptor.getContainingDeclaration();
if (!(containingDeclaration instanceof ClassDescriptor)) return true;
return ((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT;
if (!(containingDeclaration instanceof ClassDescriptor)) return InnerModifierCheckResult.ILLEGAL_POSITION;
if (((ClassDescriptor) containingDeclaration).getKind() == ClassKind.TRAIT) {
return InnerModifierCheckResult.IN_TRAIT;
}
else {
return InnerModifierCheckResult.ALLOWED;
}
}
private static boolean isIllegalNestedClass(@NotNull DeclarationDescriptor descriptor) {
@@ -23,7 +23,7 @@ enum class H {
}
trait K {
<!ILLEGAL_MODIFIER!>inner<!> class L
<!INNER_CLASS_IN_TRAIT!>inner<!> class L
}
object N {