@@ -601,9 +601,53 @@ object JavaParsers {
601601
602602 def varDecl (mods : Modifiers , tpt : Tree , name : TermName ): ValDef = {
603603 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+
605649 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)
607651 }
608652
609653 def memberDecl (start : Offset , mods : Modifiers , parentToken : Int , parentTParams : List [TypeDef ]): List [Tree ] = in.token match {
@@ -881,6 +925,25 @@ object JavaParsers {
881925 case _ => in.nextToken(); syntaxError(" illegal start of type declaration" , skipIt = true ); List (errorTypeTree)
882926 }
883927
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+
884947 /** CompilationUnit ::= [package QualId semi] TopStatSeq
885948 */
886949 def compilationUnit (): Tree = {
0 commit comments