diff --git a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java index 1a974344ae2..e9c85a789d2 100644 --- a/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java +++ b/compiler/frontend/src/org/jetbrains/jet/lang/resolve/ClassDescriptorResolver.java @@ -437,7 +437,7 @@ public class ClassDescriptorResolver { PropertyDescriptor propertyDescriptor = new PropertyDescriptor( containingDeclaration, annotationResolver.createAnnotationStubs(modifierList), - resolveModalityFromModifiers(trace, objectDeclaration.getModifierList()), // TODO : default modifiers differ in different contexts + Modality.FINAL, resolveVisibilityFromModifiers(trace, objectDeclaration.getModifierList()), false, null, @@ -548,11 +548,6 @@ public class ClassDescriptorResolver { } } - @NotNull - /*package*/ static Modality resolveModalityFromModifiers(@NotNull BindingTrace trace, @Nullable JetModifierList modifierList) { - return resolveModalityFromModifiers(trace, modifierList, Modality.FINAL); - } - @NotNull /*package*/ static Modality resolveModalityFromModifiers(@NotNull BindingTrace trace, @Nullable JetModifierList modifierList, @NotNull Modality defaultModality) { if (modifierList == null) return defaultModality; @@ -565,7 +560,7 @@ public class ClassDescriptorResolver { if (hasAbstractModifier || hasOverrideModifier) { trace.report(Errors.REDUNDANT_MODIFIER.on(modifierList, JetTokens.OPEN_KEYWORD, hasAbstractModifier ? JetTokens.ABSTRACT_KEYWORD : JetTokens.OVERRIDE_KEYWORD)); } - if (hasAbstractModifier) { + if (hasAbstractModifier || defaultModality == Modality.ABSTRACT) { return Modality.ABSTRACT; } return Modality.OPEN; @@ -573,10 +568,11 @@ public class ClassDescriptorResolver { if (hasAbstractModifier) { return Modality.ABSTRACT; } - if (hasOverrideModifier) { + boolean hasFinalModifier = modifierList.hasModifier(JetTokens.FINAL_KEYWORD); + if (hasOverrideModifier && !hasFinalModifier && !(defaultModality == Modality.ABSTRACT)) { return Modality.OPEN; } - if (modifierList.hasModifier(JetTokens.FINAL_KEYWORD)) { + if (hasFinalModifier) { return Modality.FINAL; } return defaultModality; @@ -634,7 +630,7 @@ public class ClassDescriptorResolver { JetParameter parameter = setter.getParameter(); setterDescriptor = new PropertySetterDescriptor( - resolveModalityFromModifiers(trace, setter.getModifierList()), // TODO : default modifiers differ in different contexts + resolveModalityFromModifiers(trace, setter.getModifierList(), propertyDescriptor.getModality()), resolveVisibilityFromModifiers(trace, setter.getModifierList(), propertyDescriptor.getVisibility()), propertyDescriptor, annotations, setter.getBodyExpression() != null, false); if (parameter != null) { @@ -709,7 +705,7 @@ public class ClassDescriptorResolver { } getterDescriptor = new PropertyGetterDescriptor( - resolveModalityFromModifiers(trace, getter.getModifierList()), // TODO : default modifiers differ in different contexts + resolveModalityFromModifiers(trace, getter.getModifierList(), propertyDescriptor.getModality()), resolveVisibilityFromModifiers(trace, getter.getModifierList(), propertyDescriptor.getVisibility()), propertyDescriptor, annotations, returnType, getter.getBodyExpression() != null, false); trace.record(BindingContext.PROPERTY_ACCESSOR, getter, getterDescriptor); @@ -785,7 +781,7 @@ public class ClassDescriptorResolver { PropertyDescriptor propertyDescriptor = new PropertyDescriptor( classDescriptor, annotationResolver.resolveAnnotations(scope, modifierList), - resolveModalityFromModifiers(trace, parameter.getModifierList()), + resolveModalityFromModifiers(trace, parameter.getModifierList(), Modality.FINAL), resolveVisibilityFromModifiers(trace, parameter.getModifierList()), isMutable, null, diff --git a/idea/tests/org/jetbrains/jet/JetTestUtils.java b/idea/tests/org/jetbrains/jet/JetTestUtils.java index 14e5a5b8412..9cb42a1648e 100644 --- a/idea/tests/org/jetbrains/jet/JetTestUtils.java +++ b/idea/tests/org/jetbrains/jet/JetTestUtils.java @@ -2,6 +2,7 @@ package org.jetbrains.jet; import org.jetbrains.annotations.NotNull; import org.jetbrains.jet.lang.diagnostics.Diagnostic; +import org.jetbrains.jet.lang.diagnostics.Severity; import org.jetbrains.jet.lang.diagnostics.UnresolvedReferenceDiagnostic; import org.jetbrains.jet.lang.resolve.BindingContext; import org.jetbrains.jet.lang.resolve.BindingTrace; @@ -55,4 +56,41 @@ public class JetTestUtils { } } }; + + public static BindingTrace DUMMY_EXCEPTION_ON_ERROR_TRACE = new BindingTrace() { + @Override + public BindingContext getBindingContext() { + return new BindingContext() { + @Override + public Collection getDiagnostics() { + throw new UnsupportedOperationException(); + } + + @Override + public V get(ReadOnlySlice slice, K key) { + return DUMMY_EXCEPTION_ON_ERROR_TRACE.get(slice, key); + } + }; + } + + @Override + public void record(WritableSlice slice, K key, V value) { + } + + @Override + public void record(WritableSlice slice, K key) { + } + + @Override + public V get(ReadOnlySlice slice, K key) { + return null; + } + + @Override + public void report(@NotNull Diagnostic diagnostic) { + if (diagnostic.getSeverity() == Severity.ERROR) { + throw new IllegalStateException(diagnostic.getMessage()); + } + } + }; } diff --git a/idea/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java b/idea/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java new file mode 100644 index 00000000000..6cbf896ed52 --- /dev/null +++ b/idea/tests/org/jetbrains/jet/types/JetDefaultModalityModifiersTest.java @@ -0,0 +1,407 @@ +package org.jetbrains.jet.types; + +import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase; +import org.jetbrains.jet.JetTestUtils; +import org.jetbrains.jet.lang.JetSemanticServices; +import org.jetbrains.jet.lang.descriptors.*; +import org.jetbrains.jet.lang.psi.*; +import org.jetbrains.jet.lang.resolve.BindingContext; +import org.jetbrains.jet.lang.resolve.ClassDescriptorResolver; +import org.jetbrains.jet.lang.resolve.scopes.JetScope; +import org.jetbrains.jet.lang.resolve.scopes.RedeclarationHandler; +import org.jetbrains.jet.lang.resolve.scopes.WritableScopeImpl; +import org.jetbrains.jet.lang.types.JetStandardLibrary; +import org.jetbrains.jet.plugin.AnalyzerFacade; + +import java.util.List; + +/** + * @author svtk + */ +public class JetDefaultModalityModifiersTest extends LightDaemonAnalyzerTestCase { + private JetDefaultModalityModifiersTestCase tc = new JetDefaultModalityModifiersTestCase(); + + @Override + public void setUp() throws Exception { + super.setUp(); + tc.setUp(); + } + + public static class JetDefaultModalityModifiersTestCase { + private ModuleDescriptor root = new ModuleDescriptor("test_root"); + private ClassDescriptorResolver classDescriptorResolver; + private JetScope scope; + + public void setUp() throws Exception { + JetStandardLibrary library = JetStandardLibrary.getJetStandardLibrary(getProject()); + JetSemanticServices semanticServices = JetSemanticServices.createSemanticServices(library); + classDescriptorResolver = semanticServices.getClassDescriptorResolver(JetTestUtils.DUMMY_EXCEPTION_ON_ERROR_TRACE); + scope = createScope(library.getLibraryScope()); + } + + private JetScope createScope(JetScope libraryScope) { + JetFile file = JetPsiFactory.createFile(getProject(), "abstract class C { abstract fun foo(); abstract val a: Int }"); + List declarations = file.getRootNamespace().getDeclarations(); + JetDeclaration aClass = declarations.get(0); + assert aClass instanceof JetClass; + BindingContext bindingContext = AnalyzerFacade.analyzeFileWithCache(file); + DeclarationDescriptor classDescriptor = bindingContext.get(BindingContext.DECLARATION_TO_DESCRIPTOR, aClass); + WritableScopeImpl scope = new WritableScopeImpl(libraryScope, root, RedeclarationHandler.DO_NOTHING); + assert classDescriptor instanceof ClassifierDescriptor; + scope.addClassifierDescriptor((ClassifierDescriptor) classDescriptor); + return scope; + } + + private MutableClassDescriptor createClassDescriptor(ClassKind kind, JetClass aClass) { + MutableClassDescriptor classDescriptor = new MutableClassDescriptor(JetTestUtils.DUMMY_TRACE, root, scope, kind); + classDescriptorResolver.resolveMutableClassDescriptor(aClass, classDescriptor); + return classDescriptor; + } + + private void testClassModality(String classDeclaration, ClassKind kind, Modality expectedModality) { + JetClass aClass = JetPsiFactory.createClass(getProject(), classDeclaration); + MutableClassDescriptor classDescriptor = createClassDescriptor(kind, aClass); + + assertEquals(expectedModality, classDescriptor.getModality()); + } + + + private void testFunctionModality(String classWithFunction, ClassKind kind, Modality expectedFunctionModality) { + JetClass aClass = JetPsiFactory.createClass(getProject(), classWithFunction); + MutableClassDescriptor classDescriptor = createClassDescriptor(kind, aClass); + + List declarations = aClass.getDeclarations(); + JetNamedFunction function = (JetNamedFunction) declarations.get(0); + FunctionDescriptorImpl functionDescriptor = classDescriptorResolver.resolveFunctionDescriptor(classDescriptor, scope, function); + + assertEquals(expectedFunctionModality, functionDescriptor.getModality()); + } + + private void testPropertyModality(String classWithProperty, ClassKind kind, Modality expectedPropertyModality) { + JetClass aClass = JetPsiFactory.createClass(getProject(), classWithProperty); + MutableClassDescriptor classDescriptor = createClassDescriptor(kind, aClass); + + List declarations = aClass.getDeclarations(); + JetProperty property = (JetProperty) declarations.get(0); + PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(classDescriptor, scope, property); + + assertEquals(expectedPropertyModality, propertyDescriptor.getModality()); + } + + + private void testPropertyAccessorModality(String classWithPropertyWithAccessor, ClassKind kind, Modality expectedPropertyAccessorModality, boolean isGetter) { + JetClass aClass = JetPsiFactory.createClass(getProject(), classWithPropertyWithAccessor); + MutableClassDescriptor classDescriptor = createClassDescriptor(kind, aClass); + + List declarations = aClass.getDeclarations(); + JetProperty property = (JetProperty) declarations.get(0); + PropertyDescriptor propertyDescriptor = classDescriptorResolver.resolvePropertyDescriptor(classDescriptor, scope, property); + PropertyAccessorDescriptor propertyAccessor = isGetter + ? propertyDescriptor.getGetter() + : propertyDescriptor.getSetter(); + assert propertyAccessor != null; + assertEquals(expectedPropertyAccessorModality, propertyAccessor.getModality()); + } + + public void testClassModality(String classDeclaration, Modality expectedModality) { + testClassModality(classDeclaration, ClassKind.CLASS, expectedModality); + } + + public void testTraitModality(String classDeclaration, Modality expectedModality) { + testClassModality(classDeclaration, ClassKind.TRAIT, expectedModality); + } + + public void testEnumModality(String classDeclaration, Modality expectedModality) { + testClassModality(classDeclaration, ClassKind.ENUM_CLASS, expectedModality); + } + + public void testFunctionModalityInClass(String classWithFunction, Modality expectedModality) { + testFunctionModality(classWithFunction, ClassKind.CLASS, expectedModality); + } + + public void testFunctionModalityInEnum(String classWithFunction, Modality expectedModality) { + testFunctionModality(classWithFunction, ClassKind.ENUM_CLASS, expectedModality); + } + + public void testFunctionModalityInTrait(String classWithFunction, Modality expectedModality) { + testFunctionModality(classWithFunction, ClassKind.TRAIT, expectedModality); + } + + public void testPropertyModalityInClass(String classWithProperty, Modality expectedModality) { + testPropertyModality(classWithProperty, ClassKind.CLASS, expectedModality); + } + + public void testPropertyModalityInEnum(String classWithProperty, Modality expectedModality) { + testPropertyModality(classWithProperty, ClassKind.ENUM_CLASS, expectedModality); + } + + public void testPropertyModalityInTrait(String classWithProperty, Modality expectedModality) { + testPropertyModality(classWithProperty, ClassKind.TRAIT, expectedModality); + } + + public void testPropertyAccessorModalityInClass(String classWithPropertyWithAccessor, Modality expectedModality) { + testPropertyAccessorModality(classWithPropertyWithAccessor, ClassKind.CLASS, expectedModality, true); + } + + public void testPropertyAccessorModalityInTrait(String classWithPropertyWithAccessor, Modality expectedModality) { + testPropertyAccessorModality(classWithPropertyWithAccessor, ClassKind.TRAIT, expectedModality, true); + } + + public void testPropertyAccessorModalityInClass(String classWithPropertyWithAccessor, Modality expectedModality, boolean isGetter) { + testPropertyAccessorModality(classWithPropertyWithAccessor, ClassKind.CLASS, expectedModality, isGetter); + } + + public void testPropertyAccessorModalityInTrait(String classWithPropertyWithAccessor, Modality expectedModality, boolean isGetter) { + testPropertyAccessorModality(classWithPropertyWithAccessor, ClassKind.TRAIT, expectedModality, isGetter); + } + } + + public void testClassModality() { + tc.testClassModality("class A {}", Modality.FINAL); + tc.testClassModality("open class A {}", Modality.OPEN); + tc.testClassModality("abstract class A {}", Modality.ABSTRACT); + tc.testClassModality("final class A {}", Modality.FINAL); + tc.testClassModality("open abstract class A {}", Modality.ABSTRACT); + + tc.testEnumModality("enum class A {}", Modality.FINAL); + tc.testEnumModality("open enum class A {}", Modality.OPEN); + tc.testEnumModality("abstract enum class A {}", Modality.ABSTRACT); + tc.testEnumModality("final enum class A {}", Modality.FINAL); + + tc.testTraitModality("trait A {}", Modality.ABSTRACT); + tc.testTraitModality("open trait A {}", Modality.ABSTRACT); + tc.testTraitModality("abstract trait A {}", Modality.ABSTRACT); + } + + public void testFunctionModality() { + tc.testFunctionModalityInClass("class A { fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInClass("class A { open fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInClass("class A { final fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInClass("open class A { fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInClass("open class A { open fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInClass("open class A { final fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInClass("abstract class A { open fun foo() }", Modality.OPEN); + tc.testFunctionModalityInClass("abstract class A { abstract fun foo() }", Modality.ABSTRACT); + + tc.testFunctionModalityInEnum("enum class A { fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInEnum("enum class A { final fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInEnum("open enum class A { open fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInEnum("abstract enum class A { open fun foo() }", Modality.OPEN); + tc.testFunctionModalityInEnum("abstract enum class A { abstract fun foo() }", Modality.ABSTRACT); + + tc.testFunctionModalityInTrait("trait A { fun foo() }", Modality.ABSTRACT); + tc.testFunctionModalityInTrait("trait A { abstract fun foo() }", Modality.ABSTRACT); + tc.testFunctionModalityInTrait("trait A { fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInTrait("trait A { open fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInTrait("trait A { final fun foo() {} }", Modality.FINAL); + } + + public void testFunctionModalityWithOverride() { + tc.testFunctionModalityInClass("class A : C { override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInClass("class A : C { open override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInClass("class A : C { final override fun foo() {} }", Modality.FINAL); + + tc.testFunctionModalityInClass("open class A : C { override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInClass("open class A : C { open override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInClass("open class A : C { final override fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInClass("abstract class A : C { open override fun foo() }", Modality.OPEN); + tc.testFunctionModalityInClass("abstract class A : C { abstract override fun foo() }", Modality.ABSTRACT); + + tc.testFunctionModalityInEnum("enum class A : C { override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInEnum("enum class A : C { final override fun foo() {} }", Modality.FINAL); + tc.testFunctionModalityInEnum("open enum class A : C { open override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInEnum("abstract enum class A : C { open override fun foo() }", Modality.OPEN); + tc.testFunctionModalityInEnum("abstract enum class A : C { abstract override fun foo() }", Modality.ABSTRACT); + + tc.testFunctionModalityInTrait("trait A : C { override fun foo() }", Modality.ABSTRACT); + tc.testFunctionModalityInTrait("trait A : C { abstract override fun foo() }", Modality.ABSTRACT); + tc.testFunctionModalityInTrait("trait A : C { override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInTrait("trait A : C { open override fun foo() {} }", Modality.OPEN); + tc.testFunctionModalityInTrait("trait A : C { final override fun foo() {} }", Modality.FINAL); + } + + public void testPropertyModality() { + tc.testPropertyModalityInClass("class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("class A { final val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("open class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("open class A { final val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("open class A { open val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("abstract class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("abstract class A { open val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("abstract class A { abstract val a: Int }", Modality.ABSTRACT); + + tc.testPropertyModalityInEnum("enum class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInEnum("enum class A { final val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInEnum("open enum class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInEnum("open enum class A { final val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInEnum("open enum class A { open val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInEnum("abstract enum class A { open val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInEnum("abstract enum class A { abstract val a: Int }", Modality.ABSTRACT); + + tc.testPropertyModalityInTrait("trait A { val a: Int }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A { open val a: Int }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A { abstract val a: Int }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A { open abstract val a: Int }", Modality.ABSTRACT); + + tc.testPropertyModalityInTrait("trait A { val a: Int get() = 10 }", Modality.OPEN); + tc.testPropertyModalityInTrait("trait A { var a: Int get() = 1; set(v: Int) {} }", Modality.OPEN); + tc.testPropertyModalityInTrait("trait A { val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A { var a: Int open get open set}", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A { open val a: Int get }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A { open val a: Int get() = 1 }", Modality.OPEN); + tc.testPropertyModalityInTrait("trait A { open val a: Int final get() = 1 }", Modality.OPEN); + } + + public void testPropertyModalityWithOverride() { + tc.testPropertyModalityInClass("class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("class A : C { final override val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("open class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("open class A : C { final override val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInClass("open class A : C { open override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("abstract class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("abstract class A : C { open override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInClass("abstract class A : C { abstract override val a: Int }", Modality.ABSTRACT); + + tc.testPropertyModalityInEnum("enum class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInEnum("enum class A : C { final override val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInEnum("open enum class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInEnum("open enum class A : C { final override val a: Int = 0 }", Modality.FINAL); + tc.testPropertyModalityInEnum("open enum class A : C { open override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInEnum("abstract enum class A : C { open override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyModalityInEnum("abstract enum class A : C { abstract override val a: Int }", Modality.ABSTRACT); + + tc.testPropertyModalityInTrait("trait A : C { override val a: Int }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A : C { open override val a: Int }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A : C { abstract override val a: Int }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A : C { open abstract override val a: Int }", Modality.ABSTRACT); + + tc.testPropertyModalityInTrait("trait A : C { override val a: Int get() = 10 }", Modality.OPEN); + tc.testPropertyModalityInTrait("trait A : C { override var a: Int get() = 1; set(v: Int) {} }", Modality.OPEN); + tc.testPropertyModalityInTrait("trait A : C { override val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A : C { override var a: Int open get open set }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A : C { open override val a: Int get }", Modality.ABSTRACT); + tc.testPropertyModalityInTrait("trait A : C { open override val a: Int get() = 1 }", Modality.OPEN); + tc.testPropertyModalityInTrait("trait A : C { open override val a: Int final get() = 1 }", Modality.OPEN); + } + + public void testPropertyAccessorModality() { + tc.testPropertyAccessorModalityInClass("class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("class A { val a: Int = 0; get }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("class A { val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("class A { final val a: Int = 0 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("class A { final val a: Int = 0; get }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("class A { final val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("open class A { val a: Int = 0 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("open class A { val a: Int = 0; get }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("open class A { val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("open class A { open val a: Int = 0 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A { open val a: Int = 0; get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A { open val a: Int = 0; open get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A { open val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("open class A { final val a: Int = 0 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("open class A { final val a: Int = 0; get }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("open class A { final val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("abstract class A { abstract val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { abstract val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { abstract val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { abstract val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { val a: Int get() = 10 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("abstract class A { val a: Int open get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { val a: Int final get() = 10 }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open val a: Int get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { open val a: Int open get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { open val a: Int final get() = 10 }", Modality.FINAL); + + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int open get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int final get }", Modality.FINAL); + tc.testPropertyAccessorModalityInTrait("trait A { val a: Int final get() = 1 }", Modality.FINAL); + + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int open get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int final get }", Modality.FINAL); + tc.testPropertyAccessorModalityInTrait("abstract trait A { val a: Int final get() = 1 }", Modality.FINAL); + } + + public void testPropertyAccessorModalityWithOverride() { + tc.testPropertyAccessorModalityInClass("class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("class A : C { override val a: Int = 0; get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("class A : C { override val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("class A : C { final override val a: Int = 0 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("class A : C { final override val a: Int = 0; get }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("class A : C { final override val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("open class A : C { override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A : C { override val a: Int = 0; get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A : C { override val a: Int = 0; open get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A : C { override val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("open class A : C { open override val a: Int = 0 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A : C { open override val a: Int = 0; get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A : C { open override val a: Int = 0; open get }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("open class A : C { open override val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("open class A : C { final override val a: Int = 0 }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("open class A : C { final override val a: Int = 0; get }", Modality.FINAL); + tc.testPropertyAccessorModalityInClass("open class A : C { final override val a: Int = 0; final get }", Modality.FINAL); + + tc.testPropertyAccessorModalityInTrait("trait A : C { override val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A : C { override val a: Int = 0; get }", Modality.OPEN); + + tc.testPropertyAccessorModalityInTrait("trait A : C { abstract override val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A : C { abstract override val a: Int get }", Modality.ABSTRACT); + + tc.testPropertyAccessorModalityInClass("abstract class A { abstract override val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { abstract override val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { abstract override val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { abstract override val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { override val a: Int get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { override val a: Int open get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { override val a: Int final get() = 10 }", Modality.FINAL); + + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract override val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract override val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract override val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open abstract override val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInClass("abstract class A { open override val a: Int get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { open override val a: Int open get() = 10 }", Modality.OPEN); + tc.testPropertyAccessorModalityInClass("abstract class A { open override val a: Int final get() = 10 }", Modality.FINAL); + + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int open get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int final get }", Modality.FINAL); + tc.testPropertyAccessorModalityInTrait("trait A { override val a: Int final get() = 1 }", Modality.FINAL); + + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int abstract get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int open get }", Modality.ABSTRACT); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int open get() = 1 }", Modality.OPEN); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int final get }", Modality.FINAL); + tc.testPropertyAccessorModalityInTrait("abstract trait A { override val a: Int final get() = 1 }", Modality.FINAL); + } +}