From b195cb82425bf10a9306f501d880d73382d86893 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Pedro=20Evangelista?= Date: Thu, 11 Oct 2018 01:58:37 -0300 Subject: [PATCH] Add error messages for CheckStatic Adds messages for checking of companions and @static fields - Static overriding non static member - Lazy static field - Trait's companion defining mutable static field Part of #1589 --- .../reporting/diagnostic/ErrorMessageID.java | 5 +- .../dotc/reporting/diagnostic/messages.scala | 21 +++++++ .../tools/dotc/transform/CheckStatic.scala | 8 +-- .../dotc/reporting/ErrorMessagesTests.scala | 60 +++++++++++++++++++ 4 files changed, 89 insertions(+), 5 deletions(-) diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java index 14c8c1ecf7ec..b4d74a835114 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java @@ -136,7 +136,10 @@ public enum ErrorMessageID { ValueClassParameterMayNotBeCallByNameID, NotAnExtractorID, MemberWithSameNameAsStaticID, - PureExpressionInStatementPositionID + PureExpressionInStatementPositionID, + TraitCompanionWithMutableStaticID, + LazyStaticFieldID, + StaticOverridingNonStaticMembersID ; public int errorNumber() { diff --git a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala index bd19f7954f43..69137706cf2c 100644 --- a/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala +++ b/compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala @@ -2149,4 +2149,25 @@ object messages { hl"""The pure expression `$stat` doesn't have any side effect and its result is not assigned elsewhere. |It can be removed without changing the semantics of the program. This may indicate an error.""".stripMargin } + + case class TraitCompanionWithMutableStatic()(implicit val ctx: Context) + extends Message(TraitCompanionWithMutableStaticID) { + override def msg: String = hl"Companion of traits cannot define mutable @static fields" + override def kind: String = "Syntax" + override def explanation: String = "" + } + + case class LazyStaticField()(implicit val ctx: Context) + extends Message(LazyStaticFieldID) { + override def msg: String = hl"Lazy @static fields are not supported" + override def kind: String = "Syntax" + override def explanation: String = "" + } + + case class StaticOverridingNonStaticMembers()(implicit val ctx: Context) + extends Message(StaticOverridingNonStaticMembersID) { + override def msg: String = hl"@static members cannot override or implement non-static ones" + override def kind: String = "Syntax" + override def explanation: String = "" + } } diff --git a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala index 157c22d02953..845725c24bbe 100644 --- a/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala +++ b/compiler/src/dotty/tools/dotc/transform/CheckStatic.scala @@ -8,7 +8,7 @@ import Contexts.Context import Symbols._ import dotty.tools.dotc.ast.tpd import Decorators._ -import reporting.diagnostic.messages.{MemberWithSameNameAsStatic, MissingCompanionForStatic, StaticFieldsOnlyAllowedInObjects} +import reporting.diagnostic.messages._ /** A transformer that check that requirements of Static fields\methods are implemented: * 1. Only objects can have members annotated with `@static` @@ -48,11 +48,11 @@ class CheckStatic extends MiniPhase { } else if (clashes.exists) { ctx.error(MemberWithSameNameAsStatic(), defn.pos) } else if (defn.symbol.is(Flags.Mutable) && companion.is(Flags.Trait)) { - ctx.error("Companions of traits cannot define mutable @static fields", defn.pos) + ctx.error(TraitCompanionWithMutableStatic(), defn.pos) } else if (defn.symbol.is(Flags.Lazy)) { - ctx.error("Lazy @static fields are not supported", defn.pos) + ctx.error(LazyStaticField(), defn.pos) } else if (defn.symbol.allOverriddenSymbols.nonEmpty) { - ctx.error("@static members cannot override or implement non-static ones", defn.pos) + ctx.error(StaticOverridingNonStaticMembers(), defn.pos) } } else hadNonStaticField = hadNonStaticField || defn.isInstanceOf[ValDef] diff --git a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala index b8018ba39b4c..575f04a08c0b 100644 --- a/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala +++ b/compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala @@ -1545,4 +1545,64 @@ class ErrorMessagesTests extends ErrorMessagesTest { assertTrue(message.isInstanceOf[MemberWithSameNameAsStatic]) assertEquals(message.msg, "Companion classes cannot define members with same name as a @static member") } + + @Test def companionOfTraitWithMutableStatic() = + checkMessagesAfter(CheckStatic.name) { + """ + | import scala.annotation.static + | trait Test + | object Test { + | @static var myStatic = "" + | } + """.stripMargin + }.expect { (_, messages) => + assertMessageCount(1, messages) + val message = messages.head + assertTrue(message.isInstanceOf[TraitCompanionWithMutableStatic]) + assertEquals( + "Companion of traits cannot define mutable @static fields", + message.msg + ) + } + + @Test def lazyStaticField() = + checkMessagesAfter(CheckStatic.name) { + """ + | import scala.annotation.static + | class Test + | object Test { + | @static lazy val myStatic = "" + | } + """.stripMargin + }.expect { (_, messages) => + assertMessageCount(1, messages) + val message = messages.head + assertTrue(message.isInstanceOf[LazyStaticField]) + assertEquals( + "Lazy @static fields are not supported", + message.msg + ) + } + + @Test def staticOverridingNonStatic() = + checkMessagesAfter(CheckStatic.name) { + """ + | import scala.annotation.static + | trait Foo { + | val foo = "" + | } + | class Test + | object Test extends Foo { + | @static val foo = "" + | } + """.stripMargin + }.expect { (_, messages) => + assertMessageCount(1, messages) + val message = messages.head + assertTrue(message.isInstanceOf[StaticOverridingNonStaticMembers]) + assertEquals( + "@static members cannot override or implement non-static ones", + message.msg + ) + } }