langtools/src/share/classes/com/sun/tools/javac/parser/Scanner.java
changeset 7330 7c670eebe55c
parent 6716 71df48777dd1
child 8032 e1aa25ccdabb
equal deleted inserted replaced
7329:8a5601394af4 7330:7c670eebe55c
    64 
    64 
    65     /** Allow underscores in literals.
    65     /** Allow underscores in literals.
    66      */
    66      */
    67     private boolean allowUnderscoresInLiterals;
    67     private boolean allowUnderscoresInLiterals;
    68 
    68 
    69     /** Allow exotic identifiers.
       
    70      */
       
    71     private boolean allowExoticIdentifiers;
       
    72 
       
    73     /** The source language setting.
    69     /** The source language setting.
    74      */
    70      */
    75     private Source source;
    71     private Source source;
    76 
    72 
    77     /** The token's position, 0-based offset from beginning of text.
    73     /** The token's position, 0-based offset from beginning of text.
   141         keywords = fac.keywords;
   137         keywords = fac.keywords;
   142         source = fac.source;
   138         source = fac.source;
   143         allowBinaryLiterals = source.allowBinaryLiterals();
   139         allowBinaryLiterals = source.allowBinaryLiterals();
   144         allowHexFloats = source.allowHexFloats();
   140         allowHexFloats = source.allowHexFloats();
   145         allowUnderscoresInLiterals = source.allowBinaryLiterals();
   141         allowUnderscoresInLiterals = source.allowBinaryLiterals();
   146         allowExoticIdentifiers = source.allowExoticIdentifiers();  // for invokedynamic
       
   147     }
   142     }
   148 
   143 
   149     private static final boolean hexFloatsWork = hexFloatsWork();
   144     private static final boolean hexFloatsWork = hexFloatsWork();
   150     private static boolean hexFloatsWork() {
   145     private static boolean hexFloatsWork() {
   151         try {
   146         try {
   293         System.err.print(ch); System.out.flush();
   288         System.err.print(ch); System.out.flush();
   294     }
   289     }
   295 
   290 
   296     /** Read next character in character or string literal and copy into sbuf.
   291     /** Read next character in character or string literal and copy into sbuf.
   297      */
   292      */
   298     private void scanLitChar(boolean forBytecodeName) {
   293     private void scanLitChar() {
   299         if (ch == '\\') {
   294         if (ch == '\\') {
   300             if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
   295             if (buf[bp+1] == '\\' && unicodeConversionBp != bp) {
   301                 bp++;
   296                 bp++;
   302                 putChar('\\');
   297                 putChar('\\');
   303                 scanChar();
   298                 scanChar();
   333                     putChar('\''); scanChar(); break;
   328                     putChar('\''); scanChar(); break;
   334                 case '\"':
   329                 case '\"':
   335                     putChar('\"'); scanChar(); break;
   330                     putChar('\"'); scanChar(); break;
   336                 case '\\':
   331                 case '\\':
   337                     putChar('\\'); scanChar(); break;
   332                     putChar('\\'); scanChar(); break;
   338                 case '|': case ',': case '?': case '%':
       
   339                 case '^': case '_': case '{': case '}':
       
   340                 case '!': case '-': case '=':
       
   341                     if (forBytecodeName) {
       
   342                         // Accept escape sequences for dangerous bytecode chars.
       
   343                         // This is illegal in normal Java string or character literals.
       
   344                         // Note that the escape sequence itself is passed through.
       
   345                         putChar('\\'); putChar(ch); scanChar();
       
   346                     } else {
       
   347                         lexError(bp, "illegal.esc.char");
       
   348                     }
       
   349                     break;
       
   350                 default:
   333                 default:
   351                     lexError(bp, "illegal.esc.char");
   334                     lexError(bp, "illegal.esc.char");
   352                 }
   335                 }
   353             }
   336             }
   354         } else if (bp != buflen) {
   337         } else if (bp != buflen) {
   355             putChar(ch); scanChar();
   338             putChar(ch); scanChar();
   356         }
   339         }
   357     }
       
   358     private void scanLitChar() {
       
   359         scanLitChar(false);
       
   360     }
       
   361 
       
   362     /** Read next character in an exotic name #"foo"
       
   363      */
       
   364     private void scanBytecodeNameChar() {
       
   365         switch (ch) {
       
   366         // reject any "dangerous" char which is illegal somewhere in the JVM spec
       
   367         // cf. http://blogs.sun.com/jrose/entry/symbolic_freedom_in_the_vm
       
   368         case '/': case '.': case ';':  // illegal everywhere
       
   369         case '<': case '>':  // illegal in methods, dangerous in classes
       
   370         case '[':  // illegal in classes
       
   371             lexError(bp, "illegal.bytecode.ident.char", String.valueOf((int)ch));
       
   372             break;
       
   373         }
       
   374         scanLitChar(true);
       
   375     }
   340     }
   376 
   341 
   377     private void scanDigits(int digitRadix) {
   342     private void scanDigits(int digitRadix) {
   378         char saveCh;
   343         char saveCh;
   379         int savePos;
   344         int savePos;
   968                         scanChar();
   933                         scanChar();
   969                     } else {
   934                     } else {
   970                         lexError(pos, "unclosed.str.lit");
   935                         lexError(pos, "unclosed.str.lit");
   971                     }
   936                     }
   972                     return;
   937                     return;
   973                 case '#':
       
   974                     scanChar();
       
   975                     if (ch == '\"') {
       
   976                         if (!allowExoticIdentifiers) {
       
   977                             lexError("unsupported.exotic.id", source.name);
       
   978                             allowExoticIdentifiers = true;
       
   979                         }
       
   980                         scanChar();
       
   981                         if (ch == '\"')
       
   982                             lexError(pos, "empty.bytecode.ident");
       
   983                         while (ch != '\"' && ch != CR && ch != LF && bp < buflen) {
       
   984                             scanBytecodeNameChar();
       
   985                         }
       
   986                         if (ch == '\"') {
       
   987                             name = names.fromChars(sbuf, 0, sp);
       
   988                             token = IDENTIFIER;  // even if #"int" or #"do"
       
   989                             scanChar();
       
   990                         } else {
       
   991                             lexError(pos, "unclosed.bytecode.ident");
       
   992                         }
       
   993                     } else {
       
   994                         lexError("illegal.char", String.valueOf((int)'#'));
       
   995                     }
       
   996                     return;
       
   997                 default:
   938                 default:
   998                     if (isSpecial(ch)) {
   939                     if (isSpecial(ch)) {
   999                         scanOperator();
   940                         scanOperator();
  1000                     } else {
   941                     } else {
  1001                         boolean isJavaIdentifierStart;
   942                         boolean isJavaIdentifierStart;