From bac00786466df4f7580d11ca0cb4f4ef744f2f07 Mon Sep 17 00:00:00 2001 From: Svetlana Isakova Date: Wed, 22 Aug 2012 19:07:11 +0400 Subject: [PATCH] check modifiers for package declarations removed specific errors for illegal 'abstract' modifier --- .../jet/lang/diagnostics/Errors.java | 2 - .../rendering/DefaultErrorMessages.java | 2 - .../jet/lang/resolve/DeclarationsChecker.java | 41 ++++++++++--------- .../testData/diagnostics/tests/Abstract.kt | 20 ++++----- .../diagnostics/tests/StarsInFunctionCalls.kt | 2 +- .../packageDeclarationModifiers.kt | 13 ++++++ .../checkers/JetDiagnosticsTestGenerated.java | 5 +++ .../jet/plugin/quickfix/QuickFixes.java | 2 - 8 files changed, 50 insertions(+), 37 deletions(-) create mode 100644 compiler/testData/diagnostics/tests/declarationChecks/packageDeclarationModifiers.kt diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java index fa8ad97e514..e85e93c6689 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/Errors.java @@ -107,7 +107,6 @@ public interface Errors { DiagnosticFactory3 COMPONENT_FUNCTION_RETURN_TYPE_MISMATCH = DiagnosticFactory3.create(ERROR, DEFAULT); SimpleDiagnosticFactory ABSTRACT_PROPERTY_IN_PRIMARY_CONSTRUCTOR_PARAMETERS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER); - SimpleDiagnosticFactory ABSTRACT_PROPERTY_NOT_IN_CLASS = SimpleDiagnosticFactory.create(ERROR, ABSTRACT_MODIFIER); SimpleDiagnosticFactory ABSTRACT_PROPERTY_WITH_INITIALIZER = SimpleDiagnosticFactory.create(ERROR); SimpleDiagnosticFactory ABSTRACT_PROPERTY_WITH_GETTER = SimpleDiagnosticFactory.create(ERROR); SimpleDiagnosticFactoryABSTRACT_PROPERTY_WITH_SETTER = SimpleDiagnosticFactory.create(ERROR); @@ -124,7 +123,6 @@ public interface Errors { DiagnosticFactory2 ABSTRACT_FUNCTION_IN_NON_ABSTRACT_CLASS = DiagnosticFactory2.create(ERROR, ABSTRACT_MODIFIER); DiagnosticFactory1 ABSTRACT_FUNCTION_WITH_BODY = DiagnosticFactory1.create(ERROR, ABSTRACT_MODIFIER); DiagnosticFactory1 NON_ABSTRACT_FUNCTION_WITH_NO_BODY = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT); - DiagnosticFactory1 NON_MEMBER_ABSTRACT_FUNCTION = DiagnosticFactory1.create(ERROR, ABSTRACT_MODIFIER); DiagnosticFactory1 NON_MEMBER_FUNCTION_NO_BODY = DiagnosticFactory1.create(ERROR, NAMED_ELEMENT); SimpleDiagnosticFactory NON_FINAL_MEMBER_IN_FINAL_CLASS = SimpleDiagnosticFactory.create(WARNING, positionModifier(JetTokens.OPEN_KEYWORD)); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java index e2dbbe5d516..14169c7519b 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/diagnostics/rendering/DefaultErrorMessages.java @@ -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"); diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java index d6ca3d0163b..61f897cb842 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/DeclarationsChecker.java @@ -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) { diff --git a/compiler/testData/diagnostics/tests/Abstract.kt b/compiler/testData/diagnostics/tests/Abstract.kt index e7409af9f8a..4a25ee0088e 100644 --- a/compiler/testData/diagnostics/tests/Abstract.kt +++ b/compiler/testData/diagnostics/tests/Abstract.kt @@ -3,29 +3,29 @@ package MyNamespace //properties val a: Int val a1: Int = 1 - abstract val a2: Int - abstract val a3: Int = 1 + abstract val a2: Int + abstract val a3: Int = 1 var b: Int private set var b1: Int = 0; private set - abstract var b2: Int private set - abstract var b3: Int = 0; private set + abstract var b2: Int private set + abstract var b3: Int = 0; private set var c: Int set(v: Int) { $c = v } var c1: Int = 0; set(v: Int) { $c1 = v } - abstract var c2: Int set(v: Int) { $c2 = v } - abstract var c3: Int = 0; set(v: Int) { $c3 = v } + abstract var c2: Int set(v: Int) { $c2 = v } + abstract var c3: Int = 0; set(v: Int) { $c3 = v } val e: Int get() = a val e1: Int = 0; get() = a - abstract val e2: Int get() = a - abstract val e3: Int = 0; get() = a + abstract val e2: Int get() = a + abstract val e3: Int = 0; get() = a //methods fun f() fun g() {} - abstract fun h() - abstract fun j() {} + abstract fun h() + abstract fun j() {} //property accessors var i: Int abstract get abstract set diff --git a/compiler/testData/diagnostics/tests/StarsInFunctionCalls.kt b/compiler/testData/diagnostics/tests/StarsInFunctionCalls.kt index dc3f7be47bb..00f8dc6ee13 100644 --- a/compiler/testData/diagnostics/tests/StarsInFunctionCalls.kt +++ b/compiler/testData/diagnostics/tests/StarsInFunctionCalls.kt @@ -3,7 +3,7 @@ fun getTT() {} fun getTTT(x : Any) {} fun foo(a : Any?) {} -open fun main() { +public fun main() { getT<*>() ggetT<*>() getTT<*, *>() diff --git a/compiler/testData/diagnostics/tests/declarationChecks/packageDeclarationModifiers.kt b/compiler/testData/diagnostics/tests/declarationChecks/packageDeclarationModifiers.kt new file mode 100644 index 00000000000..d14b50f33e4 --- /dev/null +++ b/compiler/testData/diagnostics/tests/declarationChecks/packageDeclarationModifiers.kt @@ -0,0 +1,13 @@ +package d + +abstract val a : Int + +override val c : Int = 1 + +final fun foo() = 2 + +abstract fun baz() = 2 + +class T {} +override fun T.bar() = 2 + diff --git a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java index 55fffd2418a..b694569404e 100644 --- a/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java +++ b/compiler/tests/org/jetbrains/jet/checkers/JetDiagnosticsTestGenerated.java @@ -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"); diff --git a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java index 9745d393651..381a1b60a2f 100644 --- a/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java +++ b/idea/src/org/jetbrains/jet/plugin/quickfix/QuickFixes.java @@ -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));