@@ -246,7 +246,7 @@ object JavaParsers {
246246
247247 def qualId (): RefTree = {
248248 var t : RefTree = atSpan(in.offset) { Ident (ident()) }
249- while (in.token == DOT ) {
249+ while (in.token == DOT && in.lookaheadToken == IDENTIFIER ) {
250250 in.nextToken()
251251 t = atSpan(t.span.start, in.offset) { Select (t, ident()) }
252252 }
@@ -346,20 +346,86 @@ object JavaParsers {
346346 /** Annotation ::= TypeName [`(` AnnotationArgument {`,` AnnotationArgument} `)`]
347347 */
348348 def annotation (): Option [Tree ] = {
349- val id = convertToTypeId(qualId())
350- // only parse annotations without arguments
351- if (in.token == LPAREN && in.lookaheadToken != RPAREN ) {
352- skipAhead()
353- accept(RPAREN )
354- None
355- }
356- else {
357- if (in.token == LPAREN ) {
349+ object LiteralT :
350+ def unapply (token : Token ) = Option (token match {
351+ case TRUE => true
352+ case FALSE => false
353+ case CHARLIT => in.name(0 )
354+ case INTLIT => in.intVal(false ).toInt
355+ case LONGLIT => in.intVal(false )
356+ case FLOATLIT => in.floatVal(false ).toFloat
357+ case DOUBLELIT => in.floatVal(false )
358+ case STRINGLIT => in.name.toString
359+ case _ => null
360+ }).map(Constant (_))
361+
362+ def classOrId (): Tree =
363+ val id = qualId()
364+ if in.lookaheadToken == CLASS then
358365 in.nextToken()
359- accept(RPAREN )
366+ accept(CLASS )
367+ TypeApply (
368+ Select (
369+ scalaDot(nme.Predef ),
370+ nme.classOf ),
371+ convertToTypeId(id) :: Nil
372+ )
373+ else id
374+
375+ def array (): Tree =
376+ accept(LBRACE )
377+ val buffer = ListBuffer [Tree ]()
378+ while (in.token != RBRACE ) {
379+ buffer += argValue()
380+ if (in.token == COMMA ) in.nextToken() // using this instead of repsep allows us to handle trailing commas
360381 }
361- Some (ensureApplied(Select (New (id), nme.CONSTRUCTOR )))
362- }
382+ val ok = ! buffer.contains(EmptyTree )
383+ in.token match {
384+ case RBRACE if ok =>
385+ accept(RBRACE )
386+ Apply (scalaDot(nme.Array ), buffer.toList)
387+ case _ =>
388+ skipTo(RBRACE )
389+ EmptyTree
390+ }
391+
392+ def argValue (): Tree =
393+ in.token match {
394+ case LiteralT (c) =>
395+ val tree = atSpan(in.offset)(Literal (c))
396+ in.nextToken()
397+ tree
398+ case AT =>
399+ in.nextToken()
400+ annotation().get
401+ case IDENTIFIER => classOrId()
402+ case LBRACE => array()
403+ case _ => EmptyTree
404+ }
405+
406+ def annArg (): Tree =
407+ if (in.token == IDENTIFIER && in.lookaheadToken == EQUALS )
408+ val name = ident()
409+ accept(EQUALS )
410+ val argv = argValue()
411+ NamedArg (name, argv)
412+
413+ else
414+ NamedArg (nme.value, argValue())
415+
416+
417+ val id = convertToTypeId(qualId())
418+ val args = if in.token == LPAREN then
419+ in.nextToken()
420+ val args = repsep(annArg, COMMA )
421+ accept(RPAREN )
422+ args
423+ else Nil
424+
425+ Some (Apply (
426+ Select (New (id), nme.CONSTRUCTOR ),
427+ args
428+ ))
363429 }
364430
365431 def modifiers (inInterface : Boolean ): Modifiers = {
0 commit comments