File tree Expand file tree Collapse file tree 4 files changed +40
-2
lines changed
test/dotty/tools/dotc/reporting Expand file tree Collapse file tree 4 files changed +40
-2
lines changed Original file line number Diff line number Diff 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 () {
Original file line number Diff line number Diff line change @@ -1936,6 +1936,28 @@ object messages {
19361936 hl " ${" @static" } members are only allowed inside objects. "
19371937 }
19381938
1939+ case class StaticFieldsShouldPrecedeNonStatic (member : Symbol , defns : List [tpd.Tree ])(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+
1943+ val explanation : String = {
1944+ val nonStatics = defns.takeWhile(_.symbol != member).take(3 ).filter(_.isInstanceOf [tpd.ValDef ])
1945+ val codeExample = s """ object ${member.owner.name.firstPart} {
1946+ | @static ${member} = ...
1947+ | ${nonStatics.map(m => s " ${m.symbol} = ... " ).mkString(" \n " )}
1948+ | ...
1949+ |} """
1950+ hl """ The fields annotated with @static should precede any non @static fields.
1951+ |This ensures that we do not introduce surprises for users in initialization order of this class.
1952+ |Static field are initialized when class loading the code of Foo.
1953+ |Non static fields are only initialized the first time that Foo is accessed.
1954+ |
1955+ |The definition of ${member.name} should have been before the non ${" @static val" }s:
1956+ | $codeExample
1957+ | """
1958+ }
1959+ }
1960+
19391961 case class CyclicInheritance (symbol : Symbol , addendum : String )(implicit ctx : Context ) extends Message (CyclicInheritanceID ) {
19401962 val kind : String = " Syntax"
19411963 val msg : String = hl " Cyclic inheritance: $symbol extends itself $addendum"
Original file line number Diff line number Diff 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, defns) , defn.pos)
4141 }
4242
4343 val companion = ctx.owner.companionClass
Original file line number Diff line number Diff 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"
You can’t perform that action at this time.
0 commit comments