check modifiers for package declarations

removed specific errors for illegal 'abstract' modifier
This commit is contained in:
Svetlana Isakova
2012-08-22 19:07:11 +04:00
parent 4a5269bb2d
commit bac0078646
8 changed files with 50 additions and 37 deletions
@@ -107,7 +107,6 @@ public interface Errors {
DiagnosticFactory3<JetExpression, Name, JetType, JetType> COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT);
SimpleDiagnosticFactory<JetModifierListOwner> ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER);
SimpleDiagnosticFactory<JetProperty> ABSTRACT_PROPERTY_NOT_IN_CLASS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER);
SimpleDiagnosticFactory<JetExpression> ABSTRACT_PROPERTY_WITH_INITIALIZER = SimpleDiagnosticFactory.create(ERROR);
SimpleDiagnosticFactory<JetPropertyAccessor> ABSTRACT_PROPERTY_WITH_GETTER = SimpleDiagnosticFactory.create(ERROR);
SimpleDiagnosticFactory<JetPropertyAccessor>ABSTRACT_PROPERTY_WITH_SETTER = SimpleDiagnosticFactory.create(ERROR);
@@ -124,7 +123,6 @@ public interface Errors {
DiagnosticFactory2<JetFunction, String, ClassDescriptor> ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = DiagnosticFactory2.create(ERROR, ABSTRACT_MODIFIER);
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> ABSTRACT_FUNCTION_WITH_BODY = DiagnosticFactory1.create(ERROR, ABSTRACT_MODIFIER);
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_ABSTRACT_FUNCTION_WITH_NO_BODY = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT);
DiagnosticFactory1<JetModifierListOwner, SimpleFunctionDescriptor> NON_MEMBER_ABSTRACT_FUNCTION = DiagnosticFactory1.create(ERROR, ABSTRACT_MODIFIER);
DiagnosticFactory1<JetFunction, SimpleFunctionDescriptor> NON_MEMBER_FUNCTION_NO_BODY = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT);
SimpleDiagnosticFactory<JetNamedDeclaration> NON_FINAL_MEMBER_IN_FINAL_CLASS = SimpleDiagnosticFactory.create(WARNING, positionModifier(JetTokens.OPEN_KEYWORD));
@@ -121,7 +121,6 @@ public class DefaultErrorMessages {
TO_STRING, RENDER_TYPE, RENDER_TYPE);
MAP.put(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, "This property cannot be declared abstract");
MAP.put(ABSTRACT_PROPERTY_NOT_IN_CLASS, "A property may be abstract only when defined in a class or trait");
MAP.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, "Property with initializer cannot be abstract");
MAP.put(ABSTRACT_PROPERTY_WITH_GETTER, "Property with getter implementation cannot be abstract");
MAP.put(ABSTRACT_PROPERTY_WITH_SETTER, "Property with setter implementation cannot be abstract");
@@ -138,7 +137,6 @@ public class DefaultErrorMessages {
MAP.put(ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS, "Abstract function ''{0}'' in non-abstract class ''{1}''", NAME, NAME);
MAP.put(ABSTRACT_FUNCTION_WITH_BODY, "A function ''{0}'' with body cannot be abstract", NAME);
MAP.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, "Function ''{0}'' without a body must be abstract", NAME);
MAP.put(NON_MEMBER_ABSTRACT_FUNCTION, "Function ''{0}'' is not a class or trait member and cannot be abstract", NAME);
MAP.put(NON_MEMBER_FUNCTION_NO_BODY, "Function ''{0}'' must have a body", NAME);
MAP.put(NON_FINAL_MEMBER_IN_FINAL_CLASS, "\"open\" has no effect in a final class");
@@ -19,6 +19,7 @@ package org.jetbrains.jet.lang.resolve;
import com.google.common.collect.Sets;
import com.intellij.lang.ASTNode;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.jetbrains.jet.lang.descriptors.*;
import org.jetbrains.jet.lang.diagnostics.Errors;
import org.jetbrains.jet.lang.psi.*;
@@ -125,11 +126,13 @@ public class DeclarationsChecker {
private void checkProperty(JetProperty property, PropertyDescriptor propertyDescriptor) {
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
ClassDescriptor classDescriptor = (containingDeclaration instanceof ClassDescriptor)
? (ClassDescriptor) containingDeclaration
: null;
checkPropertyAbstractness(property, propertyDescriptor, classDescriptor);
checkPropertyInitializer(property, propertyDescriptor, classDescriptor);
if (containingDeclaration instanceof ClassDescriptor) {
checkPropertyAbstractness(property, propertyDescriptor, (ClassDescriptor) containingDeclaration);
}
else {
modifiersChecker.checkIllegalModalityModifiers(property);
}
checkPropertyInitializer(property, propertyDescriptor);
checkAccessors(property, propertyDescriptor);
checkDeclaredTypeInPublicMember(property, propertyDescriptor);
}
@@ -149,17 +152,17 @@ public class DeclarationsChecker {
}
}
private void checkPropertyAbstractness(JetProperty property, PropertyDescriptor propertyDescriptor, ClassDescriptor classDescriptor) {
private void checkPropertyAbstractness(
@NotNull JetProperty property,
@NotNull PropertyDescriptor propertyDescriptor,
@NotNull ClassDescriptor classDescriptor
) {
JetPropertyAccessor getter = property.getGetter();
JetPropertyAccessor setter = property.getSetter();
JetModifierList modifierList = property.getModifierList();
ASTNode abstractNode = modifierList != null ? modifierList.getModifierNode(JetTokens.ABSTRACT_KEYWORD) : null;
if (abstractNode != null) { //has abstract modifier
if (classDescriptor == null) {
trace.report(ABSTRACT_PROPERTY_NOT_IN_CLASS.on(property));
return;
}
if (!(classDescriptor.getModality() == Modality.ABSTRACT) && classDescriptor.getKind() != ClassKind.ENUM_CLASS) {
JetClass classElement = (JetClass) BindingContextUtils.classDescriptorToDeclaration(trace.getBindingContext(), classDescriptor);
String name = property.getName();
@@ -190,7 +193,10 @@ public class DeclarationsChecker {
}
}
private void checkPropertyInitializer(JetProperty property, PropertyDescriptor propertyDescriptor, ClassDescriptor classDescriptor) {
private void checkPropertyInitializer(
@NotNull JetProperty property,
@NotNull PropertyDescriptor propertyDescriptor
) {
JetPropertyAccessor getter = property.getGetter();
JetPropertyAccessor setter = property.getSetter();
boolean hasAccessorImplementation = (getter != null && getter.getBodyExpression() != null) ||
@@ -202,8 +208,8 @@ public class DeclarationsChecker {
}
return;
}
boolean inTrait = classDescriptor != null && classDescriptor.getKind() == ClassKind.TRAIT;
DeclarationDescriptor containingDeclaration = propertyDescriptor.getContainingDeclaration();
boolean inTrait = containingDeclaration instanceof ClassDescriptor && ((ClassDescriptor)containingDeclaration).getKind() == ClassKind.TRAIT;
JetExpression initializer = property.getInitializer();
boolean backingFieldRequired = trace.getBindingContext().get(BindingContext.BACKING_FIELD_REQUIRED, propertyDescriptor);
@@ -213,7 +219,7 @@ public class DeclarationsChecker {
if (initializer == null) {
boolean error = false;
if (backingFieldRequired && !inTrait && !trace.getBindingContext().get(BindingContext.IS_INITIALIZED, propertyDescriptor)) {
if (classDescriptor == null || hasAccessorImplementation) {
if (!(containingDeclaration instanceof ClassDescriptor) || hasAccessorImplementation) {
error = true;
trace.report(MUST_BE_INITIALIZED.on(property));
}
@@ -259,15 +265,10 @@ public class DeclarationsChecker {
}
return;
}
if (hasAbstractModifier) {
trace.report(NON_MEMBER_ABSTRACT_FUNCTION.on(function, functionDescriptor));
}
modifiersChecker.checkIllegalModalityModifiers(function);
if (function.getBodyExpression() == null && !hasAbstractModifier) {
trace.report(NON_MEMBER_FUNCTION_NO_BODY.on(function, functionDescriptor));
}
if (function.hasModifier(JetTokens.OVERRIDE_KEYWORD)) {
trace.report(ILLEGAL_MODIFIER.on(function.getModifierList().getModifierNode(JetTokens.OVERRIDE_KEYWORD).getPsi(), JetTokens.OVERRIDE_KEYWORD));
}
}
private void checkAccessors(@NotNull JetProperty property, @NotNull PropertyDescriptor propertyDescriptor) {
+10 -10
View File
@@ -3,29 +3,29 @@ package MyNamespace
//properties
<!MUST_BE_INITIALIZED!>val a: Int<!>
val a1: Int = 1
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val a2: Int
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val a3: Int = 1
<!ILLEGAL_MODIFIER!>abstract<!> val a2: Int
<!ILLEGAL_MODIFIER!>abstract<!> val a3: Int = 1
<!MUST_BE_INITIALIZED!>var b: Int<!> private set
var b1: Int = 0; private set
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var b2: Int private set
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var b3: Int = 0; private set
<!ILLEGAL_MODIFIER!>abstract<!> var b2: Int private set
<!ILLEGAL_MODIFIER!>abstract<!> var b3: Int = 0; private set
<!MUST_BE_INITIALIZED!>var c: Int<!> set(v: Int) { $c = v }
var c1: Int = 0; set(v: Int) { $c1 = v }
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var c2: Int set(v: Int) { $c2 = v }
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> var c3: Int = 0; set(v: Int) { $c3 = v }
<!ILLEGAL_MODIFIER!>abstract<!> var c2: Int set(v: Int) { $c2 = v }
<!ILLEGAL_MODIFIER!>abstract<!> var c3: Int = 0; set(v: Int) { $c3 = v }
val e: Int get() = a
val e1: Int = <!PROPERTY_INITIALIZER_NO_BACKING_FIELD!>0<!>; get() = a
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val e2: Int get() = a
<!ABSTRACT_PROPERTY_NOT_IN_CLASS!>abstract<!> val e3: Int = 0; get() = a
<!ILLEGAL_MODIFIER!>abstract<!> val e2: Int get() = a
<!ILLEGAL_MODIFIER!>abstract<!> val e3: Int = 0; get() = a
//methods
<!NON_MEMBER_FUNCTION_NO_BODY!>fun f()<!>
fun g() {}
<!NON_MEMBER_ABSTRACT_FUNCTION!>abstract<!> fun h()
<!NON_MEMBER_ABSTRACT_FUNCTION!>abstract<!> fun j() {}
<!ILLEGAL_MODIFIER!>abstract<!> fun h()
<!ILLEGAL_MODIFIER!>abstract<!> fun j() {}
//property accessors
var i: Int <!ILLEGAL_MODIFIER!>abstract<!> get <!ILLEGAL_MODIFIER!>abstract<!> set
@@ -3,7 +3,7 @@ fun getTT<A, B>() {}
fun getTTT<A, B, C>(<!UNUSED_PARAMETER!>x<!> : Any) {}
fun foo(<!UNUSED_PARAMETER!>a<!> : Any?) {}
open fun main() {
public fun main() {
getT<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
<!UNRESOLVED_REFERENCE!>ggetT<!><<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
getTT<<!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>, <!PROJECTION_ON_NON_CLASS_TYPE_ARGUMENT!>*<!>>()
@@ -0,0 +1,13 @@
package d
<!ILLEGAL_MODIFIER!>abstract<!> val a : Int
<!ILLEGAL_MODIFIER!>override<!> val c : Int = 1
<!ILLEGAL_MODIFIER!>final<!> fun foo() = 2
<!ILLEGAL_MODIFIER!>abstract<!> fun baz() = 2
class T {}
<!ILLEGAL_MODIFIER!>override<!> fun T.bar() = 2
@@ -1118,6 +1118,11 @@ public class JetDiagnosticsTestGenerated extends AbstractDiagnosticsTestWithEage
doTest("compiler/testData/diagnostics/tests/declarationChecks/MultiDeclarationErrors.kt");
}
@TestMetadata("packageDeclarationModifiers.kt")
public void testPackageDeclarationModifiers() throws Exception {
doTest("compiler/testData/diagnostics/tests/declarationChecks/packageDeclarationModifiers.kt");
}
@TestMetadata("RedeclarationsInMultiDecl.kt")
public void testRedeclarationsInMultiDecl() throws Exception {
doTest("compiler/testData/diagnostics/tests/declarationChecks/RedeclarationsInMultiDecl.kt");
@@ -51,7 +51,6 @@ public class QuickFixes {
JetIntentionActionFactory addAbstractModifierFactory = AddModifierFix.createFactory(ABSTRACT_KEYWORD);
factories.put(ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS, removeAbstractModifierFactory);
factories.put(ABSTRACT_PROPERTY_NOT_IN_CLASS, removeAbstractModifierFactory);
JetIntentionActionFactory removePartsFromPropertyFactory = RemovePartsFromPropertyFix.createFactory();
factories.put(ABSTRACT_PROPERTY_WITH_INITIALIZER, removeAbstractModifierFactory);
@@ -82,7 +81,6 @@ public class QuickFixes {
factories.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addAbstractModifierFactory);
factories.put(NON_ABSTRACT_FUNCTION_WITH_NO_BODY, addFunctionBodyFactory);
factories.put(NON_MEMBER_ABSTRACT_FUNCTION, removeAbstractModifierFactory);
factories.put(NON_MEMBER_FUNCTION_NO_BODY, addFunctionBodyFactory);
factories.put(NOTHING_TO_OVERRIDE, RemoveModifierFix.createRemoveModifierFromListOwnerFactory(OVERRIDE_KEYWORD));