@@ -601,9 +601,53 @@ object JavaParsers {
601
601
602
602
def varDecl (mods : Modifiers , tpt : Tree , name : TermName ): ValDef = {
603
603
val tpt1 = optArrayBrackets(tpt)
604
- if (in.token == EQUALS && ! mods.is(Flags .Param )) skipTo(COMMA , SEMI )
604
+ /** Tries to detect final static literals syntactically and returns a constant type replacement */
605
+ def optConstantTpe (): Tree = {
606
+ def constantTpe (const : Constant ): Tree = TypeTree (ConstantType (const))
607
+
608
+ def forConst (const : Constant ): Tree = {
609
+ if (in.token != SEMI ) tpt1
610
+ else {
611
+ def isStringTyped = tpt1 match {
612
+ case Ident (n : TypeName ) => " String" == n.toString
613
+ case _ => false
614
+ }
615
+ if (const.tag == Constants .StringTag && isStringTyped) constantTpe(const)
616
+ else tpt1 match {
617
+ case TypedSplice (tpt2) =>
618
+ if (const.tag == Constants .BooleanTag || const.isNumeric) {
619
+ // for example, literal 'a' is ok for float. 127 is ok for byte, but 128 is not.
620
+ val converted = const.convertTo(tpt2.tpe)
621
+ if (converted == null ) tpt1
622
+ else constantTpe(converted)
623
+ }
624
+ else tpt1
625
+ case _ => tpt1
626
+ }
627
+ }
628
+ }
629
+
630
+ in.nextToken() // EQUALS
631
+ if (mods.is(Flags .JavaStatic ) && mods.is(Flags .Final )) {
632
+ val neg = in.token match {
633
+ case MINUS | BANG => in.nextToken(); true
634
+ case _ => false
635
+ }
636
+ tryLiteral(neg).map(forConst).getOrElse(tpt1)
637
+ }
638
+ else tpt1
639
+ }
640
+
641
+ val tpt2 : Tree =
642
+ if (in.token == EQUALS && ! mods.is(Flags .Param )) {
643
+ val res = optConstantTpe()
644
+ skipTo(COMMA , SEMI )
645
+ res
646
+ }
647
+ else tpt1
648
+
605
649
val mods1 = if (mods.is(Flags .Final )) mods else mods | Flags .Mutable
606
- ValDef (name, tpt1 , if (mods.is(Flags .Param )) EmptyTree else unimplementedExpr).withMods(mods1)
650
+ ValDef (name, tpt2 , if (mods.is(Flags .Param )) EmptyTree else unimplementedExpr).withMods(mods1)
607
651
}
608
652
609
653
def memberDecl (start : Offset , mods : Modifiers , parentToken : Int , parentTParams : List [TypeDef ]): List [Tree ] = in.token match {
@@ -881,6 +925,25 @@ object JavaParsers {
881
925
case _ => in.nextToken(); syntaxError(" illegal start of type declaration" , skipIt = true ); List (errorTypeTree)
882
926
}
883
927
928
+ def tryLiteral (negate : Boolean = false ): Option [Constant ] = {
929
+ val l = in.token match {
930
+ case TRUE => ! negate
931
+ case FALSE => negate
932
+ case CHARLIT => in.strVal.charAt(0 )
933
+ case INTLIT => in.intVal(negate).toInt
934
+ case LONGLIT => in.intVal(negate)
935
+ case FLOATLIT => in.floatVal(negate).toFloat
936
+ case DOUBLELIT => in.floatVal(negate)
937
+ case STRINGLIT => in.strVal
938
+ case _ => null
939
+ }
940
+ if (l == null ) None
941
+ else {
942
+ in.nextToken()
943
+ Some (Constant (l))
944
+ }
945
+ }
946
+
884
947
/** CompilationUnit ::= [package QualId semi] TopStatSeq
885
948
*/
886
949
def compilationUnit (): Tree = {
0 commit comments