private boolean isMagicComment ( ) { assert reader . ch == ' ' ; int parens = 0 ; boolean stringLit = false ; int lbp = reader . bp ; char lch = reader . buf [ ++ lbp ] ; if ( ! Character . isJavaIdentifierStart ( lch ) ) { // The first thing after the @ has to be the annotation identifier return false ; } while ( lbp < reader . buflen ) { lch = reader . buf [ ++ lbp ] ; // We are outside any annotation values if ( Character . isWhitespace ( lch ) && ! spacesincomments && parens == 0 ) { return false ; } else if ( lch == ' ' && parens == 0 ) { // At most one annotation per magic comment return false ; } else if ( lch == ' ' && ! stringLit ) { ++ parens ; } else if ( lch == ' ' && ! stringLit ) { -- parens ; } else if ( lch == ' ' ) { // TODO: handle more complicated string literals, // char literals, escape sequences, unicode, etc. stringLit = ! stringLit ; } else if ( lch == ' ' && ! stringLit && lbp + 1 < reader . buflen && reader . buf [ lbp + 1 ] == ' ' ) { // We reached the end of the comment, make sure no // parens are open return parens == 0 ; } else if ( ! Character . isJavaIdentifierPart ( lch ) && ! Character . isWhitespace ( lch ) && lch != ' ' && // separator in fully-qualified annotation name // TODO: this also allows /*@A...*/ which should not be recognized. ! spacesincomments && parens == 0 && ! stringLit ) { return false ; } // Do we need anything else for annotation values, e.g. String literals? } // came to end of file before '*/' return false ; }
with annotation values .