Skip to content

Commit 613cbd7

Browse files
committed
better error for StaticFieldShouldPrecedeNonStatic rule
1 parent dab02ed commit 613cbd7

File tree

4 files changed

+36
-2
lines changed

4 files changed

+36
-2
lines changed

compiler/src/dotty/tools/dotc/reporting/diagnostic/ErrorMessageID.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,8 @@ public enum ErrorMessageID {
142142
StaticOverridingNonStaticMembersID,
143143
OverloadInRefinementID,
144144
NoMatchingOverloadID,
145-
StableIdentPatternID
145+
StableIdentPatternID,
146+
StaticFieldsShouldPrecedeNonStaticID
146147
;
147148

148149
public int errorNumber() {

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1936,6 +1936,24 @@ object messages {
19361936
hl"${"@static"} members are only allowed inside objects."
19371937
}
19381938

1939+
case class StaticFieldsShouldPrecedeNonStatic(member: Symbol)(implicit ctx: Context) extends Message(StaticFieldsShouldPrecedeNonStaticID) {
1940+
val msg: String = hl"${"@static"} $member in ${member.owner} must be defined before non-static fields."
1941+
val kind: String = "Syntax"
1942+
val explanation: String = {
1943+
val codeExample = """object Foo {
1944+
| @static val foo = 1
1945+
| val bar = 2
1946+
|}"""
1947+
hl"""The fields annotated with @static should precede any non-@static fields.
1948+
|This ensures that we do not introduce surprises for users in initialization order of this class.
1949+
|$codeExample
1950+
|
1951+
|Static field are initialized when class loading the code of Foo.
1952+
|Non static fields are only initialized the first time that Foo is accessed.
1953+
|"""
1954+
}
1955+
}
1956+
19391957
case class CyclicInheritance(symbol: Symbol, addendum: String)(implicit ctx: Context) extends Message(CyclicInheritanceID) {
19401958
val kind: String = "Syntax"
19411959
val msg: String = hl"Cyclic inheritance: $symbol extends itself$addendum"

compiler/src/dotty/tools/dotc/transform/CheckStatic.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ class CheckStatic extends MiniPhase {
3737
}
3838

3939
if (defn.isInstanceOf[ValDef] && hadNonStaticField) {
40-
ctx.error("@static fields should precede non-static ones", defn.pos)
40+
ctx.error(StaticFieldsShouldPrecedeNonStatic(defn.symbol), defn.pos)
4141
}
4242

4343
val companion = ctx.owner.companionClass

compiler/test/dotty/tools/dotc/reporting/ErrorMessagesTests.scala

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1393,6 +1393,21 @@ class ErrorMessagesTests extends ErrorMessagesTest {
13931393
assertEquals(field.show, "method bar")
13941394
}
13951395

1396+
@Test def staticShouldPrecedeNonStatic =
1397+
checkMessagesAfter(CheckStatic.name) {
1398+
"""
1399+
|class Foo
1400+
|object Foo {
1401+
| val foo = 1
1402+
| @annotation.static val bar = 2
1403+
|}
1404+
""".stripMargin
1405+
}.expect { (ictx, messages) =>
1406+
implicit val ctx: Context = ictx
1407+
val StaticFieldsShouldPrecedeNonStatic(field) = messages.head
1408+
assertEquals(field.show, "value bar")
1409+
}
1410+
13961411
@Test def cyclicInheritance =
13971412
checkMessagesAfter(FrontEnd.name) {
13981413
"class A extends A"

0 commit comments

Comments
 (0)