Mon, 24 Oct 2011 13:00:20 +0100
7096014: Javac tokens should retain state
Summary: Refactor javac tokens from enum constants to stateful instances (to keep track of position, comments, etc.)
Reviewed-by: jjg
1.1 --- a/src/share/classes/com/sun/tools/apt/main/AptJavaCompiler.java Fri Oct 21 14:14:29 2011 -0700 1.2 +++ b/src/share/classes/com/sun/tools/apt/main/AptJavaCompiler.java Mon Oct 24 13:00:20 2011 +0100 1.3 @@ -42,7 +42,6 @@ 1.4 import com.sun.tools.apt.comp.*; 1.5 import com.sun.tools.apt.util.Bark; 1.6 import com.sun.mirror.apt.AnnotationProcessorFactory; 1.7 -import com.sun.tools.javac.parser.DocCommentScanner; 1.8 1.9 /** 1.10 * <p><b>This is NOT part of any supported API.
2.1 --- a/src/share/classes/com/sun/tools/javac/parser/DocCommentScanner.java Fri Oct 21 14:14:29 2011 -0700 2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 2.3 @@ -1,420 +0,0 @@ 2.4 -/* 2.5 - * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 2.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 2.7 - * 2.8 - * This code is free software; you can redistribute it and/or modify it 2.9 - * under the terms of the GNU General Public License version 2 only, as 2.10 - * published by the Free Software Foundation. Oracle designates this 2.11 - * particular file as subject to the "Classpath" exception as provided 2.12 - * by Oracle in the LICENSE file that accompanied this code. 2.13 - * 2.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 2.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 2.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 2.17 - * version 2 for more details (a copy is included in the LICENSE file that 2.18 - * accompanied this code). 2.19 - * 2.20 - * You should have received a copy of the GNU General Public License version 2.21 - * 2 along with this work; if not, write to the Free Software Foundation, 2.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2.23 - * 2.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2.25 - * or visit www.oracle.com if you need additional information or have any 2.26 - * questions. 2.27 - */ 2.28 - 2.29 -package com.sun.tools.javac.parser; 2.30 - 2.31 -import java.nio.*; 2.32 - 2.33 -import com.sun.tools.javac.util.*; 2.34 -import static com.sun.tools.javac.util.LayoutCharacters.*; 2.35 - 2.36 -/** An extension to the base lexical analyzer that captures 2.37 - * and processes the contents of doc comments. It does so by 2.38 - * translating Unicode escape sequences and by stripping the 2.39 - * leading whitespace and starts from each line of the comment. 2.40 - * 2.41 - * <p><b>This is NOT part of any supported API. 2.42 - * If you write code that depends on this, you do so at your own risk. 2.43 - * This code and its internal interfaces are subject to change or 2.44 - * deletion without notice.</b> 2.45 - */ 2.46 -public class DocCommentScanner extends Scanner { 2.47 - 2.48 - /** Create a scanner from the input buffer. buffer must implement 2.49 - * array() and compact(), and remaining() must be less than limit(). 2.50 - */ 2.51 - protected DocCommentScanner(ScannerFactory fac, CharBuffer buffer) { 2.52 - super(fac, buffer); 2.53 - } 2.54 - 2.55 - /** Create a scanner from the input array. The array must have at 2.56 - * least a single character of extra space. 2.57 - */ 2.58 - protected DocCommentScanner(ScannerFactory fac, char[] input, int inputLength) { 2.59 - super(fac, input, inputLength); 2.60 - } 2.61 - 2.62 - /** Starting position of the comment in original source 2.63 - */ 2.64 - private int pos; 2.65 - 2.66 - /** The comment input buffer, index of next chacter to be read, 2.67 - * index of one past last character in buffer. 2.68 - */ 2.69 - private char[] buf; 2.70 - private int bp; 2.71 - private int buflen; 2.72 - 2.73 - /** The current character. 2.74 - */ 2.75 - private char ch; 2.76 - 2.77 - /** The column number position of the current character. 2.78 - */ 2.79 - private int col; 2.80 - 2.81 - /** The buffer index of the last converted Unicode character 2.82 - */ 2.83 - private int unicodeConversionBp = 0; 2.84 - 2.85 - /** 2.86 - * Buffer for doc comment. 2.87 - */ 2.88 - private char[] docCommentBuffer = new char[1024]; 2.89 - 2.90 - /** 2.91 - * Number of characters in doc comment buffer. 2.92 - */ 2.93 - private int docCommentCount; 2.94 - 2.95 - /** 2.96 - * Translated and stripped contents of doc comment 2.97 - */ 2.98 - private String docComment = null; 2.99 - 2.100 - 2.101 - /** Unconditionally expand the comment buffer. 2.102 - */ 2.103 - private void expandCommentBuffer() { 2.104 - char[] newBuffer = new char[docCommentBuffer.length * 2]; 2.105 - System.arraycopy(docCommentBuffer, 0, newBuffer, 2.106 - 0, docCommentBuffer.length); 2.107 - docCommentBuffer = newBuffer; 2.108 - } 2.109 - 2.110 - /** Convert an ASCII digit from its base (8, 10, or 16) 2.111 - * to its value. 2.112 - */ 2.113 - private int digit(int base) { 2.114 - char c = ch; 2.115 - int result = Character.digit(c, base); 2.116 - if (result >= 0 && c > 0x7f) { 2.117 - ch = "0123456789abcdef".charAt(result); 2.118 - } 2.119 - return result; 2.120 - } 2.121 - 2.122 - /** Convert Unicode escape; bp points to initial '\' character 2.123 - * (Spec 3.3). 2.124 - */ 2.125 - private void convertUnicode() { 2.126 - if (ch == '\\' && unicodeConversionBp != bp) { 2.127 - bp++; ch = buf[bp]; col++; 2.128 - if (ch == 'u') { 2.129 - do { 2.130 - bp++; ch = buf[bp]; col++; 2.131 - } while (ch == 'u'); 2.132 - int limit = bp + 3; 2.133 - if (limit < buflen) { 2.134 - int d = digit(16); 2.135 - int code = d; 2.136 - while (bp < limit && d >= 0) { 2.137 - bp++; ch = buf[bp]; col++; 2.138 - d = digit(16); 2.139 - code = (code << 4) + d; 2.140 - } 2.141 - if (d >= 0) { 2.142 - ch = (char)code; 2.143 - unicodeConversionBp = bp; 2.144 - return; 2.145 - } 2.146 - } 2.147 - // "illegal.Unicode.esc", reported by base scanner 2.148 - } else { 2.149 - bp--; 2.150 - ch = '\\'; 2.151 - col--; 2.152 - } 2.153 - } 2.154 - } 2.155 - 2.156 - 2.157 - /** Read next character. 2.158 - */ 2.159 - private void scanChar() { 2.160 - bp++; 2.161 - ch = buf[bp]; 2.162 - switch (ch) { 2.163 - case '\r': // return 2.164 - col = 0; 2.165 - break; 2.166 - case '\n': // newline 2.167 - if (bp == 0 || buf[bp-1] != '\r') { 2.168 - col = 0; 2.169 - } 2.170 - break; 2.171 - case '\t': // tab 2.172 - col = (col / TabInc * TabInc) + TabInc; 2.173 - break; 2.174 - case '\\': // possible Unicode 2.175 - col++; 2.176 - convertUnicode(); 2.177 - break; 2.178 - default: 2.179 - col++; 2.180 - break; 2.181 - } 2.182 - } 2.183 - 2.184 - /** 2.185 - * Read next character in doc comment, skipping over double '\' characters. 2.186 - * If a double '\' is skipped, put in the buffer and update buffer count. 2.187 - */ 2.188 - private void scanDocCommentChar() { 2.189 - scanChar(); 2.190 - if (ch == '\\') { 2.191 - if (buf[bp+1] == '\\' && unicodeConversionBp != bp) { 2.192 - if (docCommentCount == docCommentBuffer.length) 2.193 - expandCommentBuffer(); 2.194 - docCommentBuffer[docCommentCount++] = ch; 2.195 - bp++; col++; 2.196 - } else { 2.197 - convertUnicode(); 2.198 - } 2.199 - } 2.200 - } 2.201 - 2.202 - /* Reset doc comment before reading each new token 2.203 - */ 2.204 - public void nextToken() { 2.205 - docComment = null; 2.206 - super.nextToken(); 2.207 - } 2.208 - 2.209 - /** 2.210 - * Returns the documentation string of the current token. 2.211 - */ 2.212 - public String docComment() { 2.213 - return docComment; 2.214 - } 2.215 - 2.216 - /** 2.217 - * Process a doc comment and make the string content available. 2.218 - * Strips leading whitespace and stars. 2.219 - */ 2.220 - @SuppressWarnings("fallthrough") 2.221 - protected void processComment(CommentStyle style) { 2.222 - if (style != CommentStyle.JAVADOC) { 2.223 - return; 2.224 - } 2.225 - 2.226 - pos = pos(); 2.227 - buf = getRawCharacters(pos, endPos()); 2.228 - buflen = buf.length; 2.229 - bp = 0; 2.230 - col = 0; 2.231 - 2.232 - docCommentCount = 0; 2.233 - 2.234 - boolean firstLine = true; 2.235 - 2.236 - // Skip over first slash 2.237 - scanDocCommentChar(); 2.238 - // Skip over first star 2.239 - scanDocCommentChar(); 2.240 - 2.241 - // consume any number of stars 2.242 - while (bp < buflen && ch == '*') { 2.243 - scanDocCommentChar(); 2.244 - } 2.245 - // is the comment in the form /**/, /***/, /****/, etc. ? 2.246 - if (bp < buflen && ch == '/') { 2.247 - docComment = ""; 2.248 - return; 2.249 - } 2.250 - 2.251 - // skip a newline on the first line of the comment. 2.252 - if (bp < buflen) { 2.253 - if (ch == LF) { 2.254 - scanDocCommentChar(); 2.255 - firstLine = false; 2.256 - } else if (ch == CR) { 2.257 - scanDocCommentChar(); 2.258 - if (ch == LF) { 2.259 - scanDocCommentChar(); 2.260 - firstLine = false; 2.261 - } 2.262 - } 2.263 - } 2.264 - 2.265 - outerLoop: 2.266 - 2.267 - // The outerLoop processes the doc comment, looping once 2.268 - // for each line. For each line, it first strips off 2.269 - // whitespace, then it consumes any stars, then it 2.270 - // puts the rest of the line into our buffer. 2.271 - while (bp < buflen) { 2.272 - 2.273 - // The wsLoop consumes whitespace from the beginning 2.274 - // of each line. 2.275 - wsLoop: 2.276 - 2.277 - while (bp < buflen) { 2.278 - switch(ch) { 2.279 - case ' ': 2.280 - scanDocCommentChar(); 2.281 - break; 2.282 - case '\t': 2.283 - col = ((col - 1) / TabInc * TabInc) + TabInc; 2.284 - scanDocCommentChar(); 2.285 - break; 2.286 - case FF: 2.287 - col = 0; 2.288 - scanDocCommentChar(); 2.289 - break; 2.290 -// Treat newline at beginning of line (blank line, no star) 2.291 -// as comment text. Old Javadoc compatibility requires this. 2.292 -/*---------------------------------* 2.293 - case CR: // (Spec 3.4) 2.294 - scanDocCommentChar(); 2.295 - if (ch == LF) { 2.296 - col = 0; 2.297 - scanDocCommentChar(); 2.298 - } 2.299 - break; 2.300 - case LF: // (Spec 3.4) 2.301 - scanDocCommentChar(); 2.302 - break; 2.303 -*---------------------------------*/ 2.304 - default: 2.305 - // we've seen something that isn't whitespace; 2.306 - // jump out. 2.307 - break wsLoop; 2.308 - } 2.309 - } 2.310 - 2.311 - // Are there stars here? If so, consume them all 2.312 - // and check for the end of comment. 2.313 - if (ch == '*') { 2.314 - // skip all of the stars 2.315 - do { 2.316 - scanDocCommentChar(); 2.317 - } while (ch == '*'); 2.318 - 2.319 - // check for the closing slash. 2.320 - if (ch == '/') { 2.321 - // We're done with the doc comment 2.322 - // scanChar() and breakout. 2.323 - break outerLoop; 2.324 - } 2.325 - } else if (! firstLine) { 2.326 - //The current line does not begin with a '*' so we will indent it. 2.327 - for (int i = 1; i < col; i++) { 2.328 - if (docCommentCount == docCommentBuffer.length) 2.329 - expandCommentBuffer(); 2.330 - docCommentBuffer[docCommentCount++] = ' '; 2.331 - } 2.332 - } 2.333 - 2.334 - // The textLoop processes the rest of the characters 2.335 - // on the line, adding them to our buffer. 2.336 - textLoop: 2.337 - while (bp < buflen) { 2.338 - switch (ch) { 2.339 - case '*': 2.340 - // Is this just a star? Or is this the 2.341 - // end of a comment? 2.342 - scanDocCommentChar(); 2.343 - if (ch == '/') { 2.344 - // This is the end of the comment, 2.345 - // set ch and return our buffer. 2.346 - break outerLoop; 2.347 - } 2.348 - // This is just an ordinary star. Add it to 2.349 - // the buffer. 2.350 - if (docCommentCount == docCommentBuffer.length) 2.351 - expandCommentBuffer(); 2.352 - docCommentBuffer[docCommentCount++] = '*'; 2.353 - break; 2.354 - case ' ': 2.355 - case '\t': 2.356 - if (docCommentCount == docCommentBuffer.length) 2.357 - expandCommentBuffer(); 2.358 - docCommentBuffer[docCommentCount++] = ch; 2.359 - scanDocCommentChar(); 2.360 - break; 2.361 - case FF: 2.362 - scanDocCommentChar(); 2.363 - break textLoop; // treat as end of line 2.364 - case CR: // (Spec 3.4) 2.365 - scanDocCommentChar(); 2.366 - if (ch != LF) { 2.367 - // Canonicalize CR-only line terminator to LF 2.368 - if (docCommentCount == docCommentBuffer.length) 2.369 - expandCommentBuffer(); 2.370 - docCommentBuffer[docCommentCount++] = (char)LF; 2.371 - break textLoop; 2.372 - } 2.373 - /* fall through to LF case */ 2.374 - case LF: // (Spec 3.4) 2.375 - // We've seen a newline. Add it to our 2.376 - // buffer and break out of this loop, 2.377 - // starting fresh on a new line. 2.378 - if (docCommentCount == docCommentBuffer.length) 2.379 - expandCommentBuffer(); 2.380 - docCommentBuffer[docCommentCount++] = ch; 2.381 - scanDocCommentChar(); 2.382 - break textLoop; 2.383 - default: 2.384 - // Add the character to our buffer. 2.385 - if (docCommentCount == docCommentBuffer.length) 2.386 - expandCommentBuffer(); 2.387 - docCommentBuffer[docCommentCount++] = ch; 2.388 - scanDocCommentChar(); 2.389 - } 2.390 - } // end textLoop 2.391 - firstLine = false; 2.392 - } // end outerLoop 2.393 - 2.394 - if (docCommentCount > 0) { 2.395 - int i = docCommentCount - 1; 2.396 - trailLoop: 2.397 - while (i > -1) { 2.398 - switch (docCommentBuffer[i]) { 2.399 - case '*': 2.400 - i--; 2.401 - break; 2.402 - default: 2.403 - break trailLoop; 2.404 - } 2.405 - } 2.406 - docCommentCount = i + 1; 2.407 - 2.408 - // Store the text of the doc comment 2.409 - docComment = new String(docCommentBuffer, 0 , docCommentCount); 2.410 - } else { 2.411 - docComment = ""; 2.412 - } 2.413 - } 2.414 - 2.415 - /** Build a map for translating between line numbers and 2.416 - * positions in the input. 2.417 - * 2.418 - * @return a LineMap */ 2.419 - public Position.LineMap getLineMap() { 2.420 - char[] buf = getRawCharacters(); 2.421 - return Position.makeLineMap(buf, buf.length, true); 2.422 - } 2.423 -}
3.1 --- a/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java Fri Oct 21 14:14:29 2011 -0700 3.2 +++ b/src/share/classes/com/sun/tools/javac/parser/EndPosParser.java Mon Oct 24 13:00:20 2011 +0100 3.3 @@ -67,14 +67,14 @@ 3.4 /** {@inheritDoc} */ 3.5 @Override 3.6 protected <T extends JCTree> T to(T t) { 3.7 - storeEnd(t, S.endPos()); 3.8 + storeEnd(t, token.endPos); 3.9 return t; 3.10 } 3.11 3.12 /** {@inheritDoc} */ 3.13 @Override 3.14 protected <T extends JCTree> T toP(T t) { 3.15 - storeEnd(t, S.prevEndPos()); 3.16 + storeEnd(t, S.prevToken().endPos); 3.17 return t; 3.18 } 3.19 3.20 @@ -88,7 +88,7 @@ 3.21 /** {@inheritDoc} */ 3.22 @Override 3.23 JCExpression parExpression() { 3.24 - int pos = S.pos(); 3.25 + int pos = token.pos; 3.26 JCExpression t = super.parExpression(); 3.27 return toP(F.at(pos).Parens(t)); 3.28 }
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 4.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavaTokenizer.java Mon Oct 24 13:00:20 2011 +0100 4.3 @@ -0,0 +1,896 @@ 4.4 +/* 4.5 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 4.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.7 + * 4.8 + * This code is free software; you can redistribute it and/or modify it 4.9 + * under the terms of the GNU General Public License version 2 only, as 4.10 + * published by the Free Software Foundation. Oracle designates this 4.11 + * particular file as subject to the "Classpath" exception as provided 4.12 + * by Oracle in the LICENSE file that accompanied this code. 4.13 + * 4.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 4.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 4.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 4.17 + * version 2 for more details (a copy is included in the LICENSE file that 4.18 + * accompanied this code). 4.19 + * 4.20 + * You should have received a copy of the GNU General Public License version 4.21 + * 2 along with this work; if not, write to the Free Software Foundation, 4.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 4.23 + * 4.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 4.25 + * or visit www.oracle.com if you need additional information or have any 4.26 + * questions. 4.27 + */ 4.28 + 4.29 +package com.sun.tools.javac.parser; 4.30 + 4.31 +import java.nio.CharBuffer; 4.32 +import com.sun.tools.javac.code.Source; 4.33 +import com.sun.tools.javac.util.*; 4.34 + 4.35 + 4.36 +import static com.sun.tools.javac.parser.Tokens.*; 4.37 +import static com.sun.tools.javac.util.LayoutCharacters.*; 4.38 + 4.39 +/** The lexical analyzer maps an input stream consisting of 4.40 + * ASCII characters and Unicode escapes into a token sequence. 4.41 + * 4.42 + * <p><b>This is NOT part of any supported API. 4.43 + * If you write code that depends on this, you do so at your own risk. 4.44 + * This code and its internal interfaces are subject to change or 4.45 + * deletion without notice.</b> 4.46 + */ 4.47 +public class JavaTokenizer { 4.48 + 4.49 + private static boolean scannerDebug = false; 4.50 + 4.51 + /** Allow hex floating-point literals. 4.52 + */ 4.53 + private boolean allowHexFloats; 4.54 + 4.55 + /** Allow binary literals. 4.56 + */ 4.57 + private boolean allowBinaryLiterals; 4.58 + 4.59 + /** Allow underscores in literals. 4.60 + */ 4.61 + private boolean allowUnderscoresInLiterals; 4.62 + 4.63 + /** The source language setting. 4.64 + */ 4.65 + private Source source; 4.66 + 4.67 + /** The log to be used for error reporting. 4.68 + */ 4.69 + private final Log log; 4.70 + 4.71 + /** The name table. */ 4.72 + private final Names names; 4.73 + 4.74 + /** The token factory. */ 4.75 + private final Tokens tokens; 4.76 + 4.77 + /** The token kind, set by nextToken(). 4.78 + */ 4.79 + protected TokenKind tk; 4.80 + 4.81 + /** The token's radix, set by nextToken(). 4.82 + */ 4.83 + protected int radix; 4.84 + 4.85 + /** The token's name, set by nextToken(). 4.86 + */ 4.87 + protected Name name; 4.88 + 4.89 + /** The position where a lexical error occurred; 4.90 + */ 4.91 + protected int errPos = Position.NOPOS; 4.92 + 4.93 + /** Has a @deprecated been encountered in last doc comment? 4.94 + * this needs to be reset by client. 4.95 + */ 4.96 + protected boolean deprecatedFlag = false; 4.97 + 4.98 + /** A character buffer for saved chars. 4.99 + */ 4.100 + protected char[] sbuf = new char[128]; 4.101 + protected int sp; 4.102 + 4.103 + protected UnicodeReader reader; 4.104 + 4.105 + private static final boolean hexFloatsWork = hexFloatsWork(); 4.106 + private static boolean hexFloatsWork() { 4.107 + try { 4.108 + Float.valueOf("0x1.0p1"); 4.109 + return true; 4.110 + } catch (NumberFormatException ex) { 4.111 + return false; 4.112 + } 4.113 + } 4.114 + 4.115 + /** 4.116 + * Create a scanner from the input array. This method might 4.117 + * modify the array. To avoid copying the input array, ensure 4.118 + * that {@code inputLength < input.length} or 4.119 + * {@code input[input.length -1]} is a white space character. 4.120 + * 4.121 + * @param fac the factory which created this Scanner 4.122 + * @param input the input, might be modified 4.123 + * @param inputLength the size of the input. 4.124 + * Must be positive and less than or equal to input.length. 4.125 + */ 4.126 + protected JavaTokenizer(ScannerFactory fac, CharBuffer buf) { 4.127 + this(fac, new UnicodeReader(fac, buf)); 4.128 + } 4.129 + 4.130 + protected JavaTokenizer(ScannerFactory fac, char[] buf, int inputLength) { 4.131 + this(fac, new UnicodeReader(fac, buf, inputLength)); 4.132 + } 4.133 + 4.134 + protected JavaTokenizer(ScannerFactory fac, UnicodeReader reader) { 4.135 + log = fac.log; 4.136 + names = fac.names; 4.137 + tokens = fac.tokens; 4.138 + source = fac.source; 4.139 + this.reader = reader; 4.140 + allowBinaryLiterals = source.allowBinaryLiterals(); 4.141 + allowHexFloats = source.allowHexFloats(); 4.142 + allowUnderscoresInLiterals = source.allowUnderscoresInLiterals(); 4.143 + } 4.144 + 4.145 + /** Report an error at the given position using the provided arguments. 4.146 + */ 4.147 + protected void lexError(int pos, String key, Object... args) { 4.148 + log.error(pos, key, args); 4.149 + tk = TokenKind.ERROR; 4.150 + errPos = pos; 4.151 + } 4.152 + 4.153 + /** Read next character in comment, skipping over double '\' characters. 4.154 + */ 4.155 + protected void scanCommentChar() { 4.156 + reader.scanChar(); 4.157 + if (reader.ch == '\\') { 4.158 + if (reader.peekChar() == '\\' && !reader.isUnicode()) { 4.159 + reader.skipChar(); 4.160 + } else { 4.161 + reader.convertUnicode(); 4.162 + } 4.163 + } 4.164 + } 4.165 + 4.166 + /** Append a character to sbuf. 4.167 + */ 4.168 + private void putChar(char ch) { 4.169 + if (sp == sbuf.length) { 4.170 + char[] newsbuf = new char[sbuf.length * 2]; 4.171 + System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); 4.172 + sbuf = newsbuf; 4.173 + } 4.174 + sbuf[sp++] = ch; 4.175 + } 4.176 + 4.177 + /** Read next character in character or string literal and copy into sbuf. 4.178 + */ 4.179 + private void scanLitChar(int pos) { 4.180 + if (reader.ch == '\\') { 4.181 + if (reader.peekChar() == '\\' && !reader.isUnicode()) { 4.182 + reader.skipChar(); 4.183 + putChar('\\'); 4.184 + reader.scanChar(); 4.185 + } else { 4.186 + reader.scanChar(); 4.187 + switch (reader.ch) { 4.188 + case '0': case '1': case '2': case '3': 4.189 + case '4': case '5': case '6': case '7': 4.190 + char leadch = reader.ch; 4.191 + int oct = reader.digit(pos, 8); 4.192 + reader.scanChar(); 4.193 + if ('0' <= reader.ch && reader.ch <= '7') { 4.194 + oct = oct * 8 + reader.digit(pos, 8); 4.195 + reader.scanChar(); 4.196 + if (leadch <= '3' && '0' <= reader.ch && reader.ch <= '7') { 4.197 + oct = oct * 8 + reader.digit(pos, 8); 4.198 + reader.scanChar(); 4.199 + } 4.200 + } 4.201 + putChar((char)oct); 4.202 + break; 4.203 + case 'b': 4.204 + putChar('\b'); reader.scanChar(); break; 4.205 + case 't': 4.206 + putChar('\t'); reader.scanChar(); break; 4.207 + case 'n': 4.208 + putChar('\n'); reader.scanChar(); break; 4.209 + case 'f': 4.210 + putChar('\f'); reader.scanChar(); break; 4.211 + case 'r': 4.212 + putChar('\r'); reader.scanChar(); break; 4.213 + case '\'': 4.214 + putChar('\''); reader.scanChar(); break; 4.215 + case '\"': 4.216 + putChar('\"'); reader.scanChar(); break; 4.217 + case '\\': 4.218 + putChar('\\'); reader.scanChar(); break; 4.219 + default: 4.220 + lexError(reader.bp, "illegal.esc.char"); 4.221 + } 4.222 + } 4.223 + } else if (reader.bp != reader.buflen) { 4.224 + putChar(reader.ch); reader.scanChar(); 4.225 + } 4.226 + } 4.227 + 4.228 + private void scanDigits(int pos, int digitRadix) { 4.229 + char saveCh; 4.230 + int savePos; 4.231 + do { 4.232 + if (reader.ch != '_') { 4.233 + putChar(reader.ch); 4.234 + } else { 4.235 + if (!allowUnderscoresInLiterals) { 4.236 + lexError(pos, "unsupported.underscore.lit", source.name); 4.237 + allowUnderscoresInLiterals = true; 4.238 + } 4.239 + } 4.240 + saveCh = reader.ch; 4.241 + savePos = reader.bp; 4.242 + reader.scanChar(); 4.243 + } while (reader.digit(pos, digitRadix) >= 0 || reader.ch == '_'); 4.244 + if (saveCh == '_') 4.245 + lexError(savePos, "illegal.underscore"); 4.246 + } 4.247 + 4.248 + /** Read fractional part of hexadecimal floating point number. 4.249 + */ 4.250 + private void scanHexExponentAndSuffix(int pos) { 4.251 + if (reader.ch == 'p' || reader.ch == 'P') { 4.252 + putChar(reader.ch); 4.253 + reader.scanChar(); 4.254 + skipIllegalUnderscores(); 4.255 + if (reader.ch == '+' || reader.ch == '-') { 4.256 + putChar(reader.ch); 4.257 + reader.scanChar(); 4.258 + } 4.259 + skipIllegalUnderscores(); 4.260 + if ('0' <= reader.ch && reader.ch <= '9') { 4.261 + scanDigits(pos, 10); 4.262 + if (!allowHexFloats) { 4.263 + lexError(pos, "unsupported.fp.lit", source.name); 4.264 + allowHexFloats = true; 4.265 + } 4.266 + else if (!hexFloatsWork) 4.267 + lexError(pos, "unsupported.cross.fp.lit"); 4.268 + } else 4.269 + lexError(pos, "malformed.fp.lit"); 4.270 + } else { 4.271 + lexError(pos, "malformed.fp.lit"); 4.272 + } 4.273 + if (reader.ch == 'f' || reader.ch == 'F') { 4.274 + putChar(reader.ch); 4.275 + reader.scanChar(); 4.276 + tk = TokenKind.FLOATLITERAL; 4.277 + radix = 16; 4.278 + } else { 4.279 + if (reader.ch == 'd' || reader.ch == 'D') { 4.280 + putChar(reader.ch); 4.281 + reader.scanChar(); 4.282 + } 4.283 + tk = TokenKind.DOUBLELITERAL; 4.284 + radix = 16; 4.285 + } 4.286 + } 4.287 + 4.288 + /** Read fractional part of floating point number. 4.289 + */ 4.290 + private void scanFraction(int pos) { 4.291 + skipIllegalUnderscores(); 4.292 + if ('0' <= reader.ch && reader.ch <= '9') { 4.293 + scanDigits(pos, 10); 4.294 + } 4.295 + int sp1 = sp; 4.296 + if (reader.ch == 'e' || reader.ch == 'E') { 4.297 + putChar(reader.ch); 4.298 + reader.scanChar(); 4.299 + skipIllegalUnderscores(); 4.300 + if (reader.ch == '+' || reader.ch == '-') { 4.301 + putChar(reader.ch); 4.302 + reader.scanChar(); 4.303 + } 4.304 + skipIllegalUnderscores(); 4.305 + if ('0' <= reader.ch && reader.ch <= '9') { 4.306 + scanDigits(pos, 10); 4.307 + return; 4.308 + } 4.309 + lexError(pos, "malformed.fp.lit"); 4.310 + sp = sp1; 4.311 + } 4.312 + } 4.313 + 4.314 + /** Read fractional part and 'd' or 'f' suffix of floating point number. 4.315 + */ 4.316 + private void scanFractionAndSuffix(int pos) { 4.317 + radix = 10; 4.318 + scanFraction(pos); 4.319 + if (reader.ch == 'f' || reader.ch == 'F') { 4.320 + putChar(reader.ch); 4.321 + reader.scanChar(); 4.322 + tk = TokenKind.FLOATLITERAL; 4.323 + } else { 4.324 + if (reader.ch == 'd' || reader.ch == 'D') { 4.325 + putChar(reader.ch); 4.326 + reader.scanChar(); 4.327 + } 4.328 + tk = TokenKind.DOUBLELITERAL; 4.329 + } 4.330 + } 4.331 + 4.332 + /** Read fractional part and 'd' or 'f' suffix of floating point number. 4.333 + */ 4.334 + private void scanHexFractionAndSuffix(int pos, boolean seendigit) { 4.335 + radix = 16; 4.336 + Assert.check(reader.ch == '.'); 4.337 + putChar(reader.ch); 4.338 + reader.scanChar(); 4.339 + skipIllegalUnderscores(); 4.340 + if (reader.digit(pos, 16) >= 0) { 4.341 + seendigit = true; 4.342 + scanDigits(pos, 16); 4.343 + } 4.344 + if (!seendigit) 4.345 + lexError(pos, "invalid.hex.number"); 4.346 + else 4.347 + scanHexExponentAndSuffix(pos); 4.348 + } 4.349 + 4.350 + private void skipIllegalUnderscores() { 4.351 + if (reader.ch == '_') { 4.352 + lexError(reader.bp, "illegal.underscore"); 4.353 + while (reader.ch == '_') 4.354 + reader.scanChar(); 4.355 + } 4.356 + } 4.357 + 4.358 + /** Read a number. 4.359 + * @param radix The radix of the number; one of 2, j8, 10, 16. 4.360 + */ 4.361 + private void scanNumber(int pos, int radix) { 4.362 + // for octal, allow base-10 digit in case it's a float literal 4.363 + this.radix = radix; 4.364 + int digitRadix = (radix == 8 ? 10 : radix); 4.365 + boolean seendigit = false; 4.366 + if (reader.digit(pos, digitRadix) >= 0) { 4.367 + seendigit = true; 4.368 + scanDigits(pos, digitRadix); 4.369 + } 4.370 + if (radix == 16 && reader.ch == '.') { 4.371 + scanHexFractionAndSuffix(pos, seendigit); 4.372 + } else if (seendigit && radix == 16 && (reader.ch == 'p' || reader.ch == 'P')) { 4.373 + scanHexExponentAndSuffix(pos); 4.374 + } else if (digitRadix == 10 && reader.ch == '.') { 4.375 + putChar(reader.ch); 4.376 + reader.scanChar(); 4.377 + scanFractionAndSuffix(pos); 4.378 + } else if (digitRadix == 10 && 4.379 + (reader.ch == 'e' || reader.ch == 'E' || 4.380 + reader.ch == 'f' || reader.ch == 'F' || 4.381 + reader.ch == 'd' || reader.ch == 'D')) { 4.382 + scanFractionAndSuffix(pos); 4.383 + } else { 4.384 + if (reader.ch == 'l' || reader.ch == 'L') { 4.385 + reader.scanChar(); 4.386 + tk = TokenKind.LONGLITERAL; 4.387 + } else { 4.388 + tk = TokenKind.INTLITERAL; 4.389 + } 4.390 + } 4.391 + } 4.392 + 4.393 + /** Read an identifier. 4.394 + */ 4.395 + private void scanIdent() { 4.396 + boolean isJavaIdentifierPart; 4.397 + char high; 4.398 + do { 4.399 + if (sp == sbuf.length) putChar(reader.ch); else sbuf[sp++] = reader.ch; 4.400 + // optimization, was: putChar(reader.ch); 4.401 + 4.402 + reader.scanChar(); 4.403 + switch (reader.ch) { 4.404 + case 'A': case 'B': case 'C': case 'D': case 'E': 4.405 + case 'F': case 'G': case 'H': case 'I': case 'J': 4.406 + case 'K': case 'L': case 'M': case 'N': case 'O': 4.407 + case 'P': case 'Q': case 'R': case 'S': case 'T': 4.408 + case 'U': case 'V': case 'W': case 'X': case 'Y': 4.409 + case 'Z': 4.410 + case 'a': case 'b': case 'c': case 'd': case 'e': 4.411 + case 'f': case 'g': case 'h': case 'i': case 'j': 4.412 + case 'k': case 'l': case 'm': case 'n': case 'o': 4.413 + case 'p': case 'q': case 'r': case 's': case 't': 4.414 + case 'u': case 'v': case 'w': case 'x': case 'y': 4.415 + case 'z': 4.416 + case '$': case '_': 4.417 + case '0': case '1': case '2': case '3': case '4': 4.418 + case '5': case '6': case '7': case '8': case '9': 4.419 + case '\u0000': case '\u0001': case '\u0002': case '\u0003': 4.420 + case '\u0004': case '\u0005': case '\u0006': case '\u0007': 4.421 + case '\u0008': case '\u000E': case '\u000F': case '\u0010': 4.422 + case '\u0011': case '\u0012': case '\u0013': case '\u0014': 4.423 + case '\u0015': case '\u0016': case '\u0017': 4.424 + case '\u0018': case '\u0019': case '\u001B': 4.425 + case '\u007F': 4.426 + break; 4.427 + case '\u001A': // EOI is also a legal identifier part 4.428 + if (reader.bp >= reader.buflen) { 4.429 + name = names.fromChars(sbuf, 0, sp); 4.430 + tk = tokens.lookupKind(name); 4.431 + return; 4.432 + } 4.433 + break; 4.434 + default: 4.435 + if (reader.ch < '\u0080') { 4.436 + // all ASCII range chars already handled, above 4.437 + isJavaIdentifierPart = false; 4.438 + } else { 4.439 + high = reader.scanSurrogates(); 4.440 + if (high != 0) { 4.441 + if (sp == sbuf.length) { 4.442 + putChar(high); 4.443 + } else { 4.444 + sbuf[sp++] = high; 4.445 + } 4.446 + isJavaIdentifierPart = Character.isJavaIdentifierPart( 4.447 + Character.toCodePoint(high, reader.ch)); 4.448 + } else { 4.449 + isJavaIdentifierPart = Character.isJavaIdentifierPart(reader.ch); 4.450 + } 4.451 + } 4.452 + if (!isJavaIdentifierPart) { 4.453 + name = names.fromChars(sbuf, 0, sp); 4.454 + tk = tokens.lookupKind(name); 4.455 + return; 4.456 + } 4.457 + } 4.458 + } while (true); 4.459 + } 4.460 + 4.461 + /** Return true if reader.ch can be part of an operator. 4.462 + */ 4.463 + private boolean isSpecial(char ch) { 4.464 + switch (ch) { 4.465 + case '!': case '%': case '&': case '*': case '?': 4.466 + case '+': case '-': case ':': case '<': case '=': 4.467 + case '>': case '^': case '|': case '~': 4.468 + case '@': 4.469 + return true; 4.470 + default: 4.471 + return false; 4.472 + } 4.473 + } 4.474 + 4.475 + /** Read longest possible sequence of special characters and convert 4.476 + * to token. 4.477 + */ 4.478 + private void scanOperator() { 4.479 + while (true) { 4.480 + putChar(reader.ch); 4.481 + Name newname = names.fromChars(sbuf, 0, sp); 4.482 + TokenKind tk1 = tokens.lookupKind(newname); 4.483 + if (tk1 == TokenKind.IDENTIFIER) { 4.484 + sp--; 4.485 + break; 4.486 + } 4.487 + tk = tk1; 4.488 + reader.scanChar(); 4.489 + if (!isSpecial(reader.ch)) break; 4.490 + } 4.491 + } 4.492 + 4.493 + /** 4.494 + * Scan a documentation comment; determine if a deprecated tag is present. 4.495 + * Called once the initial /, * have been skipped, positioned at the second * 4.496 + * (which is treated as the beginning of the first line). 4.497 + * Stops positioned at the closing '/'. 4.498 + */ 4.499 + @SuppressWarnings("fallthrough") 4.500 + private void scanDocComment() { 4.501 + boolean deprecatedPrefix = false; 4.502 + 4.503 + forEachLine: 4.504 + while (reader.bp < reader.buflen) { 4.505 + 4.506 + // Skip optional WhiteSpace at beginning of line 4.507 + while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) { 4.508 + scanCommentChar(); 4.509 + } 4.510 + 4.511 + // Skip optional consecutive Stars 4.512 + while (reader.bp < reader.buflen && reader.ch == '*') { 4.513 + scanCommentChar(); 4.514 + if (reader.ch == '/') { 4.515 + return; 4.516 + } 4.517 + } 4.518 + 4.519 + // Skip optional WhiteSpace after Stars 4.520 + while (reader.bp < reader.buflen && (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF)) { 4.521 + scanCommentChar(); 4.522 + } 4.523 + 4.524 + deprecatedPrefix = false; 4.525 + // At beginning of line in the JavaDoc sense. 4.526 + if (reader.bp < reader.buflen && reader.ch == '@' && !deprecatedFlag) { 4.527 + scanCommentChar(); 4.528 + if (reader.bp < reader.buflen && reader.ch == 'd') { 4.529 + scanCommentChar(); 4.530 + if (reader.bp < reader.buflen && reader.ch == 'e') { 4.531 + scanCommentChar(); 4.532 + if (reader.bp < reader.buflen && reader.ch == 'p') { 4.533 + scanCommentChar(); 4.534 + if (reader.bp < reader.buflen && reader.ch == 'r') { 4.535 + scanCommentChar(); 4.536 + if (reader.bp < reader.buflen && reader.ch == 'e') { 4.537 + scanCommentChar(); 4.538 + if (reader.bp < reader.buflen && reader.ch == 'c') { 4.539 + scanCommentChar(); 4.540 + if (reader.bp < reader.buflen && reader.ch == 'a') { 4.541 + scanCommentChar(); 4.542 + if (reader.bp < reader.buflen && reader.ch == 't') { 4.543 + scanCommentChar(); 4.544 + if (reader.bp < reader.buflen && reader.ch == 'e') { 4.545 + scanCommentChar(); 4.546 + if (reader.bp < reader.buflen && reader.ch == 'd') { 4.547 + deprecatedPrefix = true; 4.548 + scanCommentChar(); 4.549 + }}}}}}}}}}} 4.550 + if (deprecatedPrefix && reader.bp < reader.buflen) { 4.551 + if (Character.isWhitespace(reader.ch)) { 4.552 + deprecatedFlag = true; 4.553 + } else if (reader.ch == '*') { 4.554 + scanCommentChar(); 4.555 + if (reader.ch == '/') { 4.556 + deprecatedFlag = true; 4.557 + return; 4.558 + } 4.559 + } 4.560 + } 4.561 + 4.562 + // Skip rest of line 4.563 + while (reader.bp < reader.buflen) { 4.564 + switch (reader.ch) { 4.565 + case '*': 4.566 + scanCommentChar(); 4.567 + if (reader.ch == '/') { 4.568 + return; 4.569 + } 4.570 + break; 4.571 + case CR: // (Spec 3.4) 4.572 + scanCommentChar(); 4.573 + if (reader.ch != LF) { 4.574 + continue forEachLine; 4.575 + } 4.576 + /* fall through to LF case */ 4.577 + case LF: // (Spec 3.4) 4.578 + scanCommentChar(); 4.579 + continue forEachLine; 4.580 + default: 4.581 + scanCommentChar(); 4.582 + } 4.583 + } // rest of line 4.584 + } // forEachLine 4.585 + return; 4.586 + } 4.587 + 4.588 + /** Read token. 4.589 + */ 4.590 + public Token readToken() { 4.591 + 4.592 + sp = 0; 4.593 + name = null; 4.594 + deprecatedFlag = false; 4.595 + radix = 0; 4.596 + int pos = 0; 4.597 + int endPos = 0; 4.598 + 4.599 + try { 4.600 + loop: while (true) { 4.601 + pos = reader.bp; 4.602 + switch (reader.ch) { 4.603 + case ' ': // (Spec 3.6) 4.604 + case '\t': // (Spec 3.6) 4.605 + case FF: // (Spec 3.6) 4.606 + do { 4.607 + reader.scanChar(); 4.608 + } while (reader.ch == ' ' || reader.ch == '\t' || reader.ch == FF); 4.609 + processWhiteSpace(pos, reader.bp); 4.610 + break; 4.611 + case LF: // (Spec 3.4) 4.612 + reader.scanChar(); 4.613 + processLineTerminator(pos, reader.bp); 4.614 + break; 4.615 + case CR: // (Spec 3.4) 4.616 + reader.scanChar(); 4.617 + if (reader.ch == LF) { 4.618 + reader.scanChar(); 4.619 + } 4.620 + processLineTerminator(pos, reader.bp); 4.621 + break; 4.622 + case 'A': case 'B': case 'C': case 'D': case 'E': 4.623 + case 'F': case 'G': case 'H': case 'I': case 'J': 4.624 + case 'K': case 'L': case 'M': case 'N': case 'O': 4.625 + case 'P': case 'Q': case 'R': case 'S': case 'T': 4.626 + case 'U': case 'V': case 'W': case 'X': case 'Y': 4.627 + case 'Z': 4.628 + case 'a': case 'b': case 'c': case 'd': case 'e': 4.629 + case 'f': case 'g': case 'h': case 'i': case 'j': 4.630 + case 'k': case 'l': case 'm': case 'n': case 'o': 4.631 + case 'p': case 'q': case 'r': case 's': case 't': 4.632 + case 'u': case 'v': case 'w': case 'x': case 'y': 4.633 + case 'z': 4.634 + case '$': case '_': 4.635 + scanIdent(); 4.636 + break loop; 4.637 + case '0': 4.638 + reader.scanChar(); 4.639 + if (reader.ch == 'x' || reader.ch == 'X') { 4.640 + reader.scanChar(); 4.641 + skipIllegalUnderscores(); 4.642 + if (reader.ch == '.') { 4.643 + scanHexFractionAndSuffix(pos, false); 4.644 + } else if (reader.digit(pos, 16) < 0) { 4.645 + lexError(pos, "invalid.hex.number"); 4.646 + } else { 4.647 + scanNumber(pos, 16); 4.648 + } 4.649 + } else if (reader.ch == 'b' || reader.ch == 'B') { 4.650 + if (!allowBinaryLiterals) { 4.651 + lexError(pos, "unsupported.binary.lit", source.name); 4.652 + allowBinaryLiterals = true; 4.653 + } 4.654 + reader.scanChar(); 4.655 + skipIllegalUnderscores(); 4.656 + if (reader.digit(pos, 2) < 0) { 4.657 + lexError(pos, "invalid.binary.number"); 4.658 + } else { 4.659 + scanNumber(pos, 2); 4.660 + } 4.661 + } else { 4.662 + putChar('0'); 4.663 + if (reader.ch == '_') { 4.664 + int savePos = reader.bp; 4.665 + do { 4.666 + reader.scanChar(); 4.667 + } while (reader.ch == '_'); 4.668 + if (reader.digit(pos, 10) < 0) { 4.669 + lexError(savePos, "illegal.underscore"); 4.670 + } 4.671 + } 4.672 + scanNumber(pos, 8); 4.673 + } 4.674 + break loop; 4.675 + case '1': case '2': case '3': case '4': 4.676 + case '5': case '6': case '7': case '8': case '9': 4.677 + scanNumber(pos, 10); 4.678 + break loop; 4.679 + case '.': 4.680 + reader.scanChar(); 4.681 + if ('0' <= reader.ch && reader.ch <= '9') { 4.682 + putChar('.'); 4.683 + scanFractionAndSuffix(pos); 4.684 + } else if (reader.ch == '.') { 4.685 + putChar('.'); putChar('.'); 4.686 + reader.scanChar(); 4.687 + if (reader.ch == '.') { 4.688 + reader.scanChar(); 4.689 + putChar('.'); 4.690 + tk = TokenKind.ELLIPSIS; 4.691 + } else { 4.692 + lexError(pos, "malformed.fp.lit"); 4.693 + } 4.694 + } else { 4.695 + tk = TokenKind.DOT; 4.696 + } 4.697 + break loop; 4.698 + case ',': 4.699 + reader.scanChar(); tk = TokenKind.COMMA; break loop; 4.700 + case ';': 4.701 + reader.scanChar(); tk = TokenKind.SEMI; break loop; 4.702 + case '(': 4.703 + reader.scanChar(); tk = TokenKind.LPAREN; break loop; 4.704 + case ')': 4.705 + reader.scanChar(); tk = TokenKind.RPAREN; break loop; 4.706 + case '[': 4.707 + reader.scanChar(); tk = TokenKind.LBRACKET; break loop; 4.708 + case ']': 4.709 + reader.scanChar(); tk = TokenKind.RBRACKET; break loop; 4.710 + case '{': 4.711 + reader.scanChar(); tk = TokenKind.LBRACE; break loop; 4.712 + case '}': 4.713 + reader.scanChar(); tk = TokenKind.RBRACE; break loop; 4.714 + case '/': 4.715 + reader.scanChar(); 4.716 + if (reader.ch == '/') { 4.717 + do { 4.718 + scanCommentChar(); 4.719 + } while (reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen); 4.720 + if (reader.bp < reader.buflen) { 4.721 + processComment(pos, reader.bp, CommentStyle.LINE); 4.722 + } 4.723 + break; 4.724 + } else if (reader.ch == '*') { 4.725 + reader.scanChar(); 4.726 + CommentStyle style; 4.727 + if (reader.ch == '*') { 4.728 + style = CommentStyle.JAVADOC; 4.729 + scanDocComment(); 4.730 + } else { 4.731 + style = CommentStyle.BLOCK; 4.732 + while (reader.bp < reader.buflen) { 4.733 + if (reader.ch == '*') { 4.734 + reader.scanChar(); 4.735 + if (reader.ch == '/') break; 4.736 + } else { 4.737 + scanCommentChar(); 4.738 + } 4.739 + } 4.740 + } 4.741 + if (reader.ch == '/') { 4.742 + reader.scanChar(); 4.743 + processComment(pos, reader.bp, style); 4.744 + break; 4.745 + } else { 4.746 + lexError(pos, "unclosed.comment"); 4.747 + break loop; 4.748 + } 4.749 + } else if (reader.ch == '=') { 4.750 + tk = TokenKind.SLASHEQ; 4.751 + reader.scanChar(); 4.752 + } else { 4.753 + tk = TokenKind.SLASH; 4.754 + } 4.755 + break loop; 4.756 + case '\'': 4.757 + reader.scanChar(); 4.758 + if (reader.ch == '\'') { 4.759 + lexError(pos, "empty.char.lit"); 4.760 + } else { 4.761 + if (reader.ch == CR || reader.ch == LF) 4.762 + lexError(pos, "illegal.line.end.in.char.lit"); 4.763 + scanLitChar(pos); 4.764 + char ch2 = reader.ch; 4.765 + if (reader.ch == '\'') { 4.766 + reader.scanChar(); 4.767 + tk = TokenKind.CHARLITERAL; 4.768 + } else { 4.769 + lexError(pos, "unclosed.char.lit"); 4.770 + } 4.771 + } 4.772 + break loop; 4.773 + case '\"': 4.774 + reader.scanChar(); 4.775 + while (reader.ch != '\"' && reader.ch != CR && reader.ch != LF && reader.bp < reader.buflen) 4.776 + scanLitChar(pos); 4.777 + if (reader.ch == '\"') { 4.778 + tk = TokenKind.STRINGLITERAL; 4.779 + reader.scanChar(); 4.780 + } else { 4.781 + lexError(pos, "unclosed.str.lit"); 4.782 + } 4.783 + break loop; 4.784 + default: 4.785 + if (isSpecial(reader.ch)) { 4.786 + scanOperator(); 4.787 + } else { 4.788 + boolean isJavaIdentifierStart; 4.789 + if (reader.ch < '\u0080') { 4.790 + // all ASCII range chars already handled, above 4.791 + isJavaIdentifierStart = false; 4.792 + } else { 4.793 + char high = reader.scanSurrogates(); 4.794 + if (high != 0) { 4.795 + if (sp == sbuf.length) { 4.796 + putChar(high); 4.797 + } else { 4.798 + sbuf[sp++] = high; 4.799 + } 4.800 + 4.801 + isJavaIdentifierStart = Character.isJavaIdentifierStart( 4.802 + Character.toCodePoint(high, reader.ch)); 4.803 + } else { 4.804 + isJavaIdentifierStart = Character.isJavaIdentifierStart(reader.ch); 4.805 + } 4.806 + } 4.807 + if (isJavaIdentifierStart) { 4.808 + scanIdent(); 4.809 + } else if (reader.bp == reader.buflen || reader.ch == EOI && reader.bp + 1 == reader.buflen) { // JLS 3.5 4.810 + tk = TokenKind.EOF; 4.811 + pos = reader.buflen; 4.812 + } else { 4.813 + lexError(pos, "illegal.char", String.valueOf((int)reader.ch)); 4.814 + reader.scanChar(); 4.815 + } 4.816 + } 4.817 + break loop; 4.818 + } 4.819 + } 4.820 + endPos = reader.bp; 4.821 + switch (tk.tag) { 4.822 + case DEFAULT: return new Token(tk, pos, endPos, deprecatedFlag); 4.823 + case NAMED: return new NamedToken(tk, pos, endPos, name, deprecatedFlag); 4.824 + case STRING: return new StringToken(tk, pos, endPos, new String(sbuf, 0, sp), deprecatedFlag); 4.825 + case NUMERIC: return new NumericToken(tk, pos, endPos, new String(sbuf, 0, sp), radix, deprecatedFlag); 4.826 + default: throw new AssertionError(); 4.827 + } 4.828 + } 4.829 + finally { 4.830 + if (scannerDebug) { 4.831 + System.out.println("nextToken(" + pos 4.832 + + "," + endPos + ")=|" + 4.833 + new String(reader.getRawCharacters(pos, endPos)) 4.834 + + "|"); 4.835 + } 4.836 + } 4.837 + } 4.838 + 4.839 + /** Return the position where a lexical error occurred; 4.840 + */ 4.841 + public int errPos() { 4.842 + return errPos; 4.843 + } 4.844 + 4.845 + /** Set the position where a lexical error occurred; 4.846 + */ 4.847 + public void errPos(int pos) { 4.848 + errPos = pos; 4.849 + } 4.850 + 4.851 + public enum CommentStyle { 4.852 + LINE, 4.853 + BLOCK, 4.854 + JAVADOC, 4.855 + } 4.856 + 4.857 + /** 4.858 + * Called when a complete comment has been scanned. pos and endPos 4.859 + * will mark the comment boundary. 4.860 + */ 4.861 + protected void processComment(int pos, int endPos, CommentStyle style) { 4.862 + if (scannerDebug) 4.863 + System.out.println("processComment(" + pos 4.864 + + "," + endPos + "," + style + ")=|" 4.865 + + new String(reader.getRawCharacters(pos, endPos)) 4.866 + + "|"); 4.867 + } 4.868 + 4.869 + /** 4.870 + * Called when a complete whitespace run has been scanned. pos and endPos 4.871 + * will mark the whitespace boundary. 4.872 + */ 4.873 + protected void processWhiteSpace(int pos, int endPos) { 4.874 + if (scannerDebug) 4.875 + System.out.println("processWhitespace(" + pos 4.876 + + "," + endPos + ")=|" + 4.877 + new String(reader.getRawCharacters(pos, endPos)) 4.878 + + "|"); 4.879 + } 4.880 + 4.881 + /** 4.882 + * Called when a line terminator has been processed. 4.883 + */ 4.884 + protected void processLineTerminator(int pos, int endPos) { 4.885 + if (scannerDebug) 4.886 + System.out.println("processTerminator(" + pos 4.887 + + "," + endPos + ")=|" + 4.888 + new String(reader.getRawCharacters(pos, endPos)) 4.889 + + "|"); 4.890 + } 4.891 + 4.892 + /** Build a map for translating between line numbers and 4.893 + * positions in the input. 4.894 + * 4.895 + * @return a LineMap */ 4.896 + public Position.LineMap getLineMap() { 4.897 + return Position.makeLineMap(reader.getRawCharacters(), reader.buflen, false); 4.898 + } 4.899 +}
5.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Fri Oct 21 14:14:29 2011 -0700 5.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java Mon Oct 24 13:00:20 2011 +0100 5.3 @@ -28,6 +28,7 @@ 5.4 import java.util.*; 5.5 5.6 import com.sun.tools.javac.code.*; 5.7 +import com.sun.tools.javac.parser.Tokens.*; 5.8 import com.sun.tools.javac.tree.*; 5.9 import com.sun.tools.javac.tree.JCTree.*; 5.10 import com.sun.tools.javac.util.*; 5.11 @@ -36,7 +37,7 @@ 5.12 import com.sun.tools.javac.util.List; 5.13 5.14 import static com.sun.tools.javac.util.ListBuffer.lb; 5.15 -import static com.sun.tools.javac.parser.Token.*; 5.16 +import static com.sun.tools.javac.parser.Tokens.TokenKind.*; 5.17 5.18 /** The parser maps a token sequence into an abstract syntax 5.19 * tree. It operates by recursive descent, with code derived 5.20 @@ -67,9 +68,6 @@ 5.21 */ 5.22 private Log log; 5.23 5.24 - /** The keyword table. */ 5.25 - private Keywords keywords; 5.26 - 5.27 /** The Source language setting. */ 5.28 private Source source; 5.29 5.30 @@ -83,11 +81,10 @@ 5.31 boolean keepDocComments, 5.32 boolean keepLineMap) { 5.33 this.S = S; 5.34 - S.nextToken(); // prime the pump 5.35 + nextToken(); // prime the pump 5.36 this.F = fac.F; 5.37 this.log = fac.log; 5.38 this.names = fac.names; 5.39 - this.keywords = fac.keywords; 5.40 this.source = fac.source; 5.41 this.allowGenerics = source.allowGenerics(); 5.42 this.allowVarargs = source.allowVarargs(); 5.43 @@ -178,7 +175,16 @@ 5.44 */ 5.45 private int lastmode = 0; 5.46 5.47 -/* ---------- error recovery -------------- */ 5.48 + /* ---------- token management -------------- */ 5.49 + 5.50 + protected Token token; 5.51 + 5.52 + protected void nextToken() { 5.53 + S.nextToken(); 5.54 + token = S.token(); 5.55 + } 5.56 + 5.57 + /* ---------- error recovery -------------- */ 5.58 5.59 private JCErroneous errorTree; 5.60 5.61 @@ -186,9 +192,9 @@ 5.62 */ 5.63 private void skip(boolean stopAtImport, boolean stopAtMemberDecl, boolean stopAtIdentifier, boolean stopAtStatement) { 5.64 while (true) { 5.65 - switch (S.token()) { 5.66 + switch (token.kind) { 5.67 case SEMI: 5.68 - S.nextToken(); 5.69 + nextToken(); 5.70 return; 5.71 case PUBLIC: 5.72 case FINAL: 5.73 @@ -249,15 +255,15 @@ 5.74 return; 5.75 break; 5.76 } 5.77 - S.nextToken(); 5.78 + nextToken(); 5.79 } 5.80 } 5.81 5.82 - private JCErroneous syntaxError(int pos, String key, Token... args) { 5.83 + private JCErroneous syntaxError(int pos, String key, TokenKind... args) { 5.84 return syntaxError(pos, List.<JCTree>nil(), key, args); 5.85 } 5.86 5.87 - private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) { 5.88 + private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, TokenKind... args) { 5.89 setErrorEndPos(pos); 5.90 JCErroneous err = F.at(pos).Erroneous(errs); 5.91 reportSyntaxError(err, key, (Object[])args); 5.92 @@ -287,16 +293,16 @@ 5.93 private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) { 5.94 int pos = diagPos.getPreferredPosition(); 5.95 if (pos > S.errPos() || pos == Position.NOPOS) { 5.96 - if (S.token() == EOF) { 5.97 + if (token.kind == EOF) { 5.98 error(diagPos, "premature.eof"); 5.99 } else { 5.100 error(diagPos, key, args); 5.101 } 5.102 } 5.103 S.errPos(pos); 5.104 - if (S.pos() == errorPos) 5.105 - S.nextToken(); // guarantee progress 5.106 - errorPos = S.pos(); 5.107 + if (token.pos == errorPos) 5.108 + nextToken(); // guarantee progress 5.109 + errorPos = token.pos; 5.110 } 5.111 5.112 5.113 @@ -304,25 +310,25 @@ 5.114 * reported at the same position. 5.115 */ 5.116 private JCErroneous syntaxError(String key) { 5.117 - return syntaxError(S.pos(), key); 5.118 + return syntaxError(token.pos, key); 5.119 } 5.120 5.121 /** Generate a syntax error at current position unless one was 5.122 * already reported at the same position. 5.123 */ 5.124 - private JCErroneous syntaxError(String key, Token arg) { 5.125 - return syntaxError(S.pos(), key, arg); 5.126 + private JCErroneous syntaxError(String key, TokenKind arg) { 5.127 + return syntaxError(token.pos, key, arg); 5.128 } 5.129 5.130 /** If next input token matches given token, skip it, otherwise report 5.131 * an error. 5.132 */ 5.133 - public void accept(Token token) { 5.134 - if (S.token() == token) { 5.135 - S.nextToken(); 5.136 + public void accept(TokenKind tk) { 5.137 + if (token.kind == tk) { 5.138 + nextToken(); 5.139 } else { 5.140 - setErrorEndPos(S.pos()); 5.141 - reportSyntaxError(S.prevEndPos(), "expected", token); 5.142 + setErrorEndPos(token.pos); 5.143 + reportSyntaxError(S.prevToken().endPos, "expected", tk); 5.144 } 5.145 } 5.146 5.147 @@ -340,14 +346,14 @@ 5.148 /** Report an illegal start of expression/type error at current position. 5.149 */ 5.150 JCExpression illegal() { 5.151 - return illegal(S.pos()); 5.152 + return illegal(token.pos); 5.153 } 5.154 5.155 /** Diagnose a modifier flag from the set, if any. */ 5.156 void checkNoMods(long mods) { 5.157 if (mods != 0) { 5.158 long lowestMod = mods & -mods; 5.159 - error(S.pos(), "mod.not.allowed.here", 5.160 + error(token.pos, "mod.not.allowed.here", 5.161 Flags.asFlagSet(lowestMod)); 5.162 } 5.163 } 5.164 @@ -435,30 +441,30 @@ 5.165 * Ident = IDENTIFIER 5.166 */ 5.167 Name ident() { 5.168 - if (S.token() == IDENTIFIER) { 5.169 - Name name = S.name(); 5.170 - S.nextToken(); 5.171 + if (token.kind == IDENTIFIER) { 5.172 + Name name = token.name(); 5.173 + nextToken(); 5.174 return name; 5.175 - } else if (S.token() == ASSERT) { 5.176 + } else if (token.kind == ASSERT) { 5.177 if (allowAsserts) { 5.178 - error(S.pos(), "assert.as.identifier"); 5.179 - S.nextToken(); 5.180 + error(token.pos, "assert.as.identifier"); 5.181 + nextToken(); 5.182 return names.error; 5.183 } else { 5.184 - warning(S.pos(), "assert.as.identifier"); 5.185 - Name name = S.name(); 5.186 - S.nextToken(); 5.187 + warning(token.pos, "assert.as.identifier"); 5.188 + Name name = token.name(); 5.189 + nextToken(); 5.190 return name; 5.191 } 5.192 - } else if (S.token() == ENUM) { 5.193 + } else if (token.kind == ENUM) { 5.194 if (allowEnums) { 5.195 - error(S.pos(), "enum.as.identifier"); 5.196 - S.nextToken(); 5.197 + error(token.pos, "enum.as.identifier"); 5.198 + nextToken(); 5.199 return names.error; 5.200 } else { 5.201 - warning(S.pos(), "enum.as.identifier"); 5.202 - Name name = S.name(); 5.203 - S.nextToken(); 5.204 + warning(token.pos, "enum.as.identifier"); 5.205 + Name name = token.name(); 5.206 + nextToken(); 5.207 return name; 5.208 } 5.209 } else { 5.210 @@ -471,17 +477,17 @@ 5.211 * Qualident = Ident { DOT Ident } 5.212 */ 5.213 public JCExpression qualident() { 5.214 - JCExpression t = toP(F.at(S.pos()).Ident(ident())); 5.215 - while (S.token() == DOT) { 5.216 - int pos = S.pos(); 5.217 - S.nextToken(); 5.218 + JCExpression t = toP(F.at(token.pos).Ident(ident())); 5.219 + while (token.kind == DOT) { 5.220 + int pos = token.pos; 5.221 + nextToken(); 5.222 t = toP(F.at(pos).Select(t, ident())); 5.223 } 5.224 return t; 5.225 } 5.226 5.227 JCExpression literal(Name prefix) { 5.228 - return literal(prefix, S.pos()); 5.229 + return literal(prefix, token.pos); 5.230 } 5.231 5.232 /** 5.233 @@ -498,27 +504,29 @@ 5.234 */ 5.235 JCExpression literal(Name prefix, int pos) { 5.236 JCExpression t = errorTree; 5.237 - switch (S.token()) { 5.238 + switch (token.kind) { 5.239 case INTLITERAL: 5.240 try { 5.241 t = F.at(pos).Literal( 5.242 TypeTags.INT, 5.243 - Convert.string2int(strval(prefix), S.radix())); 5.244 + Convert.string2int(strval(prefix), token.radix())); 5.245 } catch (NumberFormatException ex) { 5.246 - error(S.pos(), "int.number.too.large", strval(prefix)); 5.247 + error(token.pos, "int.number.too.large", strval(prefix)); 5.248 } 5.249 break; 5.250 case LONGLITERAL: 5.251 try { 5.252 t = F.at(pos).Literal( 5.253 TypeTags.LONG, 5.254 - new Long(Convert.string2long(strval(prefix), S.radix()))); 5.255 + new Long(Convert.string2long(strval(prefix), token.radix()))); 5.256 } catch (NumberFormatException ex) { 5.257 - error(S.pos(), "int.number.too.large", strval(prefix)); 5.258 + error(token.pos, "int.number.too.large", strval(prefix)); 5.259 } 5.260 break; 5.261 case FLOATLITERAL: { 5.262 - String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 5.263 + String proper = token.radix() == 16 ? 5.264 + ("0x"+ token.stringVal()) : 5.265 + token.stringVal(); 5.266 Float n; 5.267 try { 5.268 n = Float.valueOf(proper); 5.269 @@ -527,15 +535,17 @@ 5.270 n = Float.NaN; 5.271 } 5.272 if (n.floatValue() == 0.0f && !isZero(proper)) 5.273 - error(S.pos(), "fp.number.too.small"); 5.274 + error(token.pos, "fp.number.too.small"); 5.275 else if (n.floatValue() == Float.POSITIVE_INFINITY) 5.276 - error(S.pos(), "fp.number.too.large"); 5.277 + error(token.pos, "fp.number.too.large"); 5.278 else 5.279 t = F.at(pos).Literal(TypeTags.FLOAT, n); 5.280 break; 5.281 } 5.282 case DOUBLELITERAL: { 5.283 - String proper = (S.radix() == 16 ? ("0x"+ S.stringVal()) : S.stringVal()); 5.284 + String proper = token.radix() == 16 ? 5.285 + ("0x"+ token.stringVal()) : 5.286 + token.stringVal(); 5.287 Double n; 5.288 try { 5.289 n = Double.valueOf(proper); 5.290 @@ -544,9 +554,9 @@ 5.291 n = Double.NaN; 5.292 } 5.293 if (n.doubleValue() == 0.0d && !isZero(proper)) 5.294 - error(S.pos(), "fp.number.too.small"); 5.295 + error(token.pos, "fp.number.too.small"); 5.296 else if (n.doubleValue() == Double.POSITIVE_INFINITY) 5.297 - error(S.pos(), "fp.number.too.large"); 5.298 + error(token.pos, "fp.number.too.large"); 5.299 else 5.300 t = F.at(pos).Literal(TypeTags.DOUBLE, n); 5.301 break; 5.302 @@ -554,17 +564,17 @@ 5.303 case CHARLITERAL: 5.304 t = F.at(pos).Literal( 5.305 TypeTags.CHAR, 5.306 - S.stringVal().charAt(0) + 0); 5.307 + token.stringVal().charAt(0) + 0); 5.308 break; 5.309 case STRINGLITERAL: 5.310 t = F.at(pos).Literal( 5.311 TypeTags.CLASS, 5.312 - S.stringVal()); 5.313 + token.stringVal()); 5.314 break; 5.315 case TRUE: case FALSE: 5.316 t = F.at(pos).Literal( 5.317 TypeTags.BOOLEAN, 5.318 - (S.token() == TRUE ? 1 : 0)); 5.319 + (token.kind == TRUE ? 1 : 0)); 5.320 break; 5.321 case NULL: 5.322 t = F.at(pos).Literal( 5.323 @@ -576,8 +586,8 @@ 5.324 } 5.325 if (t == errorTree) 5.326 t = F.at(pos).Erroneous(); 5.327 - storeEnd(t, S.endPos()); 5.328 - S.nextToken(); 5.329 + storeEnd(t, token.endPos); 5.330 + nextToken(); 5.331 return t; 5.332 } 5.333 //where 5.334 @@ -590,7 +600,7 @@ 5.335 } 5.336 5.337 String strval(Name prefix) { 5.338 - String s = S.stringVal(); 5.339 + String s = token.stringVal(); 5.340 return prefix.isEmpty() ? s : prefix + s; 5.341 } 5.342 5.343 @@ -627,17 +637,17 @@ 5.344 JCExpression term() { 5.345 JCExpression t = term1(); 5.346 if ((mode & EXPR) != 0 && 5.347 - S.token() == EQ || PLUSEQ.compareTo(S.token()) <= 0 && S.token().compareTo(GTGTGTEQ) <= 0) 5.348 + token.kind == EQ || PLUSEQ.compareTo(token.kind) <= 0 && token.kind.compareTo(GTGTGTEQ) <= 0) 5.349 return termRest(t); 5.350 else 5.351 return t; 5.352 } 5.353 5.354 JCExpression termRest(JCExpression t) { 5.355 - switch (S.token()) { 5.356 + switch (token.kind) { 5.357 case EQ: { 5.358 - int pos = S.pos(); 5.359 - S.nextToken(); 5.360 + int pos = token.pos; 5.361 + nextToken(); 5.362 mode = EXPR; 5.363 JCExpression t1 = term(); 5.364 return toP(F.at(pos).Assign(t, t1)); 5.365 @@ -653,12 +663,12 @@ 5.366 case LTLTEQ: 5.367 case GTGTEQ: 5.368 case GTGTGTEQ: 5.369 - int pos = S.pos(); 5.370 - Token token = S.token(); 5.371 - S.nextToken(); 5.372 + int pos = token.pos; 5.373 + TokenKind tk = token.kind; 5.374 + nextToken(); 5.375 mode = EXPR; 5.376 JCExpression t1 = term(); 5.377 - return F.at(pos).Assignop(optag(token), t, t1); 5.378 + return F.at(pos).Assignop(optag(tk), t, t1); 5.379 default: 5.380 return t; 5.381 } 5.382 @@ -670,7 +680,7 @@ 5.383 */ 5.384 JCExpression term1() { 5.385 JCExpression t = term2(); 5.386 - if ((mode & EXPR) != 0 && S.token() == QUES) { 5.387 + if ((mode & EXPR) != 0 && token.kind == QUES) { 5.388 mode = EXPR; 5.389 return term1Rest(t); 5.390 } else { 5.391 @@ -681,9 +691,9 @@ 5.392 /** Expression1Rest = ["?" Expression ":" Expression1] 5.393 */ 5.394 JCExpression term1Rest(JCExpression t) { 5.395 - if (S.token() == QUES) { 5.396 - int pos = S.pos(); 5.397 - S.nextToken(); 5.398 + if (token.kind == QUES) { 5.399 + int pos = token.pos; 5.400 + nextToken(); 5.401 JCExpression t1 = term(); 5.402 accept(COLON); 5.403 JCExpression t2 = term1(); 5.404 @@ -699,7 +709,7 @@ 5.405 */ 5.406 JCExpression term2() { 5.407 JCExpression t = term3(); 5.408 - if ((mode & EXPR) != 0 && prec(S.token()) >= TreeInfo.orPrec) { 5.409 + if ((mode & EXPR) != 0 && prec(token.kind) >= TreeInfo.orPrec) { 5.410 mode = EXPR; 5.411 return term2Rest(t, TreeInfo.orPrec); 5.412 } else { 5.413 @@ -725,28 +735,23 @@ 5.414 JCExpression[] odStack = newOdStack(); 5.415 List<Token[]> savedOp = opStackSupply.elems; 5.416 Token[] opStack = newOpStack(); 5.417 - List<int[]> savedPos = posStackSupply.elems; 5.418 - int[] posStack = newPosStack(); 5.419 + 5.420 // optimization, was odStack = new Tree[...]; opStack = new Tree[...]; 5.421 int top = 0; 5.422 odStack[0] = t; 5.423 - int startPos = S.pos(); 5.424 - Token topOp = ERROR; 5.425 - int topOpPos = Position.NOPOS; 5.426 - while (prec(S.token()) >= minprec) { 5.427 - posStack[top] = topOpPos; 5.428 + int startPos = token.pos; 5.429 + Token topOp = Tokens.DUMMY; 5.430 + while (prec(token.kind) >= minprec) { 5.431 opStack[top] = topOp; 5.432 top++; 5.433 - topOp = S.token(); 5.434 - topOpPos = S.pos(); 5.435 - S.nextToken(); 5.436 - odStack[top] = (topOp == INSTANCEOF) ? parseType() : term3(); 5.437 - while (top > 0 && prec(topOp) >= prec(S.token())) { 5.438 - odStack[top-1] = makeOp(topOpPos, topOp, odStack[top-1], 5.439 + topOp = token; 5.440 + nextToken(); 5.441 + odStack[top] = (topOp.kind == INSTANCEOF) ? parseType() : term3(); 5.442 + while (top > 0 && prec(topOp.kind) >= prec(token.kind)) { 5.443 + odStack[top-1] = makeOp(topOp.pos, topOp.kind, odStack[top-1], 5.444 odStack[top]); 5.445 top--; 5.446 topOp = opStack[top]; 5.447 - topOpPos = posStack[top]; 5.448 } 5.449 } 5.450 Assert.check(top == 0); 5.451 @@ -761,14 +766,13 @@ 5.452 5.453 odStackSupply.elems = savedOd; // optimization 5.454 opStackSupply.elems = savedOp; // optimization 5.455 - posStackSupply.elems = savedPos; // optimization 5.456 return t; 5.457 } 5.458 //where 5.459 /** Construct a binary or type test node. 5.460 */ 5.461 private JCExpression makeOp(int pos, 5.462 - Token topOp, 5.463 + TokenKind topOp, 5.464 JCExpression od1, 5.465 JCExpression od2) 5.466 { 5.467 @@ -817,7 +821,6 @@ 5.468 */ 5.469 ListBuffer<JCExpression[]> odStackSupply = new ListBuffer<JCExpression[]>(); 5.470 ListBuffer<Token[]> opStackSupply = new ListBuffer<Token[]>(); 5.471 - ListBuffer<int[]> posStackSupply = new ListBuffer<int[]>(); 5.472 5.473 private JCExpression[] newOdStack() { 5.474 if (odStackSupply.elems == odStackSupply.last) 5.475 @@ -835,14 +838,6 @@ 5.476 return opStack; 5.477 } 5.478 5.479 - private int[] newPosStack() { 5.480 - if (posStackSupply.elems == posStackSupply.last) 5.481 - posStackSupply.append(new int[infixPrecedenceLevels + 1]); 5.482 - int[] posStack = posStackSupply.elems.head; 5.483 - posStackSupply.elems = posStackSupply.elems.tail; 5.484 - return posStack; 5.485 - } 5.486 - 5.487 /** Expression3 = PrefixOp Expression3 5.488 * | "(" Expr | TypeNoParams ")" Expression3 5.489 * | Primary {Selector} {PostfixOp} 5.490 @@ -871,10 +866,10 @@ 5.491 * SuperSuffix = Arguments | "." Ident [Arguments] 5.492 */ 5.493 protected JCExpression term3() { 5.494 - int pos = S.pos(); 5.495 + int pos = token.pos; 5.496 JCExpression t; 5.497 List<JCExpression> typeArgs = typeArgumentsOpt(EXPR); 5.498 - switch (S.token()) { 5.499 + switch (token.kind) { 5.500 case QUES: 5.501 if ((mode & TYPE) != 0 && (mode & (TYPEARG|NOPARAMS)) == TYPEARG) { 5.502 mode = TYPE; 5.503 @@ -883,49 +878,49 @@ 5.504 return illegal(); 5.505 case PLUSPLUS: case SUBSUB: case BANG: case TILDE: case PLUS: case SUB: 5.506 if (typeArgs == null && (mode & EXPR) != 0) { 5.507 - Token token = S.token(); 5.508 - S.nextToken(); 5.509 + TokenKind tk = token.kind; 5.510 + nextToken(); 5.511 mode = EXPR; 5.512 - if (token == SUB && 5.513 - (S.token() == INTLITERAL || S.token() == LONGLITERAL) && 5.514 - S.radix() == 10) { 5.515 + if (tk == SUB && 5.516 + (token.kind == INTLITERAL || token.kind == LONGLITERAL) && 5.517 + token.radix() == 10) { 5.518 mode = EXPR; 5.519 t = literal(names.hyphen, pos); 5.520 } else { 5.521 t = term3(); 5.522 - return F.at(pos).Unary(unoptag(token), t); 5.523 + return F.at(pos).Unary(unoptag(tk), t); 5.524 } 5.525 } else return illegal(); 5.526 break; 5.527 case LPAREN: 5.528 if (typeArgs == null && (mode & EXPR) != 0) { 5.529 - S.nextToken(); 5.530 + nextToken(); 5.531 mode = EXPR | TYPE | NOPARAMS; 5.532 t = term3(); 5.533 - if ((mode & TYPE) != 0 && S.token() == LT) { 5.534 + if ((mode & TYPE) != 0 && token.kind == LT) { 5.535 // Could be a cast to a parameterized type 5.536 int op = JCTree.LT; 5.537 - int pos1 = S.pos(); 5.538 - S.nextToken(); 5.539 + int pos1 = token.pos; 5.540 + nextToken(); 5.541 mode &= (EXPR | TYPE); 5.542 mode |= TYPEARG; 5.543 JCExpression t1 = term3(); 5.544 if ((mode & TYPE) != 0 && 5.545 - (S.token() == COMMA || S.token() == GT)) { 5.546 + (token.kind == COMMA || token.kind == GT)) { 5.547 mode = TYPE; 5.548 ListBuffer<JCExpression> args = new ListBuffer<JCExpression>(); 5.549 args.append(t1); 5.550 - while (S.token() == COMMA) { 5.551 - S.nextToken(); 5.552 + while (token.kind == COMMA) { 5.553 + nextToken(); 5.554 args.append(typeArgument()); 5.555 } 5.556 accept(GT); 5.557 t = toP(F.at(pos1).TypeApply(t, args.toList())); 5.558 checkGenerics(); 5.559 - while (S.token() == DOT) { 5.560 - S.nextToken(); 5.561 + while (token.kind == DOT) { 5.562 + nextToken(); 5.563 mode = TYPE; 5.564 - t = toP(F.at(S.pos()).Select(t, ident())); 5.565 + t = toP(F.at(token.pos).Select(t, ident())); 5.566 t = typeArgumentsOpt(t); 5.567 } 5.568 t = bracketsOpt(toP(t)); 5.569 @@ -948,7 +943,7 @@ 5.570 JCExpression t1 = term3(); 5.571 return F.at(pos).TypeCast(t, t1); 5.572 } else if ((lastmode & TYPE) != 0) { 5.573 - switch (S.token()) { 5.574 + switch (token.kind) { 5.575 /*case PLUSPLUS: case SUBSUB: */ 5.576 case BANG: case TILDE: 5.577 case LPAREN: case THIS: case SUPER: 5.578 @@ -969,7 +964,7 @@ 5.579 if ((mode & EXPR) != 0) { 5.580 mode = EXPR; 5.581 t = to(F.at(pos).Ident(names._this)); 5.582 - S.nextToken(); 5.583 + nextToken(); 5.584 if (typeArgs == null) 5.585 t = argumentsOpt(null, t); 5.586 else 5.587 @@ -997,22 +992,22 @@ 5.588 if (typeArgs != null) return illegal(); 5.589 if ((mode & EXPR) != 0) { 5.590 mode = EXPR; 5.591 - S.nextToken(); 5.592 - if (S.token() == LT) typeArgs = typeArguments(false); 5.593 + nextToken(); 5.594 + if (token.kind == LT) typeArgs = typeArguments(false); 5.595 t = creator(pos, typeArgs); 5.596 typeArgs = null; 5.597 } else return illegal(); 5.598 break; 5.599 case IDENTIFIER: case ASSERT: case ENUM: 5.600 if (typeArgs != null) return illegal(); 5.601 - t = toP(F.at(S.pos()).Ident(ident())); 5.602 + t = toP(F.at(token.pos).Ident(ident())); 5.603 loop: while (true) { 5.604 - pos = S.pos(); 5.605 - switch (S.token()) { 5.606 + pos = token.pos; 5.607 + switch (token.kind) { 5.608 case LBRACKET: 5.609 - S.nextToken(); 5.610 - if (S.token() == RBRACKET) { 5.611 - S.nextToken(); 5.612 + nextToken(); 5.613 + if (token.kind == RBRACKET) { 5.614 + nextToken(); 5.615 t = bracketsOpt(t); 5.616 t = toP(F.at(pos).TypeArray(t)); 5.617 t = bracketsSuffix(t); 5.618 @@ -1033,24 +1028,24 @@ 5.619 } 5.620 break loop; 5.621 case DOT: 5.622 - S.nextToken(); 5.623 + nextToken(); 5.624 int oldmode = mode; 5.625 mode &= ~NOPARAMS; 5.626 typeArgs = typeArgumentsOpt(EXPR); 5.627 mode = oldmode; 5.628 if ((mode & EXPR) != 0) { 5.629 - switch (S.token()) { 5.630 + switch (token.kind) { 5.631 case CLASS: 5.632 if (typeArgs != null) return illegal(); 5.633 mode = EXPR; 5.634 t = to(F.at(pos).Select(t, names._class)); 5.635 - S.nextToken(); 5.636 + nextToken(); 5.637 break loop; 5.638 case THIS: 5.639 if (typeArgs != null) return illegal(); 5.640 mode = EXPR; 5.641 t = to(F.at(pos).Select(t, names._this)); 5.642 - S.nextToken(); 5.643 + nextToken(); 5.644 break loop; 5.645 case SUPER: 5.646 mode = EXPR; 5.647 @@ -1061,9 +1056,9 @@ 5.648 case NEW: 5.649 if (typeArgs != null) return illegal(); 5.650 mode = EXPR; 5.651 - int pos1 = S.pos(); 5.652 - S.nextToken(); 5.653 - if (S.token() == LT) typeArgs = typeArguments(false); 5.654 + int pos1 = token.pos; 5.655 + nextToken(); 5.656 + if (token.kind == LT) typeArgs = typeArguments(false); 5.657 t = innerCreator(pos1, typeArgs, t); 5.658 typeArgs = null; 5.659 break loop; 5.660 @@ -1087,8 +1082,8 @@ 5.661 case VOID: 5.662 if (typeArgs != null) illegal(); 5.663 if ((mode & EXPR) != 0) { 5.664 - S.nextToken(); 5.665 - if (S.token() == DOT) { 5.666 + nextToken(); 5.667 + if (token.kind == DOT) { 5.668 JCPrimitiveTypeTree ti = toP(F.at(pos).TypeIdent(TypeTags.VOID)); 5.669 t = bracketsSuffix(ti); 5.670 } else { 5.671 @@ -1099,7 +1094,7 @@ 5.672 // a void type (like other primitive types) to the next phase. 5.673 // The error will be reported in Attr.attribTypes or Attr.visitApply. 5.674 JCPrimitiveTypeTree ti = to(F.at(pos).TypeIdent(TypeTags.VOID)); 5.675 - S.nextToken(); 5.676 + nextToken(); 5.677 return ti; 5.678 //return illegal(); 5.679 } 5.680 @@ -1109,14 +1104,14 @@ 5.681 } 5.682 if (typeArgs != null) illegal(); 5.683 while (true) { 5.684 - int pos1 = S.pos(); 5.685 - if (S.token() == LBRACKET) { 5.686 - S.nextToken(); 5.687 + int pos1 = token.pos; 5.688 + if (token.kind == LBRACKET) { 5.689 + nextToken(); 5.690 if ((mode & TYPE) != 0) { 5.691 int oldmode = mode; 5.692 mode = TYPE; 5.693 - if (S.token() == RBRACKET) { 5.694 - S.nextToken(); 5.695 + if (token.kind == RBRACKET) { 5.696 + nextToken(); 5.697 t = bracketsOpt(t); 5.698 t = toP(F.at(pos1).TypeArray(t)); 5.699 return t; 5.700 @@ -1129,21 +1124,21 @@ 5.701 t = to(F.at(pos1).Indexed(t, t1)); 5.702 } 5.703 accept(RBRACKET); 5.704 - } else if (S.token() == DOT) { 5.705 - S.nextToken(); 5.706 + } else if (token.kind == DOT) { 5.707 + nextToken(); 5.708 typeArgs = typeArgumentsOpt(EXPR); 5.709 - if (S.token() == SUPER && (mode & EXPR) != 0) { 5.710 + if (token.kind == SUPER && (mode & EXPR) != 0) { 5.711 mode = EXPR; 5.712 t = to(F.at(pos1).Select(t, names._super)); 5.713 - S.nextToken(); 5.714 + nextToken(); 5.715 t = arguments(typeArgs, t); 5.716 typeArgs = null; 5.717 - } else if (S.token() == NEW && (mode & EXPR) != 0) { 5.718 + } else if (token.kind == NEW && (mode & EXPR) != 0) { 5.719 if (typeArgs != null) return illegal(); 5.720 mode = EXPR; 5.721 - int pos2 = S.pos(); 5.722 - S.nextToken(); 5.723 - if (S.token() == LT) typeArgs = typeArguments(false); 5.724 + int pos2 = token.pos; 5.725 + nextToken(); 5.726 + if (token.kind == LT) typeArgs = typeArguments(false); 5.727 t = innerCreator(pos2, typeArgs, t); 5.728 typeArgs = null; 5.729 } else { 5.730 @@ -1155,11 +1150,11 @@ 5.731 break; 5.732 } 5.733 } 5.734 - while ((S.token() == PLUSPLUS || S.token() == SUBSUB) && (mode & EXPR) != 0) { 5.735 + while ((token.kind == PLUSPLUS || token.kind == SUBSUB) && (mode & EXPR) != 0) { 5.736 mode = EXPR; 5.737 - t = to(F.at(S.pos()).Unary( 5.738 - S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 5.739 - S.nextToken(); 5.740 + t = to(F.at(token.pos).Unary( 5.741 + token.kind == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t)); 5.742 + nextToken(); 5.743 } 5.744 return toP(t); 5.745 } 5.746 @@ -1167,13 +1162,13 @@ 5.747 /** SuperSuffix = Arguments | "." [TypeArguments] Ident [Arguments] 5.748 */ 5.749 JCExpression superSuffix(List<JCExpression> typeArgs, JCExpression t) { 5.750 - S.nextToken(); 5.751 - if (S.token() == LPAREN || typeArgs != null) { 5.752 + nextToken(); 5.753 + if (token.kind == LPAREN || typeArgs != null) { 5.754 t = arguments(typeArgs, t); 5.755 } else { 5.756 - int pos = S.pos(); 5.757 + int pos = token.pos; 5.758 accept(DOT); 5.759 - typeArgs = (S.token() == LT) ? typeArguments(false) : null; 5.760 + typeArgs = (token.kind == LT) ? typeArguments(false) : null; 5.761 t = toP(F.at(pos).Select(t, ident())); 5.762 t = argumentsOpt(typeArgs, t); 5.763 } 5.764 @@ -1183,15 +1178,15 @@ 5.765 /** BasicType = BYTE | SHORT | CHAR | INT | LONG | FLOAT | DOUBLE | BOOLEAN 5.766 */ 5.767 JCPrimitiveTypeTree basicType() { 5.768 - JCPrimitiveTypeTree t = to(F.at(S.pos()).TypeIdent(typetag(S.token()))); 5.769 - S.nextToken(); 5.770 + JCPrimitiveTypeTree t = to(F.at(token.pos).TypeIdent(typetag(token.kind))); 5.771 + nextToken(); 5.772 return t; 5.773 } 5.774 5.775 /** ArgumentsOpt = [ Arguments ] 5.776 */ 5.777 JCExpression argumentsOpt(List<JCExpression> typeArgs, JCExpression t) { 5.778 - if ((mode & EXPR) != 0 && S.token() == LPAREN || typeArgs != null) { 5.779 + if ((mode & EXPR) != 0 && token.kind == LPAREN || typeArgs != null) { 5.780 mode = EXPR; 5.781 return arguments(typeArgs, t); 5.782 } else { 5.783 @@ -1203,24 +1198,24 @@ 5.784 */ 5.785 List<JCExpression> arguments() { 5.786 ListBuffer<JCExpression> args = lb(); 5.787 - if (S.token() == LPAREN) { 5.788 - S.nextToken(); 5.789 - if (S.token() != RPAREN) { 5.790 + if (token.kind == LPAREN) { 5.791 + nextToken(); 5.792 + if (token.kind != RPAREN) { 5.793 args.append(parseExpression()); 5.794 - while (S.token() == COMMA) { 5.795 - S.nextToken(); 5.796 + while (token.kind == COMMA) { 5.797 + nextToken(); 5.798 args.append(parseExpression()); 5.799 } 5.800 } 5.801 accept(RPAREN); 5.802 } else { 5.803 - syntaxError(S.pos(), "expected", LPAREN); 5.804 + syntaxError(token.pos, "expected", LPAREN); 5.805 } 5.806 return args.toList(); 5.807 } 5.808 5.809 JCMethodInvocation arguments(List<JCExpression> typeArgs, JCExpression t) { 5.810 - int pos = S.pos(); 5.811 + int pos = token.pos; 5.812 List<JCExpression> args = arguments(); 5.813 return toP(F.at(pos).Apply(typeArgs, t, args)); 5.814 } 5.815 @@ -1228,7 +1223,7 @@ 5.816 /** TypeArgumentsOpt = [ TypeArguments ] 5.817 */ 5.818 JCExpression typeArgumentsOpt(JCExpression t) { 5.819 - if (S.token() == LT && 5.820 + if (token.kind == LT && 5.821 (mode & TYPE) != 0 && 5.822 (mode & NOPARAMS) == 0) { 5.823 mode = TYPE; 5.824 @@ -1243,7 +1238,7 @@ 5.825 } 5.826 5.827 List<JCExpression> typeArgumentsOpt(int useMode) { 5.828 - if (S.token() == LT) { 5.829 + if (token.kind == LT) { 5.830 checkGenerics(); 5.831 if ((mode & useMode) == 0 || 5.832 (mode & NOPARAMS) != 0) { 5.833 @@ -1258,47 +1253,37 @@ 5.834 /** TypeArguments = "<" TypeArgument {"," TypeArgument} ">" 5.835 */ 5.836 List<JCExpression> typeArguments(boolean diamondAllowed) { 5.837 - if (S.token() == LT) { 5.838 - S.nextToken(); 5.839 - if (S.token() == GT && diamondAllowed) { 5.840 + if (token.kind == LT) { 5.841 + nextToken(); 5.842 + if (token.kind == GT && diamondAllowed) { 5.843 checkDiamond(); 5.844 mode |= DIAMOND; 5.845 - S.nextToken(); 5.846 + nextToken(); 5.847 return List.nil(); 5.848 } else { 5.849 ListBuffer<JCExpression> args = ListBuffer.lb(); 5.850 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 5.851 - while (S.token() == COMMA) { 5.852 - S.nextToken(); 5.853 + while (token.kind == COMMA) { 5.854 + nextToken(); 5.855 args.append(((mode & EXPR) == 0) ? typeArgument() : parseType()); 5.856 } 5.857 - switch (S.token()) { 5.858 - case GTGTGTEQ: 5.859 - S.token(GTGTEQ); 5.860 - break; 5.861 - case GTGTEQ: 5.862 - S.token(GTEQ); 5.863 - break; 5.864 - case GTEQ: 5.865 - S.token(EQ); 5.866 - break; 5.867 - case GTGTGT: 5.868 - S.token(GTGT); 5.869 - break; 5.870 - case GTGT: 5.871 - S.token(GT); 5.872 + switch (token.kind) { 5.873 + 5.874 + case GTGTGTEQ: case GTGTEQ: case GTEQ: 5.875 + case GTGTGT: case GTGT: 5.876 + token = S.split(); 5.877 break; 5.878 case GT: 5.879 - S.nextToken(); 5.880 + nextToken(); 5.881 break; 5.882 default: 5.883 - args.append(syntaxError(S.pos(), "expected", GT)); 5.884 + args.append(syntaxError(token.pos, "expected", GT)); 5.885 break; 5.886 } 5.887 return args.toList(); 5.888 } 5.889 } else { 5.890 - return List.<JCExpression>of(syntaxError(S.pos(), "expected", LT)); 5.891 + return List.<JCExpression>of(syntaxError(token.pos, "expected", LT)); 5.892 } 5.893 } 5.894 5.895 @@ -1308,24 +1293,24 @@ 5.896 * | "?" SUPER Type 5.897 */ 5.898 JCExpression typeArgument() { 5.899 - if (S.token() != QUES) return parseType(); 5.900 - int pos = S.pos(); 5.901 - S.nextToken(); 5.902 - if (S.token() == EXTENDS) { 5.903 + if (token.kind != QUES) return parseType(); 5.904 + int pos = token.pos; 5.905 + nextToken(); 5.906 + if (token.kind == EXTENDS) { 5.907 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.EXTENDS)); 5.908 - S.nextToken(); 5.909 + nextToken(); 5.910 JCExpression bound = parseType(); 5.911 return F.at(pos).Wildcard(t, bound); 5.912 - } else if (S.token() == SUPER) { 5.913 + } else if (token.kind == SUPER) { 5.914 TypeBoundKind t = to(F.at(pos).TypeBoundKind(BoundKind.SUPER)); 5.915 - S.nextToken(); 5.916 + nextToken(); 5.917 JCExpression bound = parseType(); 5.918 return F.at(pos).Wildcard(t, bound); 5.919 - } else if (S.token() == IDENTIFIER) { 5.920 + } else if (token.kind == IDENTIFIER) { 5.921 //error recovery 5.922 TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND); 5.923 JCExpression wc = toP(F.at(pos).Wildcard(t, null)); 5.924 - JCIdent id = toP(F.at(S.pos()).Ident(ident())); 5.925 + JCIdent id = toP(F.at(token.pos).Ident(ident())); 5.926 JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id)); 5.927 reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER); 5.928 return err; 5.929 @@ -1336,7 +1321,7 @@ 5.930 } 5.931 5.932 JCTypeApply typeArguments(JCExpression t, boolean diamondAllowed) { 5.933 - int pos = S.pos(); 5.934 + int pos = token.pos; 5.935 List<JCExpression> args = typeArguments(diamondAllowed); 5.936 return toP(F.at(pos).TypeApply(t, args)); 5.937 } 5.938 @@ -1344,9 +1329,9 @@ 5.939 /** BracketsOpt = {"[" "]"} 5.940 */ 5.941 private JCExpression bracketsOpt(JCExpression t) { 5.942 - if (S.token() == LBRACKET) { 5.943 - int pos = S.pos(); 5.944 - S.nextToken(); 5.945 + if (token.kind == LBRACKET) { 5.946 + int pos = token.pos; 5.947 + nextToken(); 5.948 t = bracketsOptCont(t, pos); 5.949 F.at(pos); 5.950 } 5.951 @@ -1363,17 +1348,17 @@ 5.952 * BracketsSuffixType = 5.953 */ 5.954 JCExpression bracketsSuffix(JCExpression t) { 5.955 - if ((mode & EXPR) != 0 && S.token() == DOT) { 5.956 + if ((mode & EXPR) != 0 && token.kind == DOT) { 5.957 mode = EXPR; 5.958 - int pos = S.pos(); 5.959 - S.nextToken(); 5.960 + int pos = token.pos; 5.961 + nextToken(); 5.962 accept(CLASS); 5.963 - if (S.pos() == errorEndPos) { 5.964 + if (token.pos == errorEndPos) { 5.965 // error recovery 5.966 Name name = null; 5.967 - if (S.token() == IDENTIFIER) { 5.968 - name = S.name(); 5.969 - S.nextToken(); 5.970 + if (token.kind == IDENTIFIER) { 5.971 + name = token.name(); 5.972 + nextToken(); 5.973 } else { 5.974 name = names.error; 5.975 } 5.976 @@ -1384,7 +1369,7 @@ 5.977 } else if ((mode & TYPE) != 0) { 5.978 mode = TYPE; 5.979 } else { 5.980 - syntaxError(S.pos(), "dot.class.expected"); 5.981 + syntaxError(token.pos, "dot.class.expected"); 5.982 } 5.983 return t; 5.984 } 5.985 @@ -1392,7 +1377,7 @@ 5.986 /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest ) 5.987 */ 5.988 JCExpression creator(int newpos, List<JCExpression> typeArgs) { 5.989 - switch (S.token()) { 5.990 + switch (token.kind) { 5.991 case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT: 5.992 case DOUBLE: case BOOLEAN: 5.993 if (typeArgs == null) 5.994 @@ -1405,29 +1390,29 @@ 5.995 mode = TYPE; 5.996 boolean diamondFound = false; 5.997 int lastTypeargsPos = -1; 5.998 - if (S.token() == LT) { 5.999 + if (token.kind == LT) { 5.1000 checkGenerics(); 5.1001 - lastTypeargsPos = S.pos(); 5.1002 + lastTypeargsPos = token.pos; 5.1003 t = typeArguments(t, true); 5.1004 diamondFound = (mode & DIAMOND) != 0; 5.1005 } 5.1006 - while (S.token() == DOT) { 5.1007 + while (token.kind == DOT) { 5.1008 if (diamondFound) { 5.1009 //cannot select after a diamond 5.1010 illegal(); 5.1011 } 5.1012 - int pos = S.pos(); 5.1013 - S.nextToken(); 5.1014 + int pos = token.pos; 5.1015 + nextToken(); 5.1016 t = toP(F.at(pos).Select(t, ident())); 5.1017 - if (S.token() == LT) { 5.1018 - lastTypeargsPos = S.pos(); 5.1019 + if (token.kind == LT) { 5.1020 + lastTypeargsPos = token.pos; 5.1021 checkGenerics(); 5.1022 t = typeArguments(t, true); 5.1023 diamondFound = (mode & DIAMOND) != 0; 5.1024 } 5.1025 } 5.1026 mode = oldmode; 5.1027 - if (S.token() == LBRACKET) { 5.1028 + if (token.kind == LBRACKET) { 5.1029 JCExpression e = arrayCreatorRest(newpos, t); 5.1030 if (diamondFound) { 5.1031 reportSyntaxError(lastTypeargsPos, "cannot.create.array.with.diamond"); 5.1032 @@ -1441,17 +1426,17 @@ 5.1033 // modified to improve error recovery. 5.1034 pos = typeArgs.head.pos; 5.1035 } 5.1036 - setErrorEndPos(S.prevEndPos()); 5.1037 + setErrorEndPos(S.prevToken().endPos); 5.1038 JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e)); 5.1039 reportSyntaxError(err, "cannot.create.array.with.type.arguments"); 5.1040 return toP(err); 5.1041 } 5.1042 return e; 5.1043 - } else if (S.token() == LPAREN) { 5.1044 + } else if (token.kind == LPAREN) { 5.1045 return classCreatorRest(newpos, null, typeArgs, t); 5.1046 } else { 5.1047 - setErrorEndPos(S.pos()); 5.1048 - reportSyntaxError(S.pos(), "expected2", LPAREN, LBRACKET); 5.1049 + setErrorEndPos(token.pos); 5.1050 + reportSyntaxError(token.pos, "expected2", LPAREN, LBRACKET); 5.1051 t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null)); 5.1052 return toP(F.at(newpos).Erroneous(List.<JCTree>of(t))); 5.1053 } 5.1054 @@ -1460,8 +1445,8 @@ 5.1055 /** InnerCreator = Ident [TypeArguments] ClassCreatorRest 5.1056 */ 5.1057 JCExpression innerCreator(int newpos, List<JCExpression> typeArgs, JCExpression encl) { 5.1058 - JCExpression t = toP(F.at(S.pos()).Ident(ident())); 5.1059 - if (S.token() == LT) { 5.1060 + JCExpression t = toP(F.at(token.pos).Ident(ident())); 5.1061 + if (token.kind == LT) { 5.1062 int oldmode = mode; 5.1063 checkGenerics(); 5.1064 t = typeArguments(t, true); 5.1065 @@ -1475,23 +1460,23 @@ 5.1066 */ 5.1067 JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) { 5.1068 accept(LBRACKET); 5.1069 - if (S.token() == RBRACKET) { 5.1070 + if (token.kind == RBRACKET) { 5.1071 accept(RBRACKET); 5.1072 elemtype = bracketsOpt(elemtype); 5.1073 - if (S.token() == LBRACE) { 5.1074 + if (token.kind == LBRACE) { 5.1075 return arrayInitializer(newpos, elemtype); 5.1076 } else { 5.1077 JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null)); 5.1078 - return syntaxError(S.pos(), List.<JCTree>of(t), "array.dimension.missing"); 5.1079 + return syntaxError(token.pos, List.<JCTree>of(t), "array.dimension.missing"); 5.1080 } 5.1081 } else { 5.1082 ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>(); 5.1083 dims.append(parseExpression()); 5.1084 accept(RBRACKET); 5.1085 - while (S.token() == LBRACKET) { 5.1086 - int pos = S.pos(); 5.1087 - S.nextToken(); 5.1088 - if (S.token() == RBRACKET) { 5.1089 + while (token.kind == LBRACKET) { 5.1090 + int pos = token.pos; 5.1091 + nextToken(); 5.1092 + if (token.kind == RBRACKET) { 5.1093 elemtype = bracketsOptCont(elemtype, pos); 5.1094 } else { 5.1095 dims.append(parseExpression()); 5.1096 @@ -1511,8 +1496,8 @@ 5.1097 { 5.1098 List<JCExpression> args = arguments(); 5.1099 JCClassDecl body = null; 5.1100 - if (S.token() == LBRACE) { 5.1101 - int pos = S.pos(); 5.1102 + if (token.kind == LBRACE) { 5.1103 + int pos = token.pos; 5.1104 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 5.1105 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 5.1106 body = toP(F.at(pos).AnonymousClassDef(mods, defs)); 5.1107 @@ -1525,13 +1510,13 @@ 5.1108 JCExpression arrayInitializer(int newpos, JCExpression t) { 5.1109 accept(LBRACE); 5.1110 ListBuffer<JCExpression> elems = new ListBuffer<JCExpression>(); 5.1111 - if (S.token() == COMMA) { 5.1112 - S.nextToken(); 5.1113 - } else if (S.token() != RBRACE) { 5.1114 + if (token.kind == COMMA) { 5.1115 + nextToken(); 5.1116 + } else if (token.kind != RBRACE) { 5.1117 elems.append(variableInitializer()); 5.1118 - while (S.token() == COMMA) { 5.1119 - S.nextToken(); 5.1120 - if (S.token() == RBRACE) break; 5.1121 + while (token.kind == COMMA) { 5.1122 + nextToken(); 5.1123 + if (token.kind == RBRACE) break; 5.1124 elems.append(variableInitializer()); 5.1125 } 5.1126 } 5.1127 @@ -1542,7 +1527,7 @@ 5.1128 /** VariableInitializer = ArrayInitializer | Expression 5.1129 */ 5.1130 public JCExpression variableInitializer() { 5.1131 - return S.token() == LBRACE ? arrayInitializer(S.pos(), null) : parseExpression(); 5.1132 + return token.kind == LBRACE ? arrayInitializer(token.pos, null) : parseExpression(); 5.1133 } 5.1134 5.1135 /** ParExpression = "(" Expression ")" 5.1136 @@ -1560,19 +1545,19 @@ 5.1137 accept(LBRACE); 5.1138 List<JCStatement> stats = blockStatements(); 5.1139 JCBlock t = F.at(pos).Block(flags, stats); 5.1140 - while (S.token() == CASE || S.token() == DEFAULT) { 5.1141 - syntaxError("orphaned", S.token()); 5.1142 + while (token.kind == CASE || token.kind == DEFAULT) { 5.1143 + syntaxError("orphaned", token.kind); 5.1144 switchBlockStatementGroups(); 5.1145 } 5.1146 // the Block node has a field "endpos" for first char of last token, which is 5.1147 // usually but not necessarily the last char of the last token. 5.1148 - t.endpos = S.pos(); 5.1149 + t.endpos = token.pos; 5.1150 accept(RBRACE); 5.1151 return toP(t); 5.1152 } 5.1153 5.1154 public JCBlock block() { 5.1155 - return block(S.pos(), 0); 5.1156 + return block(token.pos, 0); 5.1157 } 5.1158 5.1159 /** BlockStatements = { BlockStatement } 5.1160 @@ -1588,8 +1573,8 @@ 5.1161 int lastErrPos = -1; 5.1162 ListBuffer<JCStatement> stats = new ListBuffer<JCStatement>(); 5.1163 while (true) { 5.1164 - int pos = S.pos(); 5.1165 - switch (S.token()) { 5.1166 + int pos = token.pos; 5.1167 + switch (token.kind) { 5.1168 case RBRACE: case CASE: case DEFAULT: case EOF: 5.1169 return stats.toList(); 5.1170 case LBRACE: case IF: case FOR: case WHILE: case DO: case TRY: 5.1171 @@ -1599,64 +1584,63 @@ 5.1172 break; 5.1173 case MONKEYS_AT: 5.1174 case FINAL: { 5.1175 - String dc = S.docComment(); 5.1176 + String dc = token.docComment; 5.1177 JCModifiers mods = modifiersOpt(); 5.1178 - if (S.token() == INTERFACE || 5.1179 - S.token() == CLASS || 5.1180 - allowEnums && S.token() == ENUM) { 5.1181 + if (token.kind == INTERFACE || 5.1182 + token.kind == CLASS || 5.1183 + allowEnums && token.kind == ENUM) { 5.1184 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 5.1185 } else { 5.1186 JCExpression t = parseType(); 5.1187 stats.appendList(variableDeclarators(mods, t, 5.1188 new ListBuffer<JCStatement>())); 5.1189 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 5.1190 - storeEnd(stats.elems.last(), S.endPos()); 5.1191 + storeEnd(stats.elems.last(), token.endPos); 5.1192 accept(SEMI); 5.1193 } 5.1194 break; 5.1195 } 5.1196 case ABSTRACT: case STRICTFP: { 5.1197 - String dc = S.docComment(); 5.1198 + String dc = token.docComment; 5.1199 JCModifiers mods = modifiersOpt(); 5.1200 stats.append(classOrInterfaceOrEnumDeclaration(mods, dc)); 5.1201 break; 5.1202 } 5.1203 case INTERFACE: 5.1204 case CLASS: 5.1205 - stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 5.1206 - S.docComment())); 5.1207 + String dc = token.docComment; 5.1208 + stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); 5.1209 break; 5.1210 case ENUM: 5.1211 case ASSERT: 5.1212 - if (allowEnums && S.token() == ENUM) { 5.1213 - error(S.pos(), "local.enum"); 5.1214 - stats. 5.1215 - append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), 5.1216 - S.docComment())); 5.1217 + if (allowEnums && token.kind == ENUM) { 5.1218 + error(token.pos, "local.enum"); 5.1219 + dc = token.docComment; 5.1220 + stats.append(classOrInterfaceOrEnumDeclaration(modifiersOpt(), dc)); 5.1221 break; 5.1222 - } else if (allowAsserts && S.token() == ASSERT) { 5.1223 + } else if (allowAsserts && token.kind == ASSERT) { 5.1224 stats.append(parseStatement()); 5.1225 break; 5.1226 } 5.1227 /* fall through to default */ 5.1228 default: 5.1229 - Name name = S.name(); 5.1230 + Token prevToken = token; 5.1231 JCExpression t = term(EXPR | TYPE); 5.1232 - if (S.token() == COLON && t.getTag() == JCTree.IDENT) { 5.1233 - S.nextToken(); 5.1234 + if (token.kind == COLON && t.getTag() == JCTree.IDENT) { 5.1235 + nextToken(); 5.1236 JCStatement stat = parseStatement(); 5.1237 - stats.append(F.at(pos).Labelled(name, stat)); 5.1238 + stats.append(F.at(pos).Labelled(prevToken.name(), stat)); 5.1239 } else if ((lastmode & TYPE) != 0 && 5.1240 - (S.token() == IDENTIFIER || 5.1241 - S.token() == ASSERT || 5.1242 - S.token() == ENUM)) { 5.1243 - pos = S.pos(); 5.1244 + (token.kind == IDENTIFIER || 5.1245 + token.kind == ASSERT || 5.1246 + token.kind == ENUM)) { 5.1247 + pos = token.pos; 5.1248 JCModifiers mods = F.at(Position.NOPOS).Modifiers(0); 5.1249 F.at(pos); 5.1250 stats.appendList(variableDeclarators(mods, t, 5.1251 new ListBuffer<JCStatement>())); 5.1252 // A "LocalVariableDeclarationStatement" subsumes the terminating semicolon 5.1253 - storeEnd(stats.elems.last(), S.endPos()); 5.1254 + storeEnd(stats.elems.last(), token.endPos); 5.1255 accept(SEMI); 5.1256 } else { 5.1257 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 5.1258 @@ -1666,15 +1650,12 @@ 5.1259 } 5.1260 5.1261 // error recovery 5.1262 - if (S.pos() == lastErrPos) 5.1263 + if (token.pos == lastErrPos) 5.1264 return stats.toList(); 5.1265 - if (S.pos() <= errorEndPos) { 5.1266 + if (token.pos <= errorEndPos) { 5.1267 skip(false, true, true, true); 5.1268 - lastErrPos = S.pos(); 5.1269 + lastErrPos = token.pos; 5.1270 } 5.1271 - 5.1272 - // ensure no dangling /** @deprecated */ active 5.1273 - S.resetDeprecatedFlag(); 5.1274 } 5.1275 } 5.1276 5.1277 @@ -1700,29 +1681,29 @@ 5.1278 */ 5.1279 @SuppressWarnings("fallthrough") 5.1280 public JCStatement parseStatement() { 5.1281 - int pos = S.pos(); 5.1282 - switch (S.token()) { 5.1283 + int pos = token.pos; 5.1284 + switch (token.kind) { 5.1285 case LBRACE: 5.1286 return block(); 5.1287 case IF: { 5.1288 - S.nextToken(); 5.1289 + nextToken(); 5.1290 JCExpression cond = parExpression(); 5.1291 JCStatement thenpart = parseStatement(); 5.1292 JCStatement elsepart = null; 5.1293 - if (S.token() == ELSE) { 5.1294 - S.nextToken(); 5.1295 + if (token.kind == ELSE) { 5.1296 + nextToken(); 5.1297 elsepart = parseStatement(); 5.1298 } 5.1299 return F.at(pos).If(cond, thenpart, elsepart); 5.1300 } 5.1301 case FOR: { 5.1302 - S.nextToken(); 5.1303 + nextToken(); 5.1304 accept(LPAREN); 5.1305 - List<JCStatement> inits = S.token() == SEMI ? List.<JCStatement>nil() : forInit(); 5.1306 + List<JCStatement> inits = token.kind == SEMI ? List.<JCStatement>nil() : forInit(); 5.1307 if (inits.length() == 1 && 5.1308 inits.head.getTag() == JCTree.VARDEF && 5.1309 ((JCVariableDecl) inits.head).init == null && 5.1310 - S.token() == COLON) { 5.1311 + token.kind == COLON) { 5.1312 checkForeach(); 5.1313 JCVariableDecl var = (JCVariableDecl)inits.head; 5.1314 accept(COLON); 5.1315 @@ -1732,22 +1713,22 @@ 5.1316 return F.at(pos).ForeachLoop(var, expr, body); 5.1317 } else { 5.1318 accept(SEMI); 5.1319 - JCExpression cond = S.token() == SEMI ? null : parseExpression(); 5.1320 + JCExpression cond = token.kind == SEMI ? null : parseExpression(); 5.1321 accept(SEMI); 5.1322 - List<JCExpressionStatement> steps = S.token() == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); 5.1323 + List<JCExpressionStatement> steps = token.kind == RPAREN ? List.<JCExpressionStatement>nil() : forUpdate(); 5.1324 accept(RPAREN); 5.1325 JCStatement body = parseStatement(); 5.1326 return F.at(pos).ForLoop(inits, cond, steps, body); 5.1327 } 5.1328 } 5.1329 case WHILE: { 5.1330 - S.nextToken(); 5.1331 + nextToken(); 5.1332 JCExpression cond = parExpression(); 5.1333 JCStatement body = parseStatement(); 5.1334 return F.at(pos).WhileLoop(cond, body); 5.1335 } 5.1336 case DO: { 5.1337 - S.nextToken(); 5.1338 + nextToken(); 5.1339 JCStatement body = parseStatement(); 5.1340 accept(WHILE); 5.1341 JCExpression cond = parExpression(); 5.1342 @@ -1756,21 +1737,21 @@ 5.1343 return t; 5.1344 } 5.1345 case TRY: { 5.1346 - S.nextToken(); 5.1347 + nextToken(); 5.1348 List<JCTree> resources = List.<JCTree>nil(); 5.1349 - if (S.token() == LPAREN) { 5.1350 + if (token.kind == LPAREN) { 5.1351 checkTryWithResources(); 5.1352 - S.nextToken(); 5.1353 + nextToken(); 5.1354 resources = resources(); 5.1355 accept(RPAREN); 5.1356 } 5.1357 JCBlock body = block(); 5.1358 ListBuffer<JCCatch> catchers = new ListBuffer<JCCatch>(); 5.1359 JCBlock finalizer = null; 5.1360 - if (S.token() == CATCH || S.token() == FINALLY) { 5.1361 - while (S.token() == CATCH) catchers.append(catchClause()); 5.1362 - if (S.token() == FINALLY) { 5.1363 - S.nextToken(); 5.1364 + if (token.kind == CATCH || token.kind == FINALLY) { 5.1365 + while (token.kind == CATCH) catchers.append(catchClause()); 5.1366 + if (token.kind == FINALLY) { 5.1367 + nextToken(); 5.1368 finalizer = block(); 5.1369 } 5.1370 } else { 5.1371 @@ -1783,7 +1764,7 @@ 5.1372 return F.at(pos).Try(resources, body, catchers.toList(), finalizer); 5.1373 } 5.1374 case SWITCH: { 5.1375 - S.nextToken(); 5.1376 + nextToken(); 5.1377 JCExpression selector = parExpression(); 5.1378 accept(LBRACE); 5.1379 List<JCCase> cases = switchBlockStatementGroups(); 5.1380 @@ -1792,41 +1773,41 @@ 5.1381 return t; 5.1382 } 5.1383 case SYNCHRONIZED: { 5.1384 - S.nextToken(); 5.1385 + nextToken(); 5.1386 JCExpression lock = parExpression(); 5.1387 JCBlock body = block(); 5.1388 return F.at(pos).Synchronized(lock, body); 5.1389 } 5.1390 case RETURN: { 5.1391 - S.nextToken(); 5.1392 - JCExpression result = S.token() == SEMI ? null : parseExpression(); 5.1393 + nextToken(); 5.1394 + JCExpression result = token.kind == SEMI ? null : parseExpression(); 5.1395 JCReturn t = to(F.at(pos).Return(result)); 5.1396 accept(SEMI); 5.1397 return t; 5.1398 } 5.1399 case THROW: { 5.1400 - S.nextToken(); 5.1401 + nextToken(); 5.1402 JCExpression exc = parseExpression(); 5.1403 JCThrow t = to(F.at(pos).Throw(exc)); 5.1404 accept(SEMI); 5.1405 return t; 5.1406 } 5.1407 case BREAK: { 5.1408 - S.nextToken(); 5.1409 - Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 5.1410 + nextToken(); 5.1411 + Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null; 5.1412 JCBreak t = to(F.at(pos).Break(label)); 5.1413 accept(SEMI); 5.1414 return t; 5.1415 } 5.1416 case CONTINUE: { 5.1417 - S.nextToken(); 5.1418 - Name label = (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM) ? ident() : null; 5.1419 + nextToken(); 5.1420 + Name label = (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM) ? ident() : null; 5.1421 JCContinue t = to(F.at(pos).Continue(label)); 5.1422 accept(SEMI); 5.1423 return t; 5.1424 } 5.1425 case SEMI: 5.1426 - S.nextToken(); 5.1427 + nextToken(); 5.1428 return toP(F.at(pos).Skip()); 5.1429 case ELSE: 5.1430 return toP(F.Exec(syntaxError("else.without.if"))); 5.1431 @@ -1835,12 +1816,12 @@ 5.1432 case CATCH: 5.1433 return toP(F.Exec(syntaxError("catch.without.try"))); 5.1434 case ASSERT: { 5.1435 - if (allowAsserts && S.token() == ASSERT) { 5.1436 - S.nextToken(); 5.1437 + if (allowAsserts && token.kind == ASSERT) { 5.1438 + nextToken(); 5.1439 JCExpression assertion = parseExpression(); 5.1440 JCExpression message = null; 5.1441 - if (S.token() == COLON) { 5.1442 - S.nextToken(); 5.1443 + if (token.kind == COLON) { 5.1444 + nextToken(); 5.1445 message = parseExpression(); 5.1446 } 5.1447 JCAssert t = to(F.at(pos).Assert(assertion, message)); 5.1448 @@ -1851,12 +1832,12 @@ 5.1449 } 5.1450 case ENUM: 5.1451 default: 5.1452 - Name name = S.name(); 5.1453 + Token prevToken = token; 5.1454 JCExpression expr = parseExpression(); 5.1455 - if (S.token() == COLON && expr.getTag() == JCTree.IDENT) { 5.1456 - S.nextToken(); 5.1457 + if (token.kind == COLON && expr.getTag() == JCTree.IDENT) { 5.1458 + nextToken(); 5.1459 JCStatement stat = parseStatement(); 5.1460 - return F.at(pos).Labelled(name, stat); 5.1461 + return F.at(pos).Labelled(prevToken.name(), stat); 5.1462 } else { 5.1463 // This Exec is an "ExpressionStatement"; it subsumes the terminating semicolon 5.1464 JCExpressionStatement stat = to(F.at(pos).Exec(checkExprStat(expr))); 5.1465 @@ -1869,7 +1850,7 @@ 5.1466 /** CatchClause = CATCH "(" FormalParameter ")" Block 5.1467 */ 5.1468 protected JCCatch catchClause() { 5.1469 - int pos = S.pos(); 5.1470 + int pos = token.pos; 5.1471 accept(CATCH); 5.1472 accept(LPAREN); 5.1473 JCModifiers mods = optFinal(Flags.PARAMETER); 5.1474 @@ -1886,9 +1867,9 @@ 5.1475 List<JCExpression> catchTypes() { 5.1476 ListBuffer<JCExpression> catchTypes = ListBuffer.lb(); 5.1477 catchTypes.add(parseType()); 5.1478 - while (S.token() == BAR) { 5.1479 + while (token.kind == BAR) { 5.1480 checkMulticatch(); 5.1481 - S.nextToken(); 5.1482 + nextToken(); 5.1483 catchTypes.add(qualident()); 5.1484 } 5.1485 return catchTypes.toList(); 5.1486 @@ -1901,33 +1882,33 @@ 5.1487 List<JCCase> switchBlockStatementGroups() { 5.1488 ListBuffer<JCCase> cases = new ListBuffer<JCCase>(); 5.1489 while (true) { 5.1490 - int pos = S.pos(); 5.1491 - switch (S.token()) { 5.1492 + int pos = token.pos; 5.1493 + switch (token.kind) { 5.1494 case CASE: { 5.1495 - S.nextToken(); 5.1496 + nextToken(); 5.1497 JCExpression pat = parseExpression(); 5.1498 accept(COLON); 5.1499 List<JCStatement> stats = blockStatements(); 5.1500 JCCase c = F.at(pos).Case(pat, stats); 5.1501 if (stats.isEmpty()) 5.1502 - storeEnd(c, S.prevEndPos()); 5.1503 + storeEnd(c, S.prevToken().endPos); 5.1504 cases.append(c); 5.1505 break; 5.1506 } 5.1507 case DEFAULT: { 5.1508 - S.nextToken(); 5.1509 + nextToken(); 5.1510 accept(COLON); 5.1511 List<JCStatement> stats = blockStatements(); 5.1512 JCCase c = F.at(pos).Case(null, stats); 5.1513 if (stats.isEmpty()) 5.1514 - storeEnd(c, S.prevEndPos()); 5.1515 + storeEnd(c, S.prevToken().endPos); 5.1516 cases.append(c); 5.1517 break; 5.1518 } 5.1519 case RBRACE: case EOF: 5.1520 return cases.toList(); 5.1521 default: 5.1522 - S.nextToken(); // to ensure progress 5.1523 + nextToken(); // to ensure progress 5.1524 syntaxError(pos, "expected3", 5.1525 CASE, DEFAULT, RBRACE); 5.1526 } 5.1527 @@ -1941,9 +1922,9 @@ 5.1528 T stats) { 5.1529 // This Exec is a "StatementExpression"; it subsumes no terminating token 5.1530 stats.append(toP(F.at(pos).Exec(checkExprStat(first)))); 5.1531 - while (S.token() == COMMA) { 5.1532 - S.nextToken(); 5.1533 - pos = S.pos(); 5.1534 + while (token.kind == COMMA) { 5.1535 + nextToken(); 5.1536 + pos = token.pos; 5.1537 JCExpression t = parseExpression(); 5.1538 // This Exec is a "StatementExpression"; it subsumes no terminating token 5.1539 stats.append(toP(F.at(pos).Exec(checkExprStat(t)))); 5.1540 @@ -1956,13 +1937,13 @@ 5.1541 */ 5.1542 List<JCStatement> forInit() { 5.1543 ListBuffer<JCStatement> stats = lb(); 5.1544 - int pos = S.pos(); 5.1545 - if (S.token() == FINAL || S.token() == MONKEYS_AT) { 5.1546 + int pos = token.pos; 5.1547 + if (token.kind == FINAL || token.kind == MONKEYS_AT) { 5.1548 return variableDeclarators(optFinal(0), parseType(), stats).toList(); 5.1549 } else { 5.1550 JCExpression t = term(EXPR | TYPE); 5.1551 if ((lastmode & TYPE) != 0 && 5.1552 - (S.token() == IDENTIFIER || S.token() == ASSERT || S.token() == ENUM)) 5.1553 + (token.kind == IDENTIFIER || token.kind == ASSERT || token.kind == ENUM)) 5.1554 return variableDeclarators(modifiersOpt(), t, stats).toList(); 5.1555 else 5.1556 return moreStatementExpressions(pos, t, stats).toList(); 5.1557 @@ -1972,7 +1953,7 @@ 5.1558 /** ForUpdate = StatementExpression MoreStatementExpressions 5.1559 */ 5.1560 List<JCExpressionStatement> forUpdate() { 5.1561 - return moreStatementExpressions(S.pos(), 5.1562 + return moreStatementExpressions(token.pos, 5.1563 parseExpression(), 5.1564 new ListBuffer<JCExpressionStatement>()).toList(); 5.1565 } 5.1566 @@ -1980,11 +1961,11 @@ 5.1567 /** AnnotationsOpt = { '@' Annotation } 5.1568 */ 5.1569 List<JCAnnotation> annotationsOpt() { 5.1570 - if (S.token() != MONKEYS_AT) return List.nil(); // optimization 5.1571 + if (token.kind != MONKEYS_AT) return List.nil(); // optimization 5.1572 ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>(); 5.1573 - while (S.token() == MONKEYS_AT) { 5.1574 - int pos = S.pos(); 5.1575 - S.nextToken(); 5.1576 + while (token.kind == MONKEYS_AT) { 5.1577 + int pos = token.pos; 5.1578 + nextToken(); 5.1579 buf.append(annotation(pos)); 5.1580 } 5.1581 return buf.toList(); 5.1582 @@ -2004,21 +1985,20 @@ 5.1583 int pos; 5.1584 if (partial == null) { 5.1585 flags = 0; 5.1586 - pos = S.pos(); 5.1587 + pos = token.pos; 5.1588 } else { 5.1589 flags = partial.flags; 5.1590 annotations.appendList(partial.annotations); 5.1591 pos = partial.pos; 5.1592 } 5.1593 - if (S.deprecatedFlag()) { 5.1594 + if (token.deprecatedFlag) { 5.1595 flags |= Flags.DEPRECATED; 5.1596 - S.resetDeprecatedFlag(); 5.1597 } 5.1598 int lastPos = Position.NOPOS; 5.1599 loop: 5.1600 while (true) { 5.1601 long flag; 5.1602 - switch (S.token()) { 5.1603 + switch (token.kind) { 5.1604 case PRIVATE : flag = Flags.PRIVATE; break; 5.1605 case PROTECTED : flag = Flags.PROTECTED; break; 5.1606 case PUBLIC : flag = Flags.PUBLIC; break; 5.1607 @@ -2031,15 +2011,15 @@ 5.1608 case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break; 5.1609 case STRICTFP : flag = Flags.STRICTFP; break; 5.1610 case MONKEYS_AT : flag = Flags.ANNOTATION; break; 5.1611 - case ERROR : flag = 0; S.nextToken(); break; 5.1612 + case ERROR : flag = 0; nextToken(); break; 5.1613 default: break loop; 5.1614 } 5.1615 - if ((flags & flag) != 0) error(S.pos(), "repeated.modifier"); 5.1616 - lastPos = S.pos(); 5.1617 - S.nextToken(); 5.1618 + if ((flags & flag) != 0) error(token.pos, "repeated.modifier"); 5.1619 + lastPos = token.pos; 5.1620 + nextToken(); 5.1621 if (flag == Flags.ANNOTATION) { 5.1622 checkAnnotations(); 5.1623 - if (S.token() != INTERFACE) { 5.1624 + if (token.kind != INTERFACE) { 5.1625 JCAnnotation ann = annotation(lastPos); 5.1626 // if first modifier is an annotation, set pos to annotation's. 5.1627 if (flags == 0 && annotations.isEmpty()) 5.1628 @@ -2051,7 +2031,7 @@ 5.1629 } 5.1630 flags |= flag; 5.1631 } 5.1632 - switch (S.token()) { 5.1633 + switch (token.kind) { 5.1634 case ENUM: flags |= Flags.ENUM; break; 5.1635 case INTERFACE: flags |= Flags.INTERFACE; break; 5.1636 default: break; 5.1637 @@ -2064,7 +2044,7 @@ 5.1638 5.1639 JCModifiers mods = F.at(pos).Modifiers(flags, annotations.toList()); 5.1640 if (pos != Position.NOPOS) 5.1641 - storeEnd(mods, S.prevEndPos()); 5.1642 + storeEnd(mods, S.prevToken().endPos); 5.1643 return mods; 5.1644 } 5.1645 5.1646 @@ -2077,22 +2057,22 @@ 5.1647 JCTree ident = qualident(); 5.1648 List<JCExpression> fieldValues = annotationFieldValuesOpt(); 5.1649 JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues); 5.1650 - storeEnd(ann, S.prevEndPos()); 5.1651 + storeEnd(ann, S.prevToken().endPos); 5.1652 return ann; 5.1653 } 5.1654 5.1655 List<JCExpression> annotationFieldValuesOpt() { 5.1656 - return (S.token() == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil(); 5.1657 + return (token.kind == LPAREN) ? annotationFieldValues() : List.<JCExpression>nil(); 5.1658 } 5.1659 5.1660 /** AnnotationFieldValues = "(" [ AnnotationFieldValue { "," AnnotationFieldValue } ] ")" */ 5.1661 List<JCExpression> annotationFieldValues() { 5.1662 accept(LPAREN); 5.1663 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 5.1664 - if (S.token() != RPAREN) { 5.1665 + if (token.kind != RPAREN) { 5.1666 buf.append(annotationFieldValue()); 5.1667 - while (S.token() == COMMA) { 5.1668 - S.nextToken(); 5.1669 + while (token.kind == COMMA) { 5.1670 + nextToken(); 5.1671 buf.append(annotationFieldValue()); 5.1672 } 5.1673 } 5.1674 @@ -2104,11 +2084,11 @@ 5.1675 * | Identifier "=" AnnotationValue 5.1676 */ 5.1677 JCExpression annotationFieldValue() { 5.1678 - if (S.token() == IDENTIFIER) { 5.1679 + if (token.kind == IDENTIFIER) { 5.1680 mode = EXPR; 5.1681 JCExpression t1 = term1(); 5.1682 - if (t1.getTag() == JCTree.IDENT && S.token() == EQ) { 5.1683 - int pos = S.pos(); 5.1684 + if (t1.getTag() == JCTree.IDENT && token.kind == EQ) { 5.1685 + int pos = token.pos; 5.1686 accept(EQ); 5.1687 JCExpression v = annotationValue(); 5.1688 return toP(F.at(pos).Assign(t1, v)); 5.1689 @@ -2125,20 +2105,20 @@ 5.1690 */ 5.1691 JCExpression annotationValue() { 5.1692 int pos; 5.1693 - switch (S.token()) { 5.1694 + switch (token.kind) { 5.1695 case MONKEYS_AT: 5.1696 - pos = S.pos(); 5.1697 - S.nextToken(); 5.1698 + pos = token.pos; 5.1699 + nextToken(); 5.1700 return annotation(pos); 5.1701 case LBRACE: 5.1702 - pos = S.pos(); 5.1703 + pos = token.pos; 5.1704 accept(LBRACE); 5.1705 ListBuffer<JCExpression> buf = new ListBuffer<JCExpression>(); 5.1706 - if (S.token() != RBRACE) { 5.1707 + if (token.kind != RBRACE) { 5.1708 buf.append(annotationValue()); 5.1709 - while (S.token() == COMMA) { 5.1710 - S.nextToken(); 5.1711 - if (S.token() == RBRACE) break; 5.1712 + while (token.kind == COMMA) { 5.1713 + nextToken(); 5.1714 + if (token.kind == RBRACE) break; 5.1715 buf.append(annotationValue()); 5.1716 } 5.1717 } 5.1718 @@ -2156,7 +2136,7 @@ 5.1719 JCExpression type, 5.1720 T vdefs) 5.1721 { 5.1722 - return variableDeclaratorsRest(S.pos(), mods, type, ident(), false, null, vdefs); 5.1723 + return variableDeclaratorsRest(token.pos, mods, type, ident(), false, null, vdefs); 5.1724 } 5.1725 5.1726 /** VariableDeclaratorsRest = VariableDeclaratorRest { "," VariableDeclarator } 5.1727 @@ -2174,10 +2154,10 @@ 5.1728 T vdefs) 5.1729 { 5.1730 vdefs.append(variableDeclaratorRest(pos, mods, type, name, reqInit, dc)); 5.1731 - while (S.token() == COMMA) { 5.1732 + while (token.kind == COMMA) { 5.1733 // All but last of multiple declarators subsume a comma 5.1734 - storeEnd((JCTree)vdefs.elems.last(), S.endPos()); 5.1735 - S.nextToken(); 5.1736 + storeEnd((JCTree)vdefs.elems.last(), token.endPos); 5.1737 + nextToken(); 5.1738 vdefs.append(variableDeclarator(mods, type, reqInit, dc)); 5.1739 } 5.1740 return vdefs; 5.1741 @@ -2187,7 +2167,7 @@ 5.1742 * ConstantDeclarator = Ident ConstantDeclaratorRest 5.1743 */ 5.1744 JCVariableDecl variableDeclarator(JCModifiers mods, JCExpression type, boolean reqInit, String dc) { 5.1745 - return variableDeclaratorRest(S.pos(), mods, type, ident(), reqInit, dc); 5.1746 + return variableDeclaratorRest(token.pos, mods, type, ident(), reqInit, dc); 5.1747 } 5.1748 5.1749 /** VariableDeclaratorRest = BracketsOpt ["=" VariableInitializer] 5.1750 @@ -2200,11 +2180,11 @@ 5.1751 boolean reqInit, String dc) { 5.1752 type = bracketsOpt(type); 5.1753 JCExpression init = null; 5.1754 - if (S.token() == EQ) { 5.1755 - S.nextToken(); 5.1756 + if (token.kind == EQ) { 5.1757 + nextToken(); 5.1758 init = variableInitializer(); 5.1759 } 5.1760 - else if (reqInit) syntaxError(S.pos(), "expected", EQ); 5.1761 + else if (reqInit) syntaxError(token.pos, "expected", EQ); 5.1762 JCVariableDecl result = 5.1763 toP(F.at(pos).VarDef(mods, name, type, init)); 5.1764 attach(result, dc); 5.1765 @@ -2214,11 +2194,11 @@ 5.1766 /** VariableDeclaratorId = Ident BracketsOpt 5.1767 */ 5.1768 JCVariableDecl variableDeclaratorId(JCModifiers mods, JCExpression type) { 5.1769 - int pos = S.pos(); 5.1770 + int pos = token.pos; 5.1771 Name name = ident(); 5.1772 if ((mods.flags & Flags.VARARGS) != 0 && 5.1773 - S.token() == LBRACKET) { 5.1774 - log.error(S.pos(), "varargs.and.old.array.syntax"); 5.1775 + token.kind == LBRACKET) { 5.1776 + log.error(token.pos, "varargs.and.old.array.syntax"); 5.1777 } 5.1778 type = bracketsOpt(type); 5.1779 return toP(F.at(pos).VarDef(mods, name, type, null)); 5.1780 @@ -2229,12 +2209,12 @@ 5.1781 List<JCTree> resources() { 5.1782 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 5.1783 defs.append(resource()); 5.1784 - while (S.token() == SEMI) { 5.1785 + while (token.kind == SEMI) { 5.1786 // All but last of multiple declarators must subsume a semicolon 5.1787 - storeEnd(defs.elems.last(), S.endPos()); 5.1788 - int semiColonPos = S.pos(); 5.1789 - S.nextToken(); 5.1790 - if (S.token() == RPAREN) { // Optional trailing semicolon 5.1791 + storeEnd(defs.elems.last(), token.endPos); 5.1792 + int semiColonPos = token.pos; 5.1793 + nextToken(); 5.1794 + if (token.kind == RPAREN) { // Optional trailing semicolon 5.1795 // after last resource 5.1796 break; 5.1797 } 5.1798 @@ -2248,7 +2228,7 @@ 5.1799 protected JCTree resource() { 5.1800 JCModifiers optFinal = optFinal(Flags.FINAL); 5.1801 JCExpression type = parseType(); 5.1802 - int pos = S.pos(); 5.1803 + int pos = token.pos; 5.1804 Name ident = ident(); 5.1805 return variableDeclaratorRest(pos, optFinal, type, ident, true, null); 5.1806 } 5.1807 @@ -2256,54 +2236,61 @@ 5.1808 /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration} 5.1809 */ 5.1810 public JCTree.JCCompilationUnit parseCompilationUnit() { 5.1811 - int pos = S.pos(); 5.1812 + Token firstToken = token; 5.1813 JCExpression pid = null; 5.1814 - String dc = S.docComment(); 5.1815 JCModifiers mods = null; 5.1816 + boolean consumedToplevelDoc = false; 5.1817 + boolean seenImport = false; 5.1818 + boolean seenPackage = false; 5.1819 List<JCAnnotation> packageAnnotations = List.nil(); 5.1820 - if (S.token() == MONKEYS_AT) 5.1821 + if (token.kind == MONKEYS_AT) 5.1822 mods = modifiersOpt(); 5.1823 5.1824 - if (S.token() == PACKAGE) { 5.1825 + if (token.kind == PACKAGE) { 5.1826 + seenPackage = true; 5.1827 if (mods != null) { 5.1828 checkNoMods(mods.flags); 5.1829 packageAnnotations = mods.annotations; 5.1830 mods = null; 5.1831 } 5.1832 - S.nextToken(); 5.1833 + nextToken(); 5.1834 pid = qualident(); 5.1835 accept(SEMI); 5.1836 } 5.1837 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 5.1838 boolean checkForImports = true; 5.1839 - while (S.token() != EOF) { 5.1840 - if (S.pos() <= errorEndPos) { 5.1841 + boolean firstTypeDecl = true; 5.1842 + while (token.kind != EOF) { 5.1843 + if (token.pos <= errorEndPos) { 5.1844 // error recovery 5.1845 skip(checkForImports, false, false, false); 5.1846 - if (S.token() == EOF) 5.1847 + if (token.kind == EOF) 5.1848 break; 5.1849 } 5.1850 - if (checkForImports && mods == null && S.token() == IMPORT) { 5.1851 + if (checkForImports && mods == null && token.kind == IMPORT) { 5.1852 + seenImport = true; 5.1853 defs.append(importDeclaration()); 5.1854 } else { 5.1855 - JCTree def = typeDeclaration(mods); 5.1856 - if (keepDocComments && dc != null && docComments.get(def) == dc) { 5.1857 - // If the first type declaration has consumed the first doc 5.1858 - // comment, then don't use it for the top level comment as well. 5.1859 - dc = null; 5.1860 + String docComment = token.docComment; 5.1861 + if (firstTypeDecl && !seenImport && !seenPackage) { 5.1862 + docComment = firstToken.docComment; 5.1863 + consumedToplevelDoc = true; 5.1864 } 5.1865 + JCTree def = typeDeclaration(mods, docComment); 5.1866 if (def instanceof JCExpressionStatement) 5.1867 def = ((JCExpressionStatement)def).expr; 5.1868 defs.append(def); 5.1869 if (def instanceof JCClassDecl) 5.1870 checkForImports = false; 5.1871 mods = null; 5.1872 + firstTypeDecl = false; 5.1873 } 5.1874 } 5.1875 - JCTree.JCCompilationUnit toplevel = F.at(pos).TopLevel(packageAnnotations, pid, defs.toList()); 5.1876 - attach(toplevel, dc); 5.1877 + JCTree.JCCompilationUnit toplevel = F.at(firstToken.pos).TopLevel(packageAnnotations, pid, defs.toList()); 5.1878 + if (!consumedToplevelDoc) 5.1879 + attach(toplevel, firstToken.docComment); 5.1880 if (defs.elems.isEmpty()) 5.1881 - storeEnd(toplevel, S.prevEndPos()); 5.1882 + storeEnd(toplevel, S.prevToken().endPos); 5.1883 if (keepDocComments) 5.1884 toplevel.docComments = docComments; 5.1885 if (keepLineMap) 5.1886 @@ -2314,26 +2301,26 @@ 5.1887 /** ImportDeclaration = IMPORT [ STATIC ] Ident { "." Ident } [ "." "*" ] ";" 5.1888 */ 5.1889 JCTree importDeclaration() { 5.1890 - int pos = S.pos(); 5.1891 - S.nextToken(); 5.1892 + int pos = token.pos; 5.1893 + nextToken(); 5.1894 boolean importStatic = false; 5.1895 - if (S.token() == STATIC) { 5.1896 + if (token.kind == STATIC) { 5.1897 checkStaticImports(); 5.1898 importStatic = true; 5.1899 - S.nextToken(); 5.1900 + nextToken(); 5.1901 } 5.1902 - JCExpression pid = toP(F.at(S.pos()).Ident(ident())); 5.1903 + JCExpression pid = toP(F.at(token.pos).Ident(ident())); 5.1904 do { 5.1905 - int pos1 = S.pos(); 5.1906 + int pos1 = token.pos; 5.1907 accept(DOT); 5.1908 - if (S.token() == STAR) { 5.1909 + if (token.kind == STAR) { 5.1910 pid = to(F.at(pos1).Select(pid, names.asterisk)); 5.1911 - S.nextToken(); 5.1912 + nextToken(); 5.1913 break; 5.1914 } else { 5.1915 pid = toP(F.at(pos1).Select(pid, ident())); 5.1916 } 5.1917 - } while (S.token() == DOT); 5.1918 + } while (token.kind == DOT); 5.1919 accept(SEMI); 5.1920 return toP(F.at(pos).Import(pid, importStatic)); 5.1921 } 5.1922 @@ -2341,14 +2328,13 @@ 5.1923 /** TypeDeclaration = ClassOrInterfaceOrEnumDeclaration 5.1924 * | ";" 5.1925 */ 5.1926 - JCTree typeDeclaration(JCModifiers mods) { 5.1927 - int pos = S.pos(); 5.1928 - if (mods == null && S.token() == SEMI) { 5.1929 - S.nextToken(); 5.1930 + JCTree typeDeclaration(JCModifiers mods, String docComment) { 5.1931 + int pos = token.pos; 5.1932 + if (mods == null && token.kind == SEMI) { 5.1933 + nextToken(); 5.1934 return toP(F.at(pos).Skip()); 5.1935 } else { 5.1936 - String dc = S.docComment(); 5.1937 - return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), dc); 5.1938 + return classOrInterfaceOrEnumDeclaration(modifiersOpt(mods), docComment); 5.1939 } 5.1940 } 5.1941 5.1942 @@ -2358,19 +2344,19 @@ 5.1943 * @param dc The documentation comment for the class, or null. 5.1944 */ 5.1945 JCStatement classOrInterfaceOrEnumDeclaration(JCModifiers mods, String dc) { 5.1946 - if (S.token() == CLASS) { 5.1947 + if (token.kind == CLASS) { 5.1948 return classDeclaration(mods, dc); 5.1949 - } else if (S.token() == INTERFACE) { 5.1950 + } else if (token.kind == INTERFACE) { 5.1951 return interfaceDeclaration(mods, dc); 5.1952 } else if (allowEnums) { 5.1953 - if (S.token() == ENUM) { 5.1954 + if (token.kind == ENUM) { 5.1955 return enumDeclaration(mods, dc); 5.1956 } else { 5.1957 - int pos = S.pos(); 5.1958 + int pos = token.pos; 5.1959 List<JCTree> errs; 5.1960 - if (S.token() == IDENTIFIER) { 5.1961 + if (token.kind == IDENTIFIER) { 5.1962 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 5.1963 - setErrorEndPos(S.pos()); 5.1964 + setErrorEndPos(token.pos); 5.1965 } else { 5.1966 errs = List.<JCTree>of(mods); 5.1967 } 5.1968 @@ -2378,16 +2364,16 @@ 5.1969 CLASS, INTERFACE, ENUM))); 5.1970 } 5.1971 } else { 5.1972 - if (S.token() == ENUM) { 5.1973 - error(S.pos(), "enums.not.supported.in.source", source.name); 5.1974 + if (token.kind == ENUM) { 5.1975 + error(token.pos, "enums.not.supported.in.source", source.name); 5.1976 allowEnums = true; 5.1977 return enumDeclaration(mods, dc); 5.1978 } 5.1979 - int pos = S.pos(); 5.1980 + int pos = token.pos; 5.1981 List<JCTree> errs; 5.1982 - if (S.token() == IDENTIFIER) { 5.1983 + if (token.kind == IDENTIFIER) { 5.1984 errs = List.<JCTree>of(mods, toP(F.at(pos).Ident(ident()))); 5.1985 - setErrorEndPos(S.pos()); 5.1986 + setErrorEndPos(token.pos); 5.1987 } else { 5.1988 errs = List.<JCTree>of(mods); 5.1989 } 5.1990 @@ -2402,20 +2388,20 @@ 5.1991 * @param dc The documentation comment for the class, or null. 5.1992 */ 5.1993 JCClassDecl classDeclaration(JCModifiers mods, String dc) { 5.1994 - int pos = S.pos(); 5.1995 + int pos = token.pos; 5.1996 accept(CLASS); 5.1997 Name name = ident(); 5.1998 5.1999 List<JCTypeParameter> typarams = typeParametersOpt(); 5.2000 5.2001 JCExpression extending = null; 5.2002 - if (S.token() == EXTENDS) { 5.2003 - S.nextToken(); 5.2004 + if (token.kind == EXTENDS) { 5.2005 + nextToken(); 5.2006 extending = parseType(); 5.2007 } 5.2008 List<JCExpression> implementing = List.nil(); 5.2009 - if (S.token() == IMPLEMENTS) { 5.2010 - S.nextToken(); 5.2011 + if (token.kind == IMPLEMENTS) { 5.2012 + nextToken(); 5.2013 implementing = typeList(); 5.2014 } 5.2015 List<JCTree> defs = classOrInterfaceBody(name, false); 5.2016 @@ -2431,15 +2417,15 @@ 5.2017 * @param dc The documentation comment for the interface, or null. 5.2018 */ 5.2019 JCClassDecl interfaceDeclaration(JCModifiers mods, String dc) { 5.2020 - int pos = S.pos(); 5.2021 + int pos = token.pos; 5.2022 accept(INTERFACE); 5.2023 Name name = ident(); 5.2024 5.2025 List<JCTypeParameter> typarams = typeParametersOpt(); 5.2026 5.2027 List<JCExpression> extending = List.nil(); 5.2028 - if (S.token() == EXTENDS) { 5.2029 - S.nextToken(); 5.2030 + if (token.kind == EXTENDS) { 5.2031 + nextToken(); 5.2032 extending = typeList(); 5.2033 } 5.2034 List<JCTree> defs = classOrInterfaceBody(name, true); 5.2035 @@ -2454,13 +2440,13 @@ 5.2036 * @param dc The documentation comment for the enum, or null. 5.2037 */ 5.2038 JCClassDecl enumDeclaration(JCModifiers mods, String dc) { 5.2039 - int pos = S.pos(); 5.2040 + int pos = token.pos; 5.2041 accept(ENUM); 5.2042 Name name = ident(); 5.2043 5.2044 List<JCExpression> implementing = List.nil(); 5.2045 - if (S.token() == IMPLEMENTS) { 5.2046 - S.nextToken(); 5.2047 + if (token.kind == IMPLEMENTS) { 5.2048 + nextToken(); 5.2049 implementing = typeList(); 5.2050 } 5.2051 5.2052 @@ -2479,27 +2465,27 @@ 5.2053 List<JCTree> enumBody(Name enumName) { 5.2054 accept(LBRACE); 5.2055 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 5.2056 - if (S.token() == COMMA) { 5.2057 - S.nextToken(); 5.2058 - } else if (S.token() != RBRACE && S.token() != SEMI) { 5.2059 + if (token.kind == COMMA) { 5.2060 + nextToken(); 5.2061 + } else if (token.kind != RBRACE && token.kind != SEMI) { 5.2062 defs.append(enumeratorDeclaration(enumName)); 5.2063 - while (S.token() == COMMA) { 5.2064 - S.nextToken(); 5.2065 - if (S.token() == RBRACE || S.token() == SEMI) break; 5.2066 + while (token.kind == COMMA) { 5.2067 + nextToken(); 5.2068 + if (token.kind == RBRACE || token.kind == SEMI) break; 5.2069 defs.append(enumeratorDeclaration(enumName)); 5.2070 } 5.2071 - if (S.token() != SEMI && S.token() != RBRACE) { 5.2072 - defs.append(syntaxError(S.pos(), "expected3", 5.2073 + if (token.kind != SEMI && token.kind != RBRACE) { 5.2074 + defs.append(syntaxError(token.pos, "expected3", 5.2075 COMMA, RBRACE, SEMI)); 5.2076 - S.nextToken(); 5.2077 + nextToken(); 5.2078 } 5.2079 } 5.2080 - if (S.token() == SEMI) { 5.2081 - S.nextToken(); 5.2082 - while (S.token() != RBRACE && S.token() != EOF) { 5.2083 + if (token.kind == SEMI) { 5.2084 + nextToken(); 5.2085 + while (token.kind != RBRACE && token.kind != EOF) { 5.2086 defs.appendList(classOrInterfaceBodyDeclaration(enumName, 5.2087 false)); 5.2088 - if (S.pos() <= errorEndPos) { 5.2089 + if (token.pos <= errorEndPos) { 5.2090 // error recovery 5.2091 skip(false, true, true, false); 5.2092 } 5.2093 @@ -2512,23 +2498,22 @@ 5.2094 /** EnumeratorDeclaration = AnnotationsOpt [TypeArguments] IDENTIFIER [ Arguments ] [ "{" ClassBody "}" ] 5.2095 */ 5.2096 JCTree enumeratorDeclaration(Name enumName) { 5.2097 - String dc = S.docComment(); 5.2098 + String dc = token.docComment; 5.2099 int flags = Flags.PUBLIC|Flags.STATIC|Flags.FINAL|Flags.ENUM; 5.2100 - if (S.deprecatedFlag()) { 5.2101 + if (token.deprecatedFlag) { 5.2102 flags |= Flags.DEPRECATED; 5.2103 - S.resetDeprecatedFlag(); 5.2104 } 5.2105 - int pos = S.pos(); 5.2106 + int pos = token.pos; 5.2107 List<JCAnnotation> annotations = annotationsOpt(); 5.2108 JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations); 5.2109 List<JCExpression> typeArgs = typeArgumentsOpt(); 5.2110 - int identPos = S.pos(); 5.2111 + int identPos = token.pos; 5.2112 Name name = ident(); 5.2113 - int createPos = S.pos(); 5.2114 - List<JCExpression> args = (S.token() == LPAREN) 5.2115 + int createPos = token.pos; 5.2116 + List<JCExpression> args = (token.kind == LPAREN) 5.2117 ? arguments() : List.<JCExpression>nil(); 5.2118 JCClassDecl body = null; 5.2119 - if (S.token() == LBRACE) { 5.2120 + if (token.kind == LBRACE) { 5.2121 JCModifiers mods1 = F.at(Position.NOPOS).Modifiers(Flags.ENUM | Flags.STATIC); 5.2122 List<JCTree> defs = classOrInterfaceBody(names.empty, false); 5.2123 body = toP(F.at(identPos).AnonymousClassDef(mods1, defs)); 5.2124 @@ -2538,7 +2523,7 @@ 5.2125 JCIdent ident = F.at(identPos).Ident(enumName); 5.2126 JCNewClass create = F.at(createPos).NewClass(null, typeArgs, ident, args, body); 5.2127 if (createPos != identPos) 5.2128 - storeEnd(create, S.prevEndPos()); 5.2129 + storeEnd(create, S.prevToken().endPos); 5.2130 ident = F.at(identPos).Ident(enumName); 5.2131 JCTree result = toP(F.at(pos).VarDef(mods, name, ident, create)); 5.2132 attach(result, dc); 5.2133 @@ -2550,8 +2535,8 @@ 5.2134 List<JCExpression> typeList() { 5.2135 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 5.2136 ts.append(parseType()); 5.2137 - while (S.token() == COMMA) { 5.2138 - S.nextToken(); 5.2139 + while (token.kind == COMMA) { 5.2140 + nextToken(); 5.2141 ts.append(parseType()); 5.2142 } 5.2143 return ts.toList(); 5.2144 @@ -2562,16 +2547,16 @@ 5.2145 */ 5.2146 List<JCTree> classOrInterfaceBody(Name className, boolean isInterface) { 5.2147 accept(LBRACE); 5.2148 - if (S.pos() <= errorEndPos) { 5.2149 + if (token.pos <= errorEndPos) { 5.2150 // error recovery 5.2151 skip(false, true, false, false); 5.2152 - if (S.token() == LBRACE) 5.2153 - S.nextToken(); 5.2154 + if (token.kind == LBRACE) 5.2155 + nextToken(); 5.2156 } 5.2157 ListBuffer<JCTree> defs = new ListBuffer<JCTree>(); 5.2158 - while (S.token() != RBRACE && S.token() != EOF) { 5.2159 + while (token.kind != RBRACE && token.kind != EOF) { 5.2160 defs.appendList(classOrInterfaceBodyDeclaration(className, isInterface)); 5.2161 - if (S.pos() <= errorEndPos) { 5.2162 + if (token.pos <= errorEndPos) { 5.2163 // error recovery 5.2164 skip(false, true, true, false); 5.2165 } 5.2166 @@ -2598,23 +2583,23 @@ 5.2167 * ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" ) 5.2168 */ 5.2169 protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) { 5.2170 - if (S.token() == SEMI) { 5.2171 - S.nextToken(); 5.2172 + if (token.kind == SEMI) { 5.2173 + nextToken(); 5.2174 return List.<JCTree>nil(); 5.2175 } else { 5.2176 - String dc = S.docComment(); 5.2177 - int pos = S.pos(); 5.2178 + String dc = token.docComment; 5.2179 + int pos = token.pos; 5.2180 JCModifiers mods = modifiersOpt(); 5.2181 - if (S.token() == CLASS || 5.2182 - S.token() == INTERFACE || 5.2183 - allowEnums && S.token() == ENUM) { 5.2184 + if (token.kind == CLASS || 5.2185 + token.kind == INTERFACE || 5.2186 + allowEnums && token.kind == ENUM) { 5.2187 return List.<JCTree>of(classOrInterfaceOrEnumDeclaration(mods, dc)); 5.2188 - } else if (S.token() == LBRACE && !isInterface && 5.2189 + } else if (token.kind == LBRACE && !isInterface && 5.2190 (mods.flags & Flags.StandardFlags & ~Flags.STATIC) == 0 && 5.2191 mods.annotations.isEmpty()) { 5.2192 return List.<JCTree>of(block(pos, mods.flags)); 5.2193 } else { 5.2194 - pos = S.pos(); 5.2195 + pos = token.pos; 5.2196 List<JCTypeParameter> typarams = typeParametersOpt(); 5.2197 // if there are type parameters but no modifiers, save the start 5.2198 // position of the method in the modifiers. 5.2199 @@ -2622,26 +2607,26 @@ 5.2200 mods.pos = pos; 5.2201 storeEnd(mods, pos); 5.2202 } 5.2203 - Name name = S.name(); 5.2204 - pos = S.pos(); 5.2205 + Token tk = token; 5.2206 + pos = token.pos; 5.2207 JCExpression type; 5.2208 - boolean isVoid = S.token() == VOID; 5.2209 + boolean isVoid = token.kind == VOID; 5.2210 if (isVoid) { 5.2211 type = to(F.at(pos).TypeIdent(TypeTags.VOID)); 5.2212 - S.nextToken(); 5.2213 + nextToken(); 5.2214 } else { 5.2215 type = parseType(); 5.2216 } 5.2217 - if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 5.2218 - if (isInterface || name != className) 5.2219 + if (token.kind == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) { 5.2220 + if (isInterface || tk.name() != className) 5.2221 error(pos, "invalid.meth.decl.ret.type.req"); 5.2222 return List.of(methodDeclaratorRest( 5.2223 pos, mods, null, names.init, typarams, 5.2224 isInterface, true, dc)); 5.2225 } else { 5.2226 - pos = S.pos(); 5.2227 - name = ident(); 5.2228 - if (S.token() == LPAREN) { 5.2229 + pos = token.pos; 5.2230 + Name name = ident(); 5.2231 + if (token.kind == LPAREN) { 5.2232 return List.of(methodDeclaratorRest( 5.2233 pos, mods, type, name, typarams, 5.2234 isInterface, isVoid, dc)); 5.2235 @@ -2649,16 +2634,16 @@ 5.2236 List<JCTree> defs = 5.2237 variableDeclaratorsRest(pos, mods, type, name, isInterface, dc, 5.2238 new ListBuffer<JCTree>()).toList(); 5.2239 - storeEnd(defs.last(), S.endPos()); 5.2240 + storeEnd(defs.last(), token.endPos); 5.2241 accept(SEMI); 5.2242 return defs; 5.2243 } else { 5.2244 - pos = S.pos(); 5.2245 + pos = token.pos; 5.2246 List<JCTree> err = isVoid 5.2247 ? List.<JCTree>of(toP(F.at(pos).MethodDef(mods, name, type, typarams, 5.2248 List.<JCVariableDecl>nil(), List.<JCExpression>nil(), null, null))) 5.2249 : null; 5.2250 - return List.<JCTree>of(syntaxError(S.pos(), err, "expected", LPAREN)); 5.2251 + return List.<JCTree>of(syntaxError(token.pos, err, "expected", LPAREN)); 5.2252 } 5.2253 } 5.2254 } 5.2255 @@ -2686,27 +2671,27 @@ 5.2256 List<JCVariableDecl> params = formalParameters(); 5.2257 if (!isVoid) type = bracketsOpt(type); 5.2258 List<JCExpression> thrown = List.nil(); 5.2259 - if (S.token() == THROWS) { 5.2260 - S.nextToken(); 5.2261 + if (token.kind == THROWS) { 5.2262 + nextToken(); 5.2263 thrown = qualidentList(); 5.2264 } 5.2265 JCBlock body = null; 5.2266 JCExpression defaultValue; 5.2267 - if (S.token() == LBRACE) { 5.2268 + if (token.kind == LBRACE) { 5.2269 body = block(); 5.2270 defaultValue = null; 5.2271 } else { 5.2272 - if (S.token() == DEFAULT) { 5.2273 + if (token.kind == DEFAULT) { 5.2274 accept(DEFAULT); 5.2275 defaultValue = annotationValue(); 5.2276 } else { 5.2277 defaultValue = null; 5.2278 } 5.2279 accept(SEMI); 5.2280 - if (S.pos() <= errorEndPos) { 5.2281 + if (token.pos <= errorEndPos) { 5.2282 // error recovery 5.2283 skip(false, true, false, false); 5.2284 - if (S.token() == LBRACE) { 5.2285 + if (token.kind == LBRACE) { 5.2286 body = block(); 5.2287 } 5.2288 } 5.2289 @@ -2725,8 +2710,8 @@ 5.2290 List<JCExpression> qualidentList() { 5.2291 ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>(); 5.2292 ts.append(qualident()); 5.2293 - while (S.token() == COMMA) { 5.2294 - S.nextToken(); 5.2295 + while (token.kind == COMMA) { 5.2296 + nextToken(); 5.2297 ts.append(qualident()); 5.2298 } 5.2299 return ts.toList(); 5.2300 @@ -2735,13 +2720,13 @@ 5.2301 /** TypeParametersOpt = ["<" TypeParameter {"," TypeParameter} ">"] 5.2302 */ 5.2303 List<JCTypeParameter> typeParametersOpt() { 5.2304 - if (S.token() == LT) { 5.2305 + if (token.kind == LT) { 5.2306 checkGenerics(); 5.2307 ListBuffer<JCTypeParameter> typarams = new ListBuffer<JCTypeParameter>(); 5.2308 - S.nextToken(); 5.2309 + nextToken(); 5.2310 typarams.append(typeParameter()); 5.2311 - while (S.token() == COMMA) { 5.2312 - S.nextToken(); 5.2313 + while (token.kind == COMMA) { 5.2314 + nextToken(); 5.2315 typarams.append(typeParameter()); 5.2316 } 5.2317 accept(GT); 5.2318 @@ -2756,14 +2741,14 @@ 5.2319 * TypeVariable = Ident 5.2320 */ 5.2321 JCTypeParameter typeParameter() { 5.2322 - int pos = S.pos(); 5.2323 + int pos = token.pos; 5.2324 Name name = ident(); 5.2325 ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>(); 5.2326 - if (S.token() == EXTENDS) { 5.2327 - S.nextToken(); 5.2328 + if (token.kind == EXTENDS) { 5.2329 + nextToken(); 5.2330 bounds.append(parseType()); 5.2331 - while (S.token() == AMP) { 5.2332 - S.nextToken(); 5.2333 + while (token.kind == AMP) { 5.2334 + nextToken(); 5.2335 bounds.append(parseType()); 5.2336 } 5.2337 } 5.2338 @@ -2778,10 +2763,10 @@ 5.2339 ListBuffer<JCVariableDecl> params = new ListBuffer<JCVariableDecl>(); 5.2340 JCVariableDecl lastParam = null; 5.2341 accept(LPAREN); 5.2342 - if (S.token() != RPAREN) { 5.2343 + if (token.kind != RPAREN) { 5.2344 params.append(lastParam = formalParameter()); 5.2345 - while ((lastParam.mods.flags & Flags.VARARGS) == 0 && S.token() == COMMA) { 5.2346 - S.nextToken(); 5.2347 + while ((lastParam.mods.flags & Flags.VARARGS) == 0 && token.kind == COMMA) { 5.2348 + nextToken(); 5.2349 params.append(lastParam = formalParameter()); 5.2350 } 5.2351 } 5.2352 @@ -2802,11 +2787,11 @@ 5.2353 protected JCVariableDecl formalParameter() { 5.2354 JCModifiers mods = optFinal(Flags.PARAMETER); 5.2355 JCExpression type = parseType(); 5.2356 - if (S.token() == ELLIPSIS) { 5.2357 + if (token.kind == ELLIPSIS) { 5.2358 checkVarargs(); 5.2359 mods.flags |= Flags.VARARGS; 5.2360 - type = to(F.at(S.pos()).TypeArray(type)); 5.2361 - S.nextToken(); 5.2362 + type = to(F.at(token.pos).TypeArray(type)); 5.2363 + nextToken(); 5.2364 } 5.2365 return variableDeclaratorId(mods, type); 5.2366 } 5.2367 @@ -2849,7 +2834,7 @@ 5.2368 /** Return precedence of operator represented by token, 5.2369 * -1 if token is not a binary operator. @see TreeInfo.opPrec 5.2370 */ 5.2371 - static int prec(Token token) { 5.2372 + static int prec(TokenKind token) { 5.2373 int oc = optag(token); 5.2374 return (oc >= 0) ? TreeInfo.opPrec(oc) : -1; 5.2375 } 5.2376 @@ -2869,7 +2854,7 @@ 5.2377 /** Return operation tag of binary operator represented by token, 5.2378 * -1 if token is not a binary operator. 5.2379 */ 5.2380 - static int optag(Token token) { 5.2381 + static int optag(TokenKind token) { 5.2382 switch (token) { 5.2383 case BARBAR: 5.2384 return JCTree.OR; 5.2385 @@ -2941,7 +2926,7 @@ 5.2386 /** Return operation tag of unary operator represented by token, 5.2387 * -1 if token is not a binary operator. 5.2388 */ 5.2389 - static int unoptag(Token token) { 5.2390 + static int unoptag(TokenKind token) { 5.2391 switch (token) { 5.2392 case PLUS: 5.2393 return JCTree.POS; 5.2394 @@ -2963,7 +2948,7 @@ 5.2395 /** Return type tag of basic type represented by token, 5.2396 * -1 if token is not a basic type identifier. 5.2397 */ 5.2398 - static int typetag(Token token) { 5.2399 + static int typetag(TokenKind token) { 5.2400 switch (token) { 5.2401 case BYTE: 5.2402 return TypeTags.BYTE; 5.2403 @@ -2988,49 +2973,49 @@ 5.2404 5.2405 void checkGenerics() { 5.2406 if (!allowGenerics) { 5.2407 - error(S.pos(), "generics.not.supported.in.source", source.name); 5.2408 + error(token.pos, "generics.not.supported.in.source", source.name); 5.2409 allowGenerics = true; 5.2410 } 5.2411 } 5.2412 void checkVarargs() { 5.2413 if (!allowVarargs) { 5.2414 - error(S.pos(), "varargs.not.supported.in.source", source.name); 5.2415 + error(token.pos, "varargs.not.supported.in.source", source.name); 5.2416 allowVarargs = true; 5.2417 } 5.2418 } 5.2419 void checkForeach() { 5.2420 if (!allowForeach) { 5.2421 - error(S.pos(), "foreach.not.supported.in.source", source.name); 5.2422 + error(token.pos, "foreach.not.supported.in.source", source.name); 5.2423 allowForeach = true; 5.2424 } 5.2425 } 5.2426 void checkStaticImports() { 5.2427 if (!allowStaticImport) { 5.2428 - error(S.pos(), "static.import.not.supported.in.source", source.name); 5.2429 + error(token.pos, "static.import.not.supported.in.source", source.name); 5.2430 allowStaticImport = true; 5.2431 } 5.2432 } 5.2433 void checkAnnotations() { 5.2434 if (!allowAnnotations) { 5.2435 - error(S.pos(), "annotations.not.supported.in.source", source.name); 5.2436 + error(token.pos, "annotations.not.supported.in.source", source.name); 5.2437 allowAnnotations = true; 5.2438 } 5.2439 } 5.2440 void checkDiamond() { 5.2441 if (!allowDiamond) { 5.2442 - error(S.pos(), "diamond.not.supported.in.source", source.name); 5.2443 + error(token.pos, "diamond.not.supported.in.source", source.name); 5.2444 allowDiamond = true; 5.2445 } 5.2446 } 5.2447 void checkMulticatch() { 5.2448 if (!allowMulticatch) { 5.2449 - error(S.pos(), "multicatch.not.supported.in.source", source.name); 5.2450 + error(token.pos, "multicatch.not.supported.in.source", source.name); 5.2451 allowMulticatch = true; 5.2452 } 5.2453 } 5.2454 void checkTryWithResources() { 5.2455 if (!allowTWR) { 5.2456 - error(S.pos(), "try.with.resources.not.supported.in.source", source.name); 5.2457 + error(token.pos, "try.with.resources.not.supported.in.source", source.name); 5.2458 allowTWR = true; 5.2459 } 5.2460 }
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 6.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavadocTokenizer.java Mon Oct 24 13:00:20 2011 +0100 6.3 @@ -0,0 +1,412 @@ 6.4 +/* 6.5 + * Copyright (c) 2004, 2011, Oracle and/or its affiliates. All rights reserved. 6.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 6.7 + * 6.8 + * This code is free software; you can redistribute it and/or modify it 6.9 + * under the terms of the GNU General Public License version 2 only, as 6.10 + * published by the Free Software Foundation. Oracle designates this 6.11 + * particular file as subject to the "Classpath" exception as provided 6.12 + * by Oracle in the LICENSE file that accompanied this code. 6.13 + * 6.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 6.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 6.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 6.17 + * version 2 for more details (a copy is included in the LICENSE file that 6.18 + * accompanied this code). 6.19 + * 6.20 + * You should have received a copy of the GNU General Public License version 6.21 + * 2 along with this work; if not, write to the Free Software Foundation, 6.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 6.23 + * 6.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 6.25 + * or visit www.oracle.com if you need additional information or have any 6.26 + * questions. 6.27 + */ 6.28 + 6.29 +package com.sun.tools.javac.parser; 6.30 + 6.31 +import com.sun.tools.javac.file.JavacFileManager; 6.32 +import com.sun.tools.javac.parser.Tokens.Token; 6.33 +import com.sun.tools.javac.util.*; 6.34 + 6.35 +import java.nio.*; 6.36 + 6.37 +import static com.sun.tools.javac.util.LayoutCharacters.*; 6.38 + 6.39 +/** An extension to the base lexical analyzer that captures 6.40 + * and processes the contents of doc comments. It does so by 6.41 + * translating Unicode escape sequences and by stripping the 6.42 + * leading whitespace and starts from each line of the comment. 6.43 + * 6.44 + * <p><b>This is NOT part of any supported API. 6.45 + * If you write code that depends on this, you do so at your own risk. 6.46 + * This code and its internal interfaces are subject to change or 6.47 + * deletion without notice.</b> 6.48 + */ 6.49 +public class JavadocTokenizer extends JavaTokenizer { 6.50 + 6.51 + /** Create a scanner from the input buffer. buffer must implement 6.52 + * array() and compact(), and remaining() must be less than limit(). 6.53 + */ 6.54 + protected JavadocTokenizer(ScannerFactory fac, CharBuffer buffer) { 6.55 + super(fac, buffer); 6.56 + } 6.57 + 6.58 + /** Create a scanner from the input array. The array must have at 6.59 + * least a single character of extra space. 6.60 + */ 6.61 + protected JavadocTokenizer(ScannerFactory fac, char[] input, int inputLength) { 6.62 + super(fac, input, inputLength); 6.63 + } 6.64 + 6.65 + /** The comment input buffer, index of next chacter to be read, 6.66 + * index of one past last character in buffer. 6.67 + */ 6.68 + private char[] buf; 6.69 + private int bp; 6.70 + private int buflen; 6.71 + 6.72 + /** The current character. 6.73 + */ 6.74 + private char ch; 6.75 + 6.76 + /** The column number position of the current character. 6.77 + */ 6.78 + private int col; 6.79 + 6.80 + /** The buffer index of the last converted Unicode character 6.81 + */ 6.82 + private int unicodeConversionBp = 0; 6.83 + 6.84 + /** 6.85 + * Buffer for doc comment. 6.86 + */ 6.87 + private char[] docCommentBuffer = new char[1024]; 6.88 + 6.89 + /** 6.90 + * Number of characters in doc comment buffer. 6.91 + */ 6.92 + private int docCommentCount; 6.93 + 6.94 + /** 6.95 + * Translated and stripped contents of doc comment 6.96 + */ 6.97 + private String docComment = null; 6.98 + 6.99 + 6.100 + /** Unconditionally expand the comment buffer. 6.101 + */ 6.102 + private void expandCommentBuffer() { 6.103 + char[] newBuffer = new char[docCommentBuffer.length * 2]; 6.104 + System.arraycopy(docCommentBuffer, 0, newBuffer, 6.105 + 0, docCommentBuffer.length); 6.106 + docCommentBuffer = newBuffer; 6.107 + } 6.108 + 6.109 + /** Convert an ASCII digit from its base (8, 10, or 16) 6.110 + * to its value. 6.111 + */ 6.112 + private int digit(int base) { 6.113 + char c = ch; 6.114 + int result = Character.digit(c, base); 6.115 + if (result >= 0 && c > 0x7f) { 6.116 + ch = "0123456789abcdef".charAt(result); 6.117 + } 6.118 + return result; 6.119 + } 6.120 + 6.121 + /** Convert Unicode escape; bp points to initial '\' character 6.122 + * (Spec 3.3). 6.123 + */ 6.124 + private void convertUnicode() { 6.125 + if (ch == '\\' && unicodeConversionBp != bp) { 6.126 + bp++; ch = buf[bp]; col++; 6.127 + if (ch == 'u') { 6.128 + do { 6.129 + bp++; ch = buf[bp]; col++; 6.130 + } while (ch == 'u'); 6.131 + int limit = bp + 3; 6.132 + if (limit < buflen) { 6.133 + int d = digit(16); 6.134 + int code = d; 6.135 + while (bp < limit && d >= 0) { 6.136 + bp++; ch = buf[bp]; col++; 6.137 + d = digit(16); 6.138 + code = (code << 4) + d; 6.139 + } 6.140 + if (d >= 0) { 6.141 + ch = (char)code; 6.142 + unicodeConversionBp = bp; 6.143 + return; 6.144 + } 6.145 + } 6.146 + // "illegal.Unicode.esc", reported by base scanner 6.147 + } else { 6.148 + bp--; 6.149 + ch = '\\'; 6.150 + col--; 6.151 + } 6.152 + } 6.153 + } 6.154 + 6.155 + 6.156 + /** Read next character. 6.157 + */ 6.158 + private void scanChar() { 6.159 + bp++; 6.160 + ch = buf[bp]; 6.161 + switch (ch) { 6.162 + case '\r': // return 6.163 + col = 0; 6.164 + break; 6.165 + case '\n': // newline 6.166 + if (bp == 0 || buf[bp-1] != '\r') { 6.167 + col = 0; 6.168 + } 6.169 + break; 6.170 + case '\t': // tab 6.171 + col = (col / TabInc * TabInc) + TabInc; 6.172 + break; 6.173 + case '\\': // possible Unicode 6.174 + col++; 6.175 + convertUnicode(); 6.176 + break; 6.177 + default: 6.178 + col++; 6.179 + break; 6.180 + } 6.181 + } 6.182 + 6.183 + @Override 6.184 + public Token readToken() { 6.185 + docComment = null; 6.186 + Token tk = super.readToken(); 6.187 + tk.docComment = docComment; 6.188 + return tk; 6.189 + } 6.190 + 6.191 + /** 6.192 + * Read next character in doc comment, skipping over double '\' characters. 6.193 + * If a double '\' is skipped, put in the buffer and update buffer count. 6.194 + */ 6.195 + private void scanDocCommentChar() { 6.196 + scanChar(); 6.197 + if (ch == '\\') { 6.198 + if (buf[bp+1] == '\\' && unicodeConversionBp != bp) { 6.199 + if (docCommentCount == docCommentBuffer.length) 6.200 + expandCommentBuffer(); 6.201 + docCommentBuffer[docCommentCount++] = ch; 6.202 + bp++; col++; 6.203 + } else { 6.204 + convertUnicode(); 6.205 + } 6.206 + } 6.207 + } 6.208 + 6.209 + /** 6.210 + * Process a doc comment and make the string content available. 6.211 + * Strips leading whitespace and stars. 6.212 + */ 6.213 + @SuppressWarnings("fallthrough") 6.214 + protected void processComment(int pos, int endPos, CommentStyle style) { 6.215 + if (style != CommentStyle.JAVADOC) { 6.216 + return; 6.217 + } 6.218 + 6.219 + buf = reader.getRawCharacters(pos, endPos); 6.220 + buflen = buf.length; 6.221 + bp = 0; 6.222 + col = 0; 6.223 + 6.224 + docCommentCount = 0; 6.225 + 6.226 + boolean firstLine = true; 6.227 + 6.228 + // Skip over first slash 6.229 + scanDocCommentChar(); 6.230 + // Skip over first star 6.231 + scanDocCommentChar(); 6.232 + 6.233 + // consume any number of stars 6.234 + while (bp < buflen && ch == '*') { 6.235 + scanDocCommentChar(); 6.236 + } 6.237 + // is the comment in the form /**/, /***/, /****/, etc. ? 6.238 + if (bp < buflen && ch == '/') { 6.239 + docComment = ""; 6.240 + return; 6.241 + } 6.242 + 6.243 + // skip a newline on the first line of the comment. 6.244 + if (bp < buflen) { 6.245 + if (ch == LF) { 6.246 + scanDocCommentChar(); 6.247 + firstLine = false; 6.248 + } else if (ch == CR) { 6.249 + scanDocCommentChar(); 6.250 + if (ch == LF) { 6.251 + scanDocCommentChar(); 6.252 + firstLine = false; 6.253 + } 6.254 + } 6.255 + } 6.256 + 6.257 + outerLoop: 6.258 + 6.259 + // The outerLoop processes the doc comment, looping once 6.260 + // for each line. For each line, it first strips off 6.261 + // whitespace, then it consumes any stars, then it 6.262 + // puts the rest of the line into our buffer. 6.263 + while (bp < buflen) { 6.264 + 6.265 + // The wsLoop consumes whitespace from the beginning 6.266 + // of each line. 6.267 + wsLoop: 6.268 + 6.269 + while (bp < buflen) { 6.270 + switch(ch) { 6.271 + case ' ': 6.272 + scanDocCommentChar(); 6.273 + break; 6.274 + case '\t': 6.275 + col = ((col - 1) / TabInc * TabInc) + TabInc; 6.276 + scanDocCommentChar(); 6.277 + break; 6.278 + case FF: 6.279 + col = 0; 6.280 + scanDocCommentChar(); 6.281 + break; 6.282 +// Treat newline at beginning of line (blank line, no star) 6.283 +// as comment text. Old Javadoc compatibility requires this. 6.284 +/*---------------------------------* 6.285 + case CR: // (Spec 3.4) 6.286 + scanDocCommentChar(); 6.287 + if (ch == LF) { 6.288 + col = 0; 6.289 + scanDocCommentChar(); 6.290 + } 6.291 + break; 6.292 + case LF: // (Spec 3.4) 6.293 + scanDocCommentChar(); 6.294 + break; 6.295 +*---------------------------------*/ 6.296 + default: 6.297 + // we've seen something that isn't whitespace; 6.298 + // jump out. 6.299 + break wsLoop; 6.300 + } 6.301 + } 6.302 + 6.303 + // Are there stars here? If so, consume them all 6.304 + // and check for the end of comment. 6.305 + if (ch == '*') { 6.306 + // skip all of the stars 6.307 + do { 6.308 + scanDocCommentChar(); 6.309 + } while (ch == '*'); 6.310 + 6.311 + // check for the closing slash. 6.312 + if (ch == '/') { 6.313 + // We're done with the doc comment 6.314 + // scanChar() and breakout. 6.315 + break outerLoop; 6.316 + } 6.317 + } else if (! firstLine) { 6.318 + //The current line does not begin with a '*' so we will indent it. 6.319 + for (int i = 1; i < col; i++) { 6.320 + if (docCommentCount == docCommentBuffer.length) 6.321 + expandCommentBuffer(); 6.322 + docCommentBuffer[docCommentCount++] = ' '; 6.323 + } 6.324 + } 6.325 + 6.326 + // The textLoop processes the rest of the characters 6.327 + // on the line, adding them to our buffer. 6.328 + textLoop: 6.329 + while (bp < buflen) { 6.330 + switch (ch) { 6.331 + case '*': 6.332 + // Is this just a star? Or is this the 6.333 + // end of a comment? 6.334 + scanDocCommentChar(); 6.335 + if (ch == '/') { 6.336 + // This is the end of the comment, 6.337 + // set ch and return our buffer. 6.338 + break outerLoop; 6.339 + } 6.340 + // This is just an ordinary star. Add it to 6.341 + // the buffer. 6.342 + if (docCommentCount == docCommentBuffer.length) 6.343 + expandCommentBuffer(); 6.344 + docCommentBuffer[docCommentCount++] = '*'; 6.345 + break; 6.346 + case ' ': 6.347 + case '\t': 6.348 + if (docCommentCount == docCommentBuffer.length) 6.349 + expandCommentBuffer(); 6.350 + docCommentBuffer[docCommentCount++] = ch; 6.351 + scanDocCommentChar(); 6.352 + break; 6.353 + case FF: 6.354 + scanDocCommentChar(); 6.355 + break textLoop; // treat as end of line 6.356 + case CR: // (Spec 3.4) 6.357 + scanDocCommentChar(); 6.358 + if (ch != LF) { 6.359 + // Canonicalize CR-only line terminator to LF 6.360 + if (docCommentCount == docCommentBuffer.length) 6.361 + expandCommentBuffer(); 6.362 + docCommentBuffer[docCommentCount++] = (char)LF; 6.363 + break textLoop; 6.364 + } 6.365 + /* fall through to LF case */ 6.366 + case LF: // (Spec 3.4) 6.367 + // We've seen a newline. Add it to our 6.368 + // buffer and break out of this loop, 6.369 + // starting fresh on a new line. 6.370 + if (docCommentCount == docCommentBuffer.length) 6.371 + expandCommentBuffer(); 6.372 + docCommentBuffer[docCommentCount++] = ch; 6.373 + scanDocCommentChar(); 6.374 + break textLoop; 6.375 + default: 6.376 + // Add the character to our buffer. 6.377 + if (docCommentCount == docCommentBuffer.length) 6.378 + expandCommentBuffer(); 6.379 + docCommentBuffer[docCommentCount++] = ch; 6.380 + scanDocCommentChar(); 6.381 + } 6.382 + } // end textLoop 6.383 + firstLine = false; 6.384 + } // end outerLoop 6.385 + 6.386 + if (docCommentCount > 0) { 6.387 + int i = docCommentCount - 1; 6.388 + trailLoop: 6.389 + while (i > -1) { 6.390 + switch (docCommentBuffer[i]) { 6.391 + case '*': 6.392 + i--; 6.393 + break; 6.394 + default: 6.395 + break trailLoop; 6.396 + } 6.397 + } 6.398 + docCommentCount = i + 1; 6.399 + 6.400 + // Store the text of the doc comment 6.401 + docComment = new String(docCommentBuffer, 0 , docCommentCount); 6.402 + } else { 6.403 + docComment = ""; 6.404 + } 6.405 + } 6.406 + 6.407 + /** Build a map for translating between line numbers and 6.408 + * positions in the input. 6.409 + * 6.410 + * @return a LineMap */ 6.411 + public Position.LineMap getLineMap() { 6.412 + char[] buf = reader.getRawCharacters(); 6.413 + return Position.makeLineMap(buf, buf.length, true); 6.414 + } 6.415 +}
7.1 --- a/src/share/classes/com/sun/tools/javac/parser/Keywords.java Fri Oct 21 14:14:29 2011 -0700 7.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 7.3 @@ -1,98 +0,0 @@ 7.4 -/* 7.5 - * Copyright (c) 2002, 2010, Oracle and/or its affiliates. All rights reserved. 7.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 7.7 - * 7.8 - * This code is free software; you can redistribute it and/or modify it 7.9 - * under the terms of the GNU General Public License version 2 only, as 7.10 - * published by the Free Software Foundation. Oracle designates this 7.11 - * particular file as subject to the "Classpath" exception as provided 7.12 - * by Oracle in the LICENSE file that accompanied this code. 7.13 - * 7.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 7.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 7.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 7.17 - * version 2 for more details (a copy is included in the LICENSE file that 7.18 - * accompanied this code). 7.19 - * 7.20 - * You should have received a copy of the GNU General Public License version 7.21 - * 2 along with this work; if not, write to the Free Software Foundation, 7.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 7.23 - * 7.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 7.25 - * or visit www.oracle.com if you need additional information or have any 7.26 - * questions. 7.27 - */ 7.28 - 7.29 -package com.sun.tools.javac.parser; 7.30 - 7.31 -import com.sun.tools.javac.util.Context; 7.32 -import com.sun.tools.javac.util.Log; 7.33 -import com.sun.tools.javac.util.Name; 7.34 -import com.sun.tools.javac.util.Names; 7.35 - 7.36 -import static com.sun.tools.javac.parser.Token.*; 7.37 - 7.38 -/** 7.39 - * Map from Name to Token and Token to String. 7.40 - * 7.41 - * <p><b>This is NOT part of any supported API. 7.42 - * If you write code that depends on this, you do so at your own risk. 7.43 - * This code and its internal interfaces are subject to change or 7.44 - * deletion without notice.</b> 7.45 - */ 7.46 -public class Keywords { 7.47 - public static final Context.Key<Keywords> keywordsKey = 7.48 - new Context.Key<Keywords>(); 7.49 - 7.50 - public static Keywords instance(Context context) { 7.51 - Keywords instance = context.get(keywordsKey); 7.52 - if (instance == null) 7.53 - instance = new Keywords(context); 7.54 - return instance; 7.55 - } 7.56 - 7.57 - private final Names names; 7.58 - 7.59 - protected Keywords(Context context) { 7.60 - context.put(keywordsKey, this); 7.61 - names = Names.instance(context); 7.62 - 7.63 - for (Token t : Token.values()) { 7.64 - if (t.name != null) 7.65 - enterKeyword(t.name, t); 7.66 - else 7.67 - tokenName[t.ordinal()] = null; 7.68 - } 7.69 - 7.70 - key = new Token[maxKey+1]; 7.71 - for (int i = 0; i <= maxKey; i++) key[i] = IDENTIFIER; 7.72 - for (Token t : Token.values()) { 7.73 - if (t.name != null) 7.74 - key[tokenName[t.ordinal()].getIndex()] = t; 7.75 - } 7.76 - } 7.77 - 7.78 - 7.79 - public Token key(Name name) { 7.80 - return (name.getIndex() > maxKey) ? IDENTIFIER : key[name.getIndex()]; 7.81 - } 7.82 - 7.83 - /** 7.84 - * Keyword array. Maps name indices to Token. 7.85 - */ 7.86 - private final Token[] key; 7.87 - 7.88 - /** The number of the last entered keyword. 7.89 - */ 7.90 - private int maxKey = 0; 7.91 - 7.92 - /** The names of all tokens. 7.93 - */ 7.94 - private Name[] tokenName = new Name[Token.values().length]; 7.95 - 7.96 - private void enterKeyword(String s, Token token) { 7.97 - Name n = names.fromString(s); 7.98 - tokenName[token.ordinal()] = n; 7.99 - if (n.getIndex() > maxKey) maxKey = n.getIndex(); 7.100 - } 7.101 -}
8.1 --- a/src/share/classes/com/sun/tools/javac/parser/Lexer.java Fri Oct 21 14:14:29 2011 -0700 8.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Lexer.java Mon Oct 24 13:00:20 2011 +0100 8.3 @@ -25,7 +25,7 @@ 8.4 8.5 package com.sun.tools.javac.parser; 8.6 8.7 -import com.sun.tools.javac.util.*; 8.8 +import com.sun.tools.javac.parser.Tokens.*; 8.9 import com.sun.tools.javac.util.Position.LineMap; 8.10 8.11 /** 8.12 @@ -40,22 +40,26 @@ 8.13 public interface Lexer { 8.14 8.15 /** 8.16 - * Has a @deprecated been encountered in last doc comment? 8.17 - * This needs to be reset by client with resetDeprecatedFlag. 8.18 + * Consume the next token. 8.19 */ 8.20 - boolean deprecatedFlag(); 8.21 - 8.22 - void resetDeprecatedFlag(); 8.23 + void nextToken(); 8.24 8.25 /** 8.26 - * Returns the documentation string of the current token. 8.27 + * Return current token. 8.28 */ 8.29 - String docComment(); 8.30 + Token token(); 8.31 8.32 /** 8.33 - * Return the last character position of the current token. 8.34 + * Return the last character position of the previous token. 8.35 */ 8.36 - int endPos(); 8.37 + Token prevToken(); 8.38 + 8.39 + /** 8.40 + * Splits the current token in two and return the first (splitted) token. 8.41 + * For instance '<<<' is splitted into two tokens '<' and '<<' respectively, 8.42 + * and the latter is returned. 8.43 + */ 8.44 + Token split(); 8.45 8.46 /** 8.47 * Return the position where a lexical error occurred; 8.48 @@ -74,69 +78,4 @@ 8.49 * @return a LineMap 8.50 */ 8.51 LineMap getLineMap(); 8.52 - 8.53 - /** 8.54 - * Returns a copy of the input buffer, up to its inputLength. 8.55 - * Unicode escape sequences are not translated. 8.56 - */ 8.57 - char[] getRawCharacters(); 8.58 - 8.59 - /** 8.60 - * Returns a copy of a character array subset of the input buffer. 8.61 - * The returned array begins at the <code>beginIndex</code> and 8.62 - * extends to the character at index <code>endIndex - 1</code>. 8.63 - * Thus the length of the substring is <code>endIndex-beginIndex</code>. 8.64 - * This behavior is like 8.65 - * <code>String.substring(beginIndex, endIndex)</code>. 8.66 - * Unicode escape sequences are not translated. 8.67 - * 8.68 - * @param beginIndex the beginning index, inclusive. 8.69 - * @param endIndex the ending index, exclusive. 8.70 - * @throws IndexOutOfBounds if either offset is outside of the 8.71 - * array bounds 8.72 - */ 8.73 - char[] getRawCharacters(int beginIndex, int endIndex); 8.74 - 8.75 - /** 8.76 - * Return the name of an identifier or token for the current token. 8.77 - */ 8.78 - Name name(); 8.79 - 8.80 - /** 8.81 - * Read token. 8.82 - */ 8.83 - void nextToken(); 8.84 - 8.85 - /** 8.86 - * Return the current token's position: a 0-based 8.87 - * offset from beginning of the raw input stream 8.88 - * (before unicode translation) 8.89 - */ 8.90 - int pos(); 8.91 - 8.92 - /** 8.93 - * Return the last character position of the previous token. 8.94 - */ 8.95 - int prevEndPos(); 8.96 - 8.97 - /** 8.98 - * Return the radix of a numeric literal token. 8.99 - */ 8.100 - int radix(); 8.101 - 8.102 - /** 8.103 - * The value of a literal token, recorded as a string. 8.104 - * For integers, leading 0x and 'l' suffixes are suppressed. 8.105 - */ 8.106 - String stringVal(); 8.107 - 8.108 - /** 8.109 - * Return the current token, set by nextToken(). 8.110 - */ 8.111 - Token token(); 8.112 - 8.113 - /** 8.114 - * Sets the current token. 8.115 - */ 8.116 - void token(Token token); 8.117 }
9.1 --- a/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Fri Oct 21 14:14:29 2011 -0700 9.2 +++ b/src/share/classes/com/sun/tools/javac/parser/ParserFactory.java Mon Oct 24 13:00:20 2011 +0100 9.3 @@ -55,7 +55,7 @@ 9.4 9.5 final TreeMaker F; 9.6 final Log log; 9.7 - final Keywords keywords; 9.8 + final Tokens tokens; 9.9 final Source source; 9.10 final Names names; 9.11 final Options options; 9.12 @@ -67,7 +67,7 @@ 9.13 this.F = TreeMaker.instance(context); 9.14 this.log = Log.instance(context); 9.15 this.names = Names.instance(context); 9.16 - this.keywords = Keywords.instance(context); 9.17 + this.tokens = Tokens.instance(context); 9.18 this.source = Source.instance(context); 9.19 this.options = Options.instance(context); 9.20 this.scannerFactory = ScannerFactory.instance(context);
10.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java Fri Oct 21 14:14:29 2011 -0700 10.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java Mon Oct 24 13:00:20 2011 +0100 10.3 @@ -27,13 +27,11 @@ 10.4 10.5 import java.nio.*; 10.6 10.7 -import com.sun.tools.javac.code.Source; 10.8 -import com.sun.tools.javac.file.JavacFileManager; 10.9 import com.sun.tools.javac.util.*; 10.10 +import com.sun.tools.javac.util.Position.LineMap; 10.11 +import com.sun.tools.javac.parser.JavaTokenizer.*; 10.12 10.13 - 10.14 -import static com.sun.tools.javac.parser.Token.*; 10.15 -import static com.sun.tools.javac.util.LayoutCharacters.*; 10.16 +import static com.sun.tools.javac.parser.Tokens.*; 10.17 10.18 /** The lexical analyzer maps an input stream consisting of 10.19 * ASCII characters and Unicode escapes into a token sequence. 10.20 @@ -45,119 +43,17 @@ 10.21 */ 10.22 public class Scanner implements Lexer { 10.23 10.24 - private static boolean scannerDebug = false; 10.25 - 10.26 - /* Output variables; set by nextToken(): 10.27 - */ 10.28 + private Tokens tokens; 10.29 10.30 /** The token, set by nextToken(). 10.31 */ 10.32 private Token token; 10.33 10.34 - /** Allow hex floating-point literals. 10.35 + /** The previous token, set by nextToken(). 10.36 */ 10.37 - private boolean allowHexFloats; 10.38 + private Token prevToken; 10.39 10.40 - /** Allow binary literals. 10.41 - */ 10.42 - private boolean allowBinaryLiterals; 10.43 - 10.44 - /** Allow underscores in literals. 10.45 - */ 10.46 - private boolean allowUnderscoresInLiterals; 10.47 - 10.48 - /** The source language setting. 10.49 - */ 10.50 - private Source source; 10.51 - 10.52 - /** The token's position, 0-based offset from beginning of text. 10.53 - */ 10.54 - private int pos; 10.55 - 10.56 - /** Character position just after the last character of the token. 10.57 - */ 10.58 - private int endPos; 10.59 - 10.60 - /** The last character position of the previous token. 10.61 - */ 10.62 - private int prevEndPos; 10.63 - 10.64 - /** The position where a lexical error occurred; 10.65 - */ 10.66 - private int errPos = Position.NOPOS; 10.67 - 10.68 - /** The name of an identifier or token: 10.69 - */ 10.70 - private Name name; 10.71 - 10.72 - /** The radix of a numeric literal token. 10.73 - */ 10.74 - private int radix; 10.75 - 10.76 - /** Has a @deprecated been encountered in last doc comment? 10.77 - * this needs to be reset by client. 10.78 - */ 10.79 - protected boolean deprecatedFlag = false; 10.80 - 10.81 - /** A character buffer for literals. 10.82 - */ 10.83 - private char[] sbuf = new char[128]; 10.84 - private int sp; 10.85 - 10.86 - /** The input buffer, index of next chacter to be read, 10.87 - * index of one past last character in buffer. 10.88 - */ 10.89 - private char[] buf; 10.90 - private int bp; 10.91 - private int buflen; 10.92 - private int eofPos; 10.93 - 10.94 - /** The current character. 10.95 - */ 10.96 - private char ch; 10.97 - 10.98 - /** The buffer index of the last converted unicode character 10.99 - */ 10.100 - private int unicodeConversionBp = -1; 10.101 - 10.102 - /** The log to be used for error reporting. 10.103 - */ 10.104 - private final Log log; 10.105 - 10.106 - /** The name table. */ 10.107 - private final Names names; 10.108 - 10.109 - /** The keyword table. */ 10.110 - private final Keywords keywords; 10.111 - 10.112 - /** Common code for constructors. */ 10.113 - private Scanner(ScannerFactory fac) { 10.114 - log = fac.log; 10.115 - names = fac.names; 10.116 - keywords = fac.keywords; 10.117 - source = fac.source; 10.118 - allowBinaryLiterals = source.allowBinaryLiterals(); 10.119 - allowHexFloats = source.allowHexFloats(); 10.120 - allowUnderscoresInLiterals = source.allowUnderscoresInLiterals(); 10.121 - } 10.122 - 10.123 - private static final boolean hexFloatsWork = hexFloatsWork(); 10.124 - private static boolean hexFloatsWork() { 10.125 - try { 10.126 - Float.valueOf("0x1.0p1"); 10.127 - return true; 10.128 - } catch (NumberFormatException ex) { 10.129 - return false; 10.130 - } 10.131 - } 10.132 - 10.133 - /** Create a scanner from the input buffer. buffer must implement 10.134 - * array() and compact(), and remaining() must be less than limit(). 10.135 - */ 10.136 - protected Scanner(ScannerFactory fac, CharBuffer buffer) { 10.137 - this(fac, JavacFileManager.toArray(buffer), buffer.limit()); 10.138 - } 10.139 - 10.140 + private JavaTokenizer tokenizer; 10.141 /** 10.142 * Create a scanner from the input array. This method might 10.143 * modify the array. To avoid copying the input array, ensure 10.144 @@ -169,972 +65,49 @@ 10.145 * @param inputLength the size of the input. 10.146 * Must be positive and less than or equal to input.length. 10.147 */ 10.148 - protected Scanner(ScannerFactory fac, char[] input, int inputLength) { 10.149 - this(fac); 10.150 - eofPos = inputLength; 10.151 - if (inputLength == input.length) { 10.152 - if (input.length > 0 && Character.isWhitespace(input[input.length - 1])) { 10.153 - inputLength--; 10.154 - } else { 10.155 - char[] newInput = new char[inputLength + 1]; 10.156 - System.arraycopy(input, 0, newInput, 0, input.length); 10.157 - input = newInput; 10.158 - } 10.159 - } 10.160 - buf = input; 10.161 - buflen = inputLength; 10.162 - buf[buflen] = EOI; 10.163 - bp = -1; 10.164 - scanChar(); 10.165 + protected Scanner(ScannerFactory fac, CharBuffer buf) { 10.166 + this(fac, new JavaTokenizer(fac, buf)); 10.167 } 10.168 10.169 - /** Report an error at the given position using the provided arguments. 10.170 - */ 10.171 - private void lexError(int pos, String key, Object... args) { 10.172 - log.error(pos, key, args); 10.173 - token = ERROR; 10.174 - errPos = pos; 10.175 + protected Scanner(ScannerFactory fac, char[] buf, int inputLength) { 10.176 + this(fac, new JavaTokenizer(fac, buf, inputLength)); 10.177 } 10.178 10.179 - /** Report an error at the current token position using the provided 10.180 - * arguments. 10.181 - */ 10.182 - private void lexError(String key, Object... args) { 10.183 - lexError(pos, key, args); 10.184 + protected Scanner(ScannerFactory fac, JavaTokenizer tokenizer) { 10.185 + this.tokenizer = tokenizer; 10.186 + tokens = fac.tokens; 10.187 + token = prevToken = DUMMY; 10.188 } 10.189 10.190 - /** Convert an ASCII digit from its base (8, 10, or 16) 10.191 - * to its value. 10.192 - */ 10.193 - private int digit(int base) { 10.194 - char c = ch; 10.195 - int result = Character.digit(c, base); 10.196 - if (result >= 0 && c > 0x7f) { 10.197 - lexError(pos+1, "illegal.nonascii.digit"); 10.198 - ch = "0123456789abcdef".charAt(result); 10.199 - } 10.200 - return result; 10.201 - } 10.202 - 10.203 - /** Convert unicode escape; bp points to initial '\' character 10.204 - * (Spec 3.3). 10.205 - */ 10.206 - private void convertUnicode() { 10.207 - if (ch == '\\' && unicodeConversionBp != bp) { 10.208 - bp++; ch = buf[bp]; 10.209 - if (ch == 'u') { 10.210 - do { 10.211 - bp++; ch = buf[bp]; 10.212 - } while (ch == 'u'); 10.213 - int limit = bp + 3; 10.214 - if (limit < buflen) { 10.215 - int d = digit(16); 10.216 - int code = d; 10.217 - while (bp < limit && d >= 0) { 10.218 - bp++; ch = buf[bp]; 10.219 - d = digit(16); 10.220 - code = (code << 4) + d; 10.221 - } 10.222 - if (d >= 0) { 10.223 - ch = (char)code; 10.224 - unicodeConversionBp = bp; 10.225 - return; 10.226 - } 10.227 - } 10.228 - lexError(bp, "illegal.unicode.esc"); 10.229 - } else { 10.230 - bp--; 10.231 - ch = '\\'; 10.232 - } 10.233 - } 10.234 - } 10.235 - 10.236 - /** Read next character. 10.237 - */ 10.238 - private void scanChar() { 10.239 - ch = buf[++bp]; 10.240 - if (ch == '\\') { 10.241 - convertUnicode(); 10.242 - } 10.243 - } 10.244 - 10.245 - /** Read next character in comment, skipping over double '\' characters. 10.246 - */ 10.247 - private void scanCommentChar() { 10.248 - scanChar(); 10.249 - if (ch == '\\') { 10.250 - if (buf[bp+1] == '\\' && unicodeConversionBp != bp) { 10.251 - bp++; 10.252 - } else { 10.253 - convertUnicode(); 10.254 - } 10.255 - } 10.256 - } 10.257 - 10.258 - /** Append a character to sbuf. 10.259 - */ 10.260 - private void putChar(char ch) { 10.261 - if (sp == sbuf.length) { 10.262 - char[] newsbuf = new char[sbuf.length * 2]; 10.263 - System.arraycopy(sbuf, 0, newsbuf, 0, sbuf.length); 10.264 - sbuf = newsbuf; 10.265 - } 10.266 - sbuf[sp++] = ch; 10.267 - } 10.268 - 10.269 - /** Read next character in character or string literal and copy into sbuf. 10.270 - */ 10.271 - private void scanLitChar() { 10.272 - if (ch == '\\') { 10.273 - if (buf[bp+1] == '\\' && unicodeConversionBp != bp) { 10.274 - bp++; 10.275 - putChar('\\'); 10.276 - scanChar(); 10.277 - } else { 10.278 - scanChar(); 10.279 - switch (ch) { 10.280 - case '0': case '1': case '2': case '3': 10.281 - case '4': case '5': case '6': case '7': 10.282 - char leadch = ch; 10.283 - int oct = digit(8); 10.284 - scanChar(); 10.285 - if ('0' <= ch && ch <= '7') { 10.286 - oct = oct * 8 + digit(8); 10.287 - scanChar(); 10.288 - if (leadch <= '3' && '0' <= ch && ch <= '7') { 10.289 - oct = oct * 8 + digit(8); 10.290 - scanChar(); 10.291 - } 10.292 - } 10.293 - putChar((char)oct); 10.294 - break; 10.295 - case 'b': 10.296 - putChar('\b'); scanChar(); break; 10.297 - case 't': 10.298 - putChar('\t'); scanChar(); break; 10.299 - case 'n': 10.300 - putChar('\n'); scanChar(); break; 10.301 - case 'f': 10.302 - putChar('\f'); scanChar(); break; 10.303 - case 'r': 10.304 - putChar('\r'); scanChar(); break; 10.305 - case '\'': 10.306 - putChar('\''); scanChar(); break; 10.307 - case '\"': 10.308 - putChar('\"'); scanChar(); break; 10.309 - case '\\': 10.310 - putChar('\\'); scanChar(); break; 10.311 - default: 10.312 - lexError(bp, "illegal.esc.char"); 10.313 - } 10.314 - } 10.315 - } else if (bp != buflen) { 10.316 - putChar(ch); scanChar(); 10.317 - } 10.318 - } 10.319 - 10.320 - private void scanDigits(int digitRadix) { 10.321 - char saveCh; 10.322 - int savePos; 10.323 - do { 10.324 - if (ch != '_') { 10.325 - putChar(ch); 10.326 - } else { 10.327 - if (!allowUnderscoresInLiterals) { 10.328 - lexError("unsupported.underscore.lit", source.name); 10.329 - allowUnderscoresInLiterals = true; 10.330 - } 10.331 - } 10.332 - saveCh = ch; 10.333 - savePos = bp; 10.334 - scanChar(); 10.335 - } while (digit(digitRadix) >= 0 || ch == '_'); 10.336 - if (saveCh == '_') 10.337 - lexError(savePos, "illegal.underscore"); 10.338 - } 10.339 - 10.340 - /** Read fractional part of hexadecimal floating point number. 10.341 - */ 10.342 - private void scanHexExponentAndSuffix() { 10.343 - if (ch == 'p' || ch == 'P') { 10.344 - putChar(ch); 10.345 - scanChar(); 10.346 - skipIllegalUnderscores(); 10.347 - if (ch == '+' || ch == '-') { 10.348 - putChar(ch); 10.349 - scanChar(); 10.350 - } 10.351 - skipIllegalUnderscores(); 10.352 - if ('0' <= ch && ch <= '9') { 10.353 - scanDigits(10); 10.354 - if (!allowHexFloats) { 10.355 - lexError("unsupported.fp.lit", source.name); 10.356 - allowHexFloats = true; 10.357 - } 10.358 - else if (!hexFloatsWork) 10.359 - lexError("unsupported.cross.fp.lit"); 10.360 - } else 10.361 - lexError("malformed.fp.lit"); 10.362 - } else { 10.363 - lexError("malformed.fp.lit"); 10.364 - } 10.365 - if (ch == 'f' || ch == 'F') { 10.366 - putChar(ch); 10.367 - scanChar(); 10.368 - token = FLOATLITERAL; 10.369 - } else { 10.370 - if (ch == 'd' || ch == 'D') { 10.371 - putChar(ch); 10.372 - scanChar(); 10.373 - } 10.374 - token = DOUBLELITERAL; 10.375 - } 10.376 - } 10.377 - 10.378 - /** Read fractional part of floating point number. 10.379 - */ 10.380 - private void scanFraction() { 10.381 - skipIllegalUnderscores(); 10.382 - if ('0' <= ch && ch <= '9') { 10.383 - scanDigits(10); 10.384 - } 10.385 - int sp1 = sp; 10.386 - if (ch == 'e' || ch == 'E') { 10.387 - putChar(ch); 10.388 - scanChar(); 10.389 - skipIllegalUnderscores(); 10.390 - if (ch == '+' || ch == '-') { 10.391 - putChar(ch); 10.392 - scanChar(); 10.393 - } 10.394 - skipIllegalUnderscores(); 10.395 - if ('0' <= ch && ch <= '9') { 10.396 - scanDigits(10); 10.397 - return; 10.398 - } 10.399 - lexError("malformed.fp.lit"); 10.400 - sp = sp1; 10.401 - } 10.402 - } 10.403 - 10.404 - /** Read fractional part and 'd' or 'f' suffix of floating point number. 10.405 - */ 10.406 - private void scanFractionAndSuffix() { 10.407 - this.radix = 10; 10.408 - scanFraction(); 10.409 - if (ch == 'f' || ch == 'F') { 10.410 - putChar(ch); 10.411 - scanChar(); 10.412 - token = FLOATLITERAL; 10.413 - } else { 10.414 - if (ch == 'd' || ch == 'D') { 10.415 - putChar(ch); 10.416 - scanChar(); 10.417 - } 10.418 - token = DOUBLELITERAL; 10.419 - } 10.420 - } 10.421 - 10.422 - /** Read fractional part and 'd' or 'f' suffix of floating point number. 10.423 - */ 10.424 - private void scanHexFractionAndSuffix(boolean seendigit) { 10.425 - this.radix = 16; 10.426 - Assert.check(ch == '.'); 10.427 - putChar(ch); 10.428 - scanChar(); 10.429 - skipIllegalUnderscores(); 10.430 - if (digit(16) >= 0) { 10.431 - seendigit = true; 10.432 - scanDigits(16); 10.433 - } 10.434 - if (!seendigit) 10.435 - lexError("invalid.hex.number"); 10.436 - else 10.437 - scanHexExponentAndSuffix(); 10.438 - } 10.439 - 10.440 - private void skipIllegalUnderscores() { 10.441 - if (ch == '_') { 10.442 - lexError(bp, "illegal.underscore"); 10.443 - while (ch == '_') 10.444 - scanChar(); 10.445 - } 10.446 - } 10.447 - 10.448 - /** Read a number. 10.449 - * @param radix The radix of the number; one of 2, j8, 10, 16. 10.450 - */ 10.451 - private void scanNumber(int radix) { 10.452 - this.radix = radix; 10.453 - // for octal, allow base-10 digit in case it's a float literal 10.454 - int digitRadix = (radix == 8 ? 10 : radix); 10.455 - boolean seendigit = false; 10.456 - if (digit(digitRadix) >= 0) { 10.457 - seendigit = true; 10.458 - scanDigits(digitRadix); 10.459 - } 10.460 - if (radix == 16 && ch == '.') { 10.461 - scanHexFractionAndSuffix(seendigit); 10.462 - } else if (seendigit && radix == 16 && (ch == 'p' || ch == 'P')) { 10.463 - scanHexExponentAndSuffix(); 10.464 - } else if (digitRadix == 10 && ch == '.') { 10.465 - putChar(ch); 10.466 - scanChar(); 10.467 - scanFractionAndSuffix(); 10.468 - } else if (digitRadix == 10 && 10.469 - (ch == 'e' || ch == 'E' || 10.470 - ch == 'f' || ch == 'F' || 10.471 - ch == 'd' || ch == 'D')) { 10.472 - scanFractionAndSuffix(); 10.473 - } else { 10.474 - if (ch == 'l' || ch == 'L') { 10.475 - scanChar(); 10.476 - token = LONGLITERAL; 10.477 - } else { 10.478 - token = INTLITERAL; 10.479 - } 10.480 - } 10.481 - } 10.482 - 10.483 - /** Read an identifier. 10.484 - */ 10.485 - private void scanIdent() { 10.486 - boolean isJavaIdentifierPart; 10.487 - char high; 10.488 - do { 10.489 - if (sp == sbuf.length) putChar(ch); else sbuf[sp++] = ch; 10.490 - // optimization, was: putChar(ch); 10.491 - 10.492 - scanChar(); 10.493 - switch (ch) { 10.494 - case 'A': case 'B': case 'C': case 'D': case 'E': 10.495 - case 'F': case 'G': case 'H': case 'I': case 'J': 10.496 - case 'K': case 'L': case 'M': case 'N': case 'O': 10.497 - case 'P': case 'Q': case 'R': case 'S': case 'T': 10.498 - case 'U': case 'V': case 'W': case 'X': case 'Y': 10.499 - case 'Z': 10.500 - case 'a': case 'b': case 'c': case 'd': case 'e': 10.501 - case 'f': case 'g': case 'h': case 'i': case 'j': 10.502 - case 'k': case 'l': case 'm': case 'n': case 'o': 10.503 - case 'p': case 'q': case 'r': case 's': case 't': 10.504 - case 'u': case 'v': case 'w': case 'x': case 'y': 10.505 - case 'z': 10.506 - case '$': case '_': 10.507 - case '0': case '1': case '2': case '3': case '4': 10.508 - case '5': case '6': case '7': case '8': case '9': 10.509 - case '\u0000': case '\u0001': case '\u0002': case '\u0003': 10.510 - case '\u0004': case '\u0005': case '\u0006': case '\u0007': 10.511 - case '\u0008': case '\u000E': case '\u000F': case '\u0010': 10.512 - case '\u0011': case '\u0012': case '\u0013': case '\u0014': 10.513 - case '\u0015': case '\u0016': case '\u0017': 10.514 - case '\u0018': case '\u0019': case '\u001B': 10.515 - case '\u007F': 10.516 - break; 10.517 - case '\u001A': // EOI is also a legal identifier part 10.518 - if (bp >= buflen) { 10.519 - name = names.fromChars(sbuf, 0, sp); 10.520 - token = keywords.key(name); 10.521 - return; 10.522 - } 10.523 - break; 10.524 - default: 10.525 - if (ch < '\u0080') { 10.526 - // all ASCII range chars already handled, above 10.527 - isJavaIdentifierPart = false; 10.528 - } else { 10.529 - high = scanSurrogates(); 10.530 - if (high != 0) { 10.531 - if (sp == sbuf.length) { 10.532 - putChar(high); 10.533 - } else { 10.534 - sbuf[sp++] = high; 10.535 - } 10.536 - isJavaIdentifierPart = Character.isJavaIdentifierPart( 10.537 - Character.toCodePoint(high, ch)); 10.538 - } else { 10.539 - isJavaIdentifierPart = Character.isJavaIdentifierPart(ch); 10.540 - } 10.541 - } 10.542 - if (!isJavaIdentifierPart) { 10.543 - name = names.fromChars(sbuf, 0, sp); 10.544 - token = keywords.key(name); 10.545 - return; 10.546 - } 10.547 - } 10.548 - } while (true); 10.549 - } 10.550 - 10.551 - /** Are surrogates supported? 10.552 - */ 10.553 - final static boolean surrogatesSupported = surrogatesSupported(); 10.554 - private static boolean surrogatesSupported() { 10.555 - try { 10.556 - Character.isHighSurrogate('a'); 10.557 - return true; 10.558 - } catch (NoSuchMethodError ex) { 10.559 - return false; 10.560 - } 10.561 - } 10.562 - 10.563 - /** Scan surrogate pairs. If 'ch' is a high surrogate and 10.564 - * the next character is a low surrogate, then put the low 10.565 - * surrogate in 'ch', and return the high surrogate. 10.566 - * otherwise, just return 0. 10.567 - */ 10.568 - private char scanSurrogates() { 10.569 - if (surrogatesSupported && Character.isHighSurrogate(ch)) { 10.570 - char high = ch; 10.571 - 10.572 - scanChar(); 10.573 - 10.574 - if (Character.isLowSurrogate(ch)) { 10.575 - return high; 10.576 - } 10.577 - 10.578 - ch = high; 10.579 - } 10.580 - 10.581 - return 0; 10.582 - } 10.583 - 10.584 - /** Return true if ch can be part of an operator. 10.585 - */ 10.586 - private boolean isSpecial(char ch) { 10.587 - switch (ch) { 10.588 - case '!': case '%': case '&': case '*': case '?': 10.589 - case '+': case '-': case ':': case '<': case '=': 10.590 - case '>': case '^': case '|': case '~': 10.591 - case '@': 10.592 - return true; 10.593 - default: 10.594 - return false; 10.595 - } 10.596 - } 10.597 - 10.598 - /** Read longest possible sequence of special characters and convert 10.599 - * to token. 10.600 - */ 10.601 - private void scanOperator() { 10.602 - while (true) { 10.603 - putChar(ch); 10.604 - Name newname = names.fromChars(sbuf, 0, sp); 10.605 - if (keywords.key(newname) == IDENTIFIER) { 10.606 - sp--; 10.607 - break; 10.608 - } 10.609 - name = newname; 10.610 - token = keywords.key(newname); 10.611 - scanChar(); 10.612 - if (!isSpecial(ch)) break; 10.613 - } 10.614 - } 10.615 - 10.616 - /** 10.617 - * Scan a documention comment; determine if a deprecated tag is present. 10.618 - * Called once the initial /, * have been skipped, positioned at the second * 10.619 - * (which is treated as the beginning of the first line). 10.620 - * Stops positioned at the closing '/'. 10.621 - */ 10.622 - @SuppressWarnings("fallthrough") 10.623 - private void scanDocComment() { 10.624 - boolean deprecatedPrefix = false; 10.625 - 10.626 - forEachLine: 10.627 - while (bp < buflen) { 10.628 - 10.629 - // Skip optional WhiteSpace at beginning of line 10.630 - while (bp < buflen && (ch == ' ' || ch == '\t' || ch == FF)) { 10.631 - scanCommentChar(); 10.632 - } 10.633 - 10.634 - // Skip optional consecutive Stars 10.635 - while (bp < buflen && ch == '*') { 10.636 - scanCommentChar(); 10.637 - if (ch == '/') { 10.638 - return; 10.639 - } 10.640 - } 10.641 - 10.642 - // Skip optional WhiteSpace after Stars 10.643 - while (bp < buflen && (ch == ' ' || ch == '\t' || ch == FF)) { 10.644 - scanCommentChar(); 10.645 - } 10.646 - 10.647 - deprecatedPrefix = false; 10.648 - // At beginning of line in the JavaDoc sense. 10.649 - if (bp < buflen && ch == '@' && !deprecatedFlag) { 10.650 - scanCommentChar(); 10.651 - if (bp < buflen && ch == 'd') { 10.652 - scanCommentChar(); 10.653 - if (bp < buflen && ch == 'e') { 10.654 - scanCommentChar(); 10.655 - if (bp < buflen && ch == 'p') { 10.656 - scanCommentChar(); 10.657 - if (bp < buflen && ch == 'r') { 10.658 - scanCommentChar(); 10.659 - if (bp < buflen && ch == 'e') { 10.660 - scanCommentChar(); 10.661 - if (bp < buflen && ch == 'c') { 10.662 - scanCommentChar(); 10.663 - if (bp < buflen && ch == 'a') { 10.664 - scanCommentChar(); 10.665 - if (bp < buflen && ch == 't') { 10.666 - scanCommentChar(); 10.667 - if (bp < buflen && ch == 'e') { 10.668 - scanCommentChar(); 10.669 - if (bp < buflen && ch == 'd') { 10.670 - deprecatedPrefix = true; 10.671 - scanCommentChar(); 10.672 - }}}}}}}}}}} 10.673 - if (deprecatedPrefix && bp < buflen) { 10.674 - if (Character.isWhitespace(ch)) { 10.675 - deprecatedFlag = true; 10.676 - } else if (ch == '*') { 10.677 - scanCommentChar(); 10.678 - if (ch == '/') { 10.679 - deprecatedFlag = true; 10.680 - return; 10.681 - } 10.682 - } 10.683 - } 10.684 - 10.685 - // Skip rest of line 10.686 - while (bp < buflen) { 10.687 - switch (ch) { 10.688 - case '*': 10.689 - scanCommentChar(); 10.690 - if (ch == '/') { 10.691 - return; 10.692 - } 10.693 - break; 10.694 - case CR: // (Spec 3.4) 10.695 - scanCommentChar(); 10.696 - if (ch != LF) { 10.697 - continue forEachLine; 10.698 - } 10.699 - /* fall through to LF case */ 10.700 - case LF: // (Spec 3.4) 10.701 - scanCommentChar(); 10.702 - continue forEachLine; 10.703 - default: 10.704 - scanCommentChar(); 10.705 - } 10.706 - } // rest of line 10.707 - } // forEachLine 10.708 - return; 10.709 - } 10.710 - 10.711 - /** The value of a literal token, recorded as a string. 10.712 - * For integers, leading 0x and 'l' suffixes are suppressed. 10.713 - */ 10.714 - public String stringVal() { 10.715 - return new String(sbuf, 0, sp); 10.716 - } 10.717 - 10.718 - /** Read token. 10.719 - */ 10.720 - public void nextToken() { 10.721 - 10.722 - try { 10.723 - prevEndPos = endPos; 10.724 - sp = 0; 10.725 - 10.726 - while (true) { 10.727 - pos = bp; 10.728 - switch (ch) { 10.729 - case ' ': // (Spec 3.6) 10.730 - case '\t': // (Spec 3.6) 10.731 - case FF: // (Spec 3.6) 10.732 - do { 10.733 - scanChar(); 10.734 - } while (ch == ' ' || ch == '\t' || ch == FF); 10.735 - endPos = bp; 10.736 - processWhiteSpace(); 10.737 - break; 10.738 - case LF: // (Spec 3.4) 10.739 - scanChar(); 10.740 - endPos = bp; 10.741 - processLineTerminator(); 10.742 - break; 10.743 - case CR: // (Spec 3.4) 10.744 - scanChar(); 10.745 - if (ch == LF) { 10.746 - scanChar(); 10.747 - } 10.748 - endPos = bp; 10.749 - processLineTerminator(); 10.750 - break; 10.751 - case 'A': case 'B': case 'C': case 'D': case 'E': 10.752 - case 'F': case 'G': case 'H': case 'I': case 'J': 10.753 - case 'K': case 'L': case 'M': case 'N': case 'O': 10.754 - case 'P': case 'Q': case 'R': case 'S': case 'T': 10.755 - case 'U': case 'V': case 'W': case 'X': case 'Y': 10.756 - case 'Z': 10.757 - case 'a': case 'b': case 'c': case 'd': case 'e': 10.758 - case 'f': case 'g': case 'h': case 'i': case 'j': 10.759 - case 'k': case 'l': case 'm': case 'n': case 'o': 10.760 - case 'p': case 'q': case 'r': case 's': case 't': 10.761 - case 'u': case 'v': case 'w': case 'x': case 'y': 10.762 - case 'z': 10.763 - case '$': case '_': 10.764 - scanIdent(); 10.765 - return; 10.766 - case '0': 10.767 - scanChar(); 10.768 - if (ch == 'x' || ch == 'X') { 10.769 - scanChar(); 10.770 - skipIllegalUnderscores(); 10.771 - if (ch == '.') { 10.772 - scanHexFractionAndSuffix(false); 10.773 - } else if (digit(16) < 0) { 10.774 - lexError("invalid.hex.number"); 10.775 - } else { 10.776 - scanNumber(16); 10.777 - } 10.778 - } else if (ch == 'b' || ch == 'B') { 10.779 - if (!allowBinaryLiterals) { 10.780 - lexError("unsupported.binary.lit", source.name); 10.781 - allowBinaryLiterals = true; 10.782 - } 10.783 - scanChar(); 10.784 - skipIllegalUnderscores(); 10.785 - if (digit(2) < 0) { 10.786 - lexError("invalid.binary.number"); 10.787 - } else { 10.788 - scanNumber(2); 10.789 - } 10.790 - } else { 10.791 - putChar('0'); 10.792 - if (ch == '_') { 10.793 - int savePos = bp; 10.794 - do { 10.795 - scanChar(); 10.796 - } while (ch == '_'); 10.797 - if (digit(10) < 0) { 10.798 - lexError(savePos, "illegal.underscore"); 10.799 - } 10.800 - } 10.801 - scanNumber(8); 10.802 - } 10.803 - return; 10.804 - case '1': case '2': case '3': case '4': 10.805 - case '5': case '6': case '7': case '8': case '9': 10.806 - scanNumber(10); 10.807 - return; 10.808 - case '.': 10.809 - scanChar(); 10.810 - if ('0' <= ch && ch <= '9') { 10.811 - putChar('.'); 10.812 - scanFractionAndSuffix(); 10.813 - } else if (ch == '.') { 10.814 - putChar('.'); putChar('.'); 10.815 - scanChar(); 10.816 - if (ch == '.') { 10.817 - scanChar(); 10.818 - putChar('.'); 10.819 - token = ELLIPSIS; 10.820 - } else { 10.821 - lexError("malformed.fp.lit"); 10.822 - } 10.823 - } else { 10.824 - token = DOT; 10.825 - } 10.826 - return; 10.827 - case ',': 10.828 - scanChar(); token = COMMA; return; 10.829 - case ';': 10.830 - scanChar(); token = SEMI; return; 10.831 - case '(': 10.832 - scanChar(); token = LPAREN; return; 10.833 - case ')': 10.834 - scanChar(); token = RPAREN; return; 10.835 - case '[': 10.836 - scanChar(); token = LBRACKET; return; 10.837 - case ']': 10.838 - scanChar(); token = RBRACKET; return; 10.839 - case '{': 10.840 - scanChar(); token = LBRACE; return; 10.841 - case '}': 10.842 - scanChar(); token = RBRACE; return; 10.843 - case '/': 10.844 - scanChar(); 10.845 - if (ch == '/') { 10.846 - do { 10.847 - scanCommentChar(); 10.848 - } while (ch != CR && ch != LF && bp < buflen); 10.849 - if (bp < buflen) { 10.850 - endPos = bp; 10.851 - processComment(CommentStyle.LINE); 10.852 - } 10.853 - break; 10.854 - } else if (ch == '*') { 10.855 - scanChar(); 10.856 - CommentStyle style; 10.857 - if (ch == '*') { 10.858 - style = CommentStyle.JAVADOC; 10.859 - scanDocComment(); 10.860 - } else { 10.861 - style = CommentStyle.BLOCK; 10.862 - while (bp < buflen) { 10.863 - if (ch == '*') { 10.864 - scanChar(); 10.865 - if (ch == '/') break; 10.866 - } else { 10.867 - scanCommentChar(); 10.868 - } 10.869 - } 10.870 - } 10.871 - if (ch == '/') { 10.872 - scanChar(); 10.873 - endPos = bp; 10.874 - processComment(style); 10.875 - break; 10.876 - } else { 10.877 - lexError("unclosed.comment"); 10.878 - return; 10.879 - } 10.880 - } else if (ch == '=') { 10.881 - name = names.slashequals; 10.882 - token = SLASHEQ; 10.883 - scanChar(); 10.884 - } else { 10.885 - name = names.slash; 10.886 - token = SLASH; 10.887 - } 10.888 - return; 10.889 - case '\'': 10.890 - scanChar(); 10.891 - if (ch == '\'') { 10.892 - lexError("empty.char.lit"); 10.893 - } else { 10.894 - if (ch == CR || ch == LF) 10.895 - lexError(pos, "illegal.line.end.in.char.lit"); 10.896 - scanLitChar(); 10.897 - if (ch == '\'') { 10.898 - scanChar(); 10.899 - token = CHARLITERAL; 10.900 - } else { 10.901 - lexError(pos, "unclosed.char.lit"); 10.902 - } 10.903 - } 10.904 - return; 10.905 - case '\"': 10.906 - scanChar(); 10.907 - while (ch != '\"' && ch != CR && ch != LF && bp < buflen) 10.908 - scanLitChar(); 10.909 - if (ch == '\"') { 10.910 - token = STRINGLITERAL; 10.911 - scanChar(); 10.912 - } else { 10.913 - lexError(pos, "unclosed.str.lit"); 10.914 - } 10.915 - return; 10.916 - default: 10.917 - if (isSpecial(ch)) { 10.918 - scanOperator(); 10.919 - } else { 10.920 - boolean isJavaIdentifierStart; 10.921 - if (ch < '\u0080') { 10.922 - // all ASCII range chars already handled, above 10.923 - isJavaIdentifierStart = false; 10.924 - } else { 10.925 - char high = scanSurrogates(); 10.926 - if (high != 0) { 10.927 - if (sp == sbuf.length) { 10.928 - putChar(high); 10.929 - } else { 10.930 - sbuf[sp++] = high; 10.931 - } 10.932 - 10.933 - isJavaIdentifierStart = Character.isJavaIdentifierStart( 10.934 - Character.toCodePoint(high, ch)); 10.935 - } else { 10.936 - isJavaIdentifierStart = Character.isJavaIdentifierStart(ch); 10.937 - } 10.938 - } 10.939 - if (isJavaIdentifierStart) { 10.940 - scanIdent(); 10.941 - } else if (bp == buflen || ch == EOI && bp+1 == buflen) { // JLS 3.5 10.942 - token = EOF; 10.943 - pos = bp = eofPos; 10.944 - } else { 10.945 - lexError("illegal.char", String.valueOf((int)ch)); 10.946 - scanChar(); 10.947 - } 10.948 - } 10.949 - return; 10.950 - } 10.951 - } 10.952 - } finally { 10.953 - endPos = bp; 10.954 - if (scannerDebug) 10.955 - System.out.println("nextToken(" + pos 10.956 - + "," + endPos + ")=|" + 10.957 - new String(getRawCharacters(pos, endPos)) 10.958 - + "|"); 10.959 - } 10.960 - } 10.961 - 10.962 - /** Return the current token, set by nextToken(). 10.963 - */ 10.964 public Token token() { 10.965 return token; 10.966 } 10.967 10.968 - /** Sets the current token. 10.969 - * This method is primarily used to update the token stream when the 10.970 - * parser is handling the end of nested type arguments such as 10.971 - * {@code List<List<String>>} and needs to disambiguate between 10.972 - * repeated use of ">" and relation operators such as ">>" and ">>>". Noting 10.973 - * that this does not handle arbitrary tokens containing Unicode escape 10.974 - * sequences. 10.975 - */ 10.976 - public void token(Token token) { 10.977 - pos += this.token.name.length() - token.name.length(); 10.978 - prevEndPos = pos; 10.979 - this.token = token; 10.980 + public Token prevToken() { 10.981 + return prevToken; 10.982 } 10.983 10.984 - /** Return the current token's position: a 0-based 10.985 - * offset from beginning of the raw input stream 10.986 - * (before unicode translation) 10.987 - */ 10.988 - public int pos() { 10.989 - return pos; 10.990 + public void nextToken() { 10.991 + prevToken = token; 10.992 + token = tokenizer.readToken(); 10.993 } 10.994 10.995 - /** Return the last character position of the current token. 10.996 - */ 10.997 - public int endPos() { 10.998 - return endPos; 10.999 + public Token split() { 10.1000 + Token[] splitTokens = token.split(tokens); 10.1001 + prevToken = splitTokens[0]; 10.1002 + token = splitTokens[1]; 10.1003 + return token; 10.1004 } 10.1005 10.1006 - /** Return the last character position of the previous token. 10.1007 - */ 10.1008 - public int prevEndPos() { 10.1009 - return prevEndPos; 10.1010 + public LineMap getLineMap() { 10.1011 + return tokenizer.getLineMap(); 10.1012 } 10.1013 10.1014 - /** Return the position where a lexical error occurred; 10.1015 - */ 10.1016 public int errPos() { 10.1017 - return errPos; 10.1018 + return tokenizer.errPos(); 10.1019 } 10.1020 10.1021 - /** Set the position where a lexical error occurred; 10.1022 - */ 10.1023 public void errPos(int pos) { 10.1024 - errPos = pos; 10.1025 + tokenizer.errPos(pos); 10.1026 } 10.1027 - 10.1028 - /** Return the name of an identifier or token for the current token. 10.1029 - */ 10.1030 - public Name name() { 10.1031 - return name; 10.1032 - } 10.1033 - 10.1034 - /** Return the radix of a numeric literal token. 10.1035 - */ 10.1036 - public int radix() { 10.1037 - return radix; 10.1038 - } 10.1039 - 10.1040 - /** Has a @deprecated been encountered in last doc comment? 10.1041 - * This needs to be reset by client with resetDeprecatedFlag. 10.1042 - */ 10.1043 - public boolean deprecatedFlag() { 10.1044 - return deprecatedFlag; 10.1045 - } 10.1046 - 10.1047 - public void resetDeprecatedFlag() { 10.1048 - deprecatedFlag = false; 10.1049 - } 10.1050 - 10.1051 - /** 10.1052 - * Returns the documentation string of the current token. 10.1053 - */ 10.1054 - public String docComment() { 10.1055 - return null; 10.1056 - } 10.1057 - 10.1058 - /** 10.1059 - * Returns a copy of the input buffer, up to its inputLength. 10.1060 - * Unicode escape sequences are not translated. 10.1061 - */ 10.1062 - public char[] getRawCharacters() { 10.1063 - char[] chars = new char[buflen]; 10.1064 - System.arraycopy(buf, 0, chars, 0, buflen); 10.1065 - return chars; 10.1066 - } 10.1067 - 10.1068 - /** 10.1069 - * Returns a copy of a character array subset of the input buffer. 10.1070 - * The returned array begins at the <code>beginIndex</code> and 10.1071 - * extends to the character at index <code>endIndex - 1</code>. 10.1072 - * Thus the length of the substring is <code>endIndex-beginIndex</code>. 10.1073 - * This behavior is like 10.1074 - * <code>String.substring(beginIndex, endIndex)</code>. 10.1075 - * Unicode escape sequences are not translated. 10.1076 - * 10.1077 - * @param beginIndex the beginning index, inclusive. 10.1078 - * @param endIndex the ending index, exclusive. 10.1079 - * @throws IndexOutOfBounds if either offset is outside of the 10.1080 - * array bounds 10.1081 - */ 10.1082 - public char[] getRawCharacters(int beginIndex, int endIndex) { 10.1083 - int length = endIndex - beginIndex; 10.1084 - char[] chars = new char[length]; 10.1085 - System.arraycopy(buf, beginIndex, chars, 0, length); 10.1086 - return chars; 10.1087 - } 10.1088 - 10.1089 - public enum CommentStyle { 10.1090 - LINE, 10.1091 - BLOCK, 10.1092 - JAVADOC, 10.1093 - } 10.1094 - 10.1095 - /** 10.1096 - * Called when a complete comment has been scanned. pos and endPos 10.1097 - * will mark the comment boundary. 10.1098 - */ 10.1099 - protected void processComment(CommentStyle style) { 10.1100 - if (scannerDebug) 10.1101 - System.out.println("processComment(" + pos 10.1102 - + "," + endPos + "," + style + ")=|" 10.1103 - + new String(getRawCharacters(pos, endPos)) 10.1104 - + "|"); 10.1105 - } 10.1106 - 10.1107 - /** 10.1108 - * Called when a complete whitespace run has been scanned. pos and endPos 10.1109 - * will mark the whitespace boundary. 10.1110 - */ 10.1111 - protected void processWhiteSpace() { 10.1112 - if (scannerDebug) 10.1113 - System.out.println("processWhitespace(" + pos 10.1114 - + "," + endPos + ")=|" + 10.1115 - new String(getRawCharacters(pos, endPos)) 10.1116 - + "|"); 10.1117 - } 10.1118 - 10.1119 - /** 10.1120 - * Called when a line terminator has been processed. 10.1121 - */ 10.1122 - protected void processLineTerminator() { 10.1123 - if (scannerDebug) 10.1124 - System.out.println("processTerminator(" + pos 10.1125 - + "," + endPos + ")=|" + 10.1126 - new String(getRawCharacters(pos, endPos)) 10.1127 - + "|"); 10.1128 - } 10.1129 - 10.1130 - /** Build a map for translating between line numbers and 10.1131 - * positions in the input. 10.1132 - * 10.1133 - * @return a LineMap */ 10.1134 - public Position.LineMap getLineMap() { 10.1135 - return Position.makeLineMap(buf, buflen, false); 10.1136 - } 10.1137 - 10.1138 }
11.1 --- a/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java Fri Oct 21 14:14:29 2011 -0700 11.2 +++ b/src/share/classes/com/sun/tools/javac/parser/ScannerFactory.java Mon Oct 24 13:00:20 2011 +0100 11.3 @@ -57,7 +57,7 @@ 11.4 final Log log; 11.5 final Names names; 11.6 final Source source; 11.7 - final Keywords keywords; 11.8 + final Tokens tokens; 11.9 11.10 /** Create a new scanner factory. */ 11.11 protected ScannerFactory(Context context) { 11.12 @@ -65,14 +65,14 @@ 11.13 this.log = Log.instance(context); 11.14 this.names = Names.instance(context); 11.15 this.source = Source.instance(context); 11.16 - this.keywords = Keywords.instance(context); 11.17 + this.tokens = Tokens.instance(context); 11.18 } 11.19 11.20 public Scanner newScanner(CharSequence input, boolean keepDocComments) { 11.21 if (input instanceof CharBuffer) { 11.22 CharBuffer buf = (CharBuffer) input; 11.23 if (keepDocComments) 11.24 - return new DocCommentScanner(this, buf); 11.25 + return new Scanner(this, new JavadocTokenizer(this, buf)); 11.26 else 11.27 return new Scanner(this, buf); 11.28 } else { 11.29 @@ -83,7 +83,7 @@ 11.30 11.31 public Scanner newScanner(char[] input, int inputLength, boolean keepDocComments) { 11.32 if (keepDocComments) 11.33 - return new DocCommentScanner(this, input, inputLength); 11.34 + return new Scanner(this, new JavadocTokenizer(this, input, inputLength)); 11.35 else 11.36 return new Scanner(this, input, inputLength); 11.37 }
12.1 --- a/src/share/classes/com/sun/tools/javac/parser/Token.java Fri Oct 21 14:14:29 2011 -0700 12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 12.3 @@ -1,198 +0,0 @@ 12.4 -/* 12.5 - * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved. 12.6 - * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 12.7 - * 12.8 - * This code is free software; you can redistribute it and/or modify it 12.9 - * under the terms of the GNU General Public License version 2 only, as 12.10 - * published by the Free Software Foundation. Oracle designates this 12.11 - * particular file as subject to the "Classpath" exception as provided 12.12 - * by Oracle in the LICENSE file that accompanied this code. 12.13 - * 12.14 - * This code is distributed in the hope that it will be useful, but WITHOUT 12.15 - * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12.16 - * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12.17 - * version 2 for more details (a copy is included in the LICENSE file that 12.18 - * accompanied this code). 12.19 - * 12.20 - * You should have received a copy of the GNU General Public License version 12.21 - * 2 along with this work; if not, write to the Free Software Foundation, 12.22 - * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 12.23 - * 12.24 - * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 12.25 - * or visit www.oracle.com if you need additional information or have any 12.26 - * questions. 12.27 - */ 12.28 - 12.29 -package com.sun.tools.javac.parser; 12.30 - 12.31 -import java.util.Locale; 12.32 - 12.33 -import com.sun.tools.javac.api.Formattable; 12.34 -import com.sun.tools.javac.api.Messages; 12.35 - 12.36 -/** An interface that defines codes for Java source tokens 12.37 - * returned from lexical analysis. 12.38 - * 12.39 - * <p><b>This is NOT part of any supported API. 12.40 - * If you write code that depends on this, you do so at your own risk. 12.41 - * This code and its internal interfaces are subject to change or 12.42 - * deletion without notice.</b> 12.43 - */ 12.44 -public enum Token implements Formattable { 12.45 - EOF, 12.46 - ERROR, 12.47 - IDENTIFIER, 12.48 - ABSTRACT("abstract"), 12.49 - ASSERT("assert"), 12.50 - BOOLEAN("boolean"), 12.51 - BREAK("break"), 12.52 - BYTE("byte"), 12.53 - CASE("case"), 12.54 - CATCH("catch"), 12.55 - CHAR("char"), 12.56 - CLASS("class"), 12.57 - CONST("const"), 12.58 - CONTINUE("continue"), 12.59 - DEFAULT("default"), 12.60 - DO("do"), 12.61 - DOUBLE("double"), 12.62 - ELSE("else"), 12.63 - ENUM("enum"), 12.64 - EXTENDS("extends"), 12.65 - FINAL("final"), 12.66 - FINALLY("finally"), 12.67 - FLOAT("float"), 12.68 - FOR("for"), 12.69 - GOTO("goto"), 12.70 - IF("if"), 12.71 - IMPLEMENTS("implements"), 12.72 - IMPORT("import"), 12.73 - INSTANCEOF("instanceof"), 12.74 - INT("int"), 12.75 - INTERFACE("interface"), 12.76 - LONG("long"), 12.77 - NATIVE("native"), 12.78 - NEW("new"), 12.79 - PACKAGE("package"), 12.80 - PRIVATE("private"), 12.81 - PROTECTED("protected"), 12.82 - PUBLIC("public"), 12.83 - RETURN("return"), 12.84 - SHORT("short"), 12.85 - STATIC("static"), 12.86 - STRICTFP("strictfp"), 12.87 - SUPER("super"), 12.88 - SWITCH("switch"), 12.89 - SYNCHRONIZED("synchronized"), 12.90 - THIS("this"), 12.91 - THROW("throw"), 12.92 - THROWS("throws"), 12.93 - TRANSIENT("transient"), 12.94 - TRY("try"), 12.95 - VOID("void"), 12.96 - VOLATILE("volatile"), 12.97 - WHILE("while"), 12.98 - INTLITERAL, 12.99 - LONGLITERAL, 12.100 - FLOATLITERAL, 12.101 - DOUBLELITERAL, 12.102 - CHARLITERAL, 12.103 - STRINGLITERAL, 12.104 - TRUE("true"), 12.105 - FALSE("false"), 12.106 - NULL("null"), 12.107 - LPAREN("("), 12.108 - RPAREN(")"), 12.109 - LBRACE("{"), 12.110 - RBRACE("}"), 12.111 - LBRACKET("["), 12.112 - RBRACKET("]"), 12.113 - SEMI(";"), 12.114 - COMMA(","), 12.115 - DOT("."), 12.116 - ELLIPSIS("..."), 12.117 - EQ("="), 12.118 - GT(">"), 12.119 - LT("<"), 12.120 - BANG("!"), 12.121 - TILDE("~"), 12.122 - QUES("?"), 12.123 - COLON(":"), 12.124 - EQEQ("=="), 12.125 - LTEQ("<="), 12.126 - GTEQ(">="), 12.127 - BANGEQ("!="), 12.128 - AMPAMP("&&"), 12.129 - BARBAR("||"), 12.130 - PLUSPLUS("++"), 12.131 - SUBSUB("--"), 12.132 - PLUS("+"), 12.133 - SUB("-"), 12.134 - STAR("*"), 12.135 - SLASH("/"), 12.136 - AMP("&"), 12.137 - BAR("|"), 12.138 - CARET("^"), 12.139 - PERCENT("%"), 12.140 - LTLT("<<"), 12.141 - GTGT(">>"), 12.142 - GTGTGT(">>>"), 12.143 - PLUSEQ("+="), 12.144 - SUBEQ("-="), 12.145 - STAREQ("*="), 12.146 - SLASHEQ("/="), 12.147 - AMPEQ("&="), 12.148 - BAREQ("|="), 12.149 - CARETEQ("^="), 12.150 - PERCENTEQ("%="), 12.151 - LTLTEQ("<<="), 12.152 - GTGTEQ(">>="), 12.153 - GTGTGTEQ(">>>="), 12.154 - MONKEYS_AT("@"), 12.155 - CUSTOM; 12.156 - 12.157 - Token() { 12.158 - this(null); 12.159 - } 12.160 - Token(String name) { 12.161 - this.name = name; 12.162 - } 12.163 - 12.164 - public final String name; 12.165 - 12.166 - public String toString() { 12.167 - switch (this) { 12.168 - case IDENTIFIER: 12.169 - return "token.identifier"; 12.170 - case CHARLITERAL: 12.171 - return "token.character"; 12.172 - case STRINGLITERAL: 12.173 - return "token.string"; 12.174 - case INTLITERAL: 12.175 - return "token.integer"; 12.176 - case LONGLITERAL: 12.177 - return "token.long-integer"; 12.178 - case FLOATLITERAL: 12.179 - return "token.float"; 12.180 - case DOUBLELITERAL: 12.181 - return "token.double"; 12.182 - case ERROR: 12.183 - return "token.bad-symbol"; 12.184 - case EOF: 12.185 - return "token.end-of-input"; 12.186 - case DOT: case COMMA: case SEMI: case LPAREN: case RPAREN: 12.187 - case LBRACKET: case RBRACKET: case LBRACE: case RBRACE: 12.188 - return "'" + name + "'"; 12.189 - default: 12.190 - return name; 12.191 - } 12.192 - } 12.193 - 12.194 - public String getKind() { 12.195 - return "Token"; 12.196 - } 12.197 - 12.198 - public String toString(Locale locale, Messages messages) { 12.199 - return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString()); 12.200 - } 12.201 -}
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 13.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Tokens.java Mon Oct 24 13:00:20 2011 +0100 13.3 @@ -0,0 +1,423 @@ 13.4 +/* 13.5 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 13.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 13.7 + * 13.8 + * This code is free software; you can redistribute it and/or modify it 13.9 + * under the terms of the GNU General Public License version 2 only, as 13.10 + * published by the Free Software Foundation. Oracle designates this 13.11 + * particular file as subject to the "Classpath" exception as provided 13.12 + * by Oracle in the LICENSE file that accompanied this code. 13.13 + * 13.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 13.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13.17 + * version 2 for more details (a copy is included in the LICENSE file that 13.18 + * accompanied this code). 13.19 + * 13.20 + * You should have received a copy of the GNU General Public License version 13.21 + * 2 along with this work; if not, write to the Free Software Foundation, 13.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 13.23 + * 13.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 13.25 + * or visit www.oracle.com if you need additional information or have any 13.26 + * questions. 13.27 + */ 13.28 + 13.29 +package com.sun.tools.javac.parser; 13.30 + 13.31 +import java.util.Locale; 13.32 + 13.33 +import com.sun.tools.javac.api.Formattable; 13.34 +import com.sun.tools.javac.api.Messages; 13.35 +import com.sun.tools.javac.parser.Tokens.Token.Tag; 13.36 +import com.sun.tools.javac.util.Name; 13.37 +import com.sun.tools.javac.util.Context; 13.38 +import com.sun.tools.javac.util.Names; 13.39 + 13.40 +/** A class that defines codes/utilities for Java source tokens 13.41 + * returned from lexical analysis. 13.42 + * 13.43 + * <p><b>This is NOT part of any supported API. 13.44 + * If you write code that depends on this, you do so at your own risk. 13.45 + * This code and its internal interfaces are subject to change or 13.46 + * deletion without notice.</b> 13.47 + */ 13.48 +public class Tokens { 13.49 + 13.50 + private final Names names; 13.51 + 13.52 + /** 13.53 + * Keyword array. Maps name indices to Token. 13.54 + */ 13.55 + private final TokenKind[] key; 13.56 + 13.57 + /** The number of the last entered keyword. 13.58 + */ 13.59 + private int maxKey = 0; 13.60 + 13.61 + /** The names of all tokens. 13.62 + */ 13.63 + private Name[] tokenName = new Name[TokenKind.values().length]; 13.64 + 13.65 + public static final Context.Key<Tokens> tokensKey = 13.66 + new Context.Key<Tokens>(); 13.67 + 13.68 + public static Tokens instance(Context context) { 13.69 + Tokens instance = context.get(tokensKey); 13.70 + if (instance == null) 13.71 + instance = new Tokens(context); 13.72 + return instance; 13.73 + } 13.74 + 13.75 + protected Tokens(Context context) { 13.76 + context.put(tokensKey, this); 13.77 + names = Names.instance(context); 13.78 + 13.79 + for (TokenKind t : TokenKind.values()) { 13.80 + if (t.name != null) 13.81 + enterKeyword(t.name, t); 13.82 + else 13.83 + tokenName[t.ordinal()] = null; 13.84 + } 13.85 + 13.86 + key = new TokenKind[maxKey+1]; 13.87 + for (int i = 0; i <= maxKey; i++) key[i] = TokenKind.IDENTIFIER; 13.88 + for (TokenKind t : TokenKind.values()) { 13.89 + if (t.name != null) 13.90 + key[tokenName[t.ordinal()].getIndex()] = t; 13.91 + } 13.92 + } 13.93 + 13.94 + private void enterKeyword(String s, TokenKind token) { 13.95 + Name n = names.fromString(s); 13.96 + tokenName[token.ordinal()] = n; 13.97 + if (n.getIndex() > maxKey) maxKey = n.getIndex(); 13.98 + } 13.99 + 13.100 + /** 13.101 + * Create a new token given a name; if the name corresponds to a token name, 13.102 + * a new token of the corresponding kind is returned; otherwise, an 13.103 + * identifier token is returned. 13.104 + */ 13.105 + TokenKind lookupKind(Name name) { 13.106 + return (name.getIndex() > maxKey) ? TokenKind.IDENTIFIER : key[name.getIndex()]; 13.107 + } 13.108 + 13.109 + TokenKind lookupKind(String name) { 13.110 + return lookupKind(names.fromString(name)); 13.111 + } 13.112 + 13.113 + /** 13.114 + * This enum defines all tokens used by the javac scanner. A token is 13.115 + * optionally associated with a name. 13.116 + */ 13.117 + public enum TokenKind implements Formattable { 13.118 + EOF(), 13.119 + ERROR(), 13.120 + IDENTIFIER(Tag.NAMED), 13.121 + ABSTRACT("abstract"), 13.122 + ASSERT("assert", Tag.NAMED), 13.123 + BOOLEAN("boolean", Tag.NAMED), 13.124 + BREAK("break"), 13.125 + BYTE("byte", Tag.NAMED), 13.126 + CASE("case"), 13.127 + CATCH("catch"), 13.128 + CHAR("char", Tag.NAMED), 13.129 + CLASS("class"), 13.130 + CONST("const"), 13.131 + CONTINUE("continue"), 13.132 + DEFAULT("default"), 13.133 + DO("do"), 13.134 + DOUBLE("double", Tag.NAMED), 13.135 + ELSE("else"), 13.136 + ENUM("enum", Tag.NAMED), 13.137 + EXTENDS("extends"), 13.138 + FINAL("final"), 13.139 + FINALLY("finally"), 13.140 + FLOAT("float", Tag.NAMED), 13.141 + FOR("for"), 13.142 + GOTO("goto"), 13.143 + IF("if"), 13.144 + IMPLEMENTS("implements"), 13.145 + IMPORT("import"), 13.146 + INSTANCEOF("instanceof"), 13.147 + INT("int", Tag.NAMED), 13.148 + INTERFACE("interface"), 13.149 + LONG("long", Tag.NAMED), 13.150 + NATIVE("native"), 13.151 + NEW("new"), 13.152 + PACKAGE("package"), 13.153 + PRIVATE("private"), 13.154 + PROTECTED("protected"), 13.155 + PUBLIC("public"), 13.156 + RETURN("return"), 13.157 + SHORT("short", Tag.NAMED), 13.158 + STATIC("static"), 13.159 + STRICTFP("strictfp"), 13.160 + SUPER("super", Tag.NAMED), 13.161 + SWITCH("switch"), 13.162 + SYNCHRONIZED("synchronized"), 13.163 + THIS("this", Tag.NAMED), 13.164 + THROW("throw"), 13.165 + THROWS("throws"), 13.166 + TRANSIENT("transient"), 13.167 + TRY("try"), 13.168 + VOID("void", Tag.NAMED), 13.169 + VOLATILE("volatile"), 13.170 + WHILE("while"), 13.171 + INTLITERAL(Tag.NUMERIC), 13.172 + LONGLITERAL(Tag.NUMERIC), 13.173 + FLOATLITERAL(Tag.NUMERIC), 13.174 + DOUBLELITERAL(Tag.NUMERIC), 13.175 + CHARLITERAL(Tag.NUMERIC), 13.176 + STRINGLITERAL(Tag.STRING), 13.177 + TRUE("true", Tag.NAMED), 13.178 + FALSE("false", Tag.NAMED), 13.179 + NULL("null", Tag.NAMED), 13.180 + LPAREN("("), 13.181 + RPAREN(")"), 13.182 + LBRACE("{"), 13.183 + RBRACE("}"), 13.184 + LBRACKET("["), 13.185 + RBRACKET("]"), 13.186 + SEMI(";"), 13.187 + COMMA(","), 13.188 + DOT("."), 13.189 + ELLIPSIS("..."), 13.190 + EQ("="), 13.191 + GT(">"), 13.192 + LT("<"), 13.193 + BANG("!"), 13.194 + TILDE("~"), 13.195 + QUES("?"), 13.196 + COLON(":"), 13.197 + EQEQ("=="), 13.198 + LTEQ("<="), 13.199 + GTEQ(">="), 13.200 + BANGEQ("!="), 13.201 + AMPAMP("&&"), 13.202 + BARBAR("||"), 13.203 + PLUSPLUS("++"), 13.204 + SUBSUB("--"), 13.205 + PLUS("+"), 13.206 + SUB("-"), 13.207 + STAR("*"), 13.208 + SLASH("/"), 13.209 + AMP("&"), 13.210 + BAR("|"), 13.211 + CARET("^"), 13.212 + PERCENT("%"), 13.213 + LTLT("<<"), 13.214 + GTGT(">>"), 13.215 + GTGTGT(">>>"), 13.216 + PLUSEQ("+="), 13.217 + SUBEQ("-="), 13.218 + STAREQ("*="), 13.219 + SLASHEQ("/="), 13.220 + AMPEQ("&="), 13.221 + BAREQ("|="), 13.222 + CARETEQ("^="), 13.223 + PERCENTEQ("%="), 13.224 + LTLTEQ("<<="), 13.225 + GTGTEQ(">>="), 13.226 + GTGTGTEQ(">>>="), 13.227 + MONKEYS_AT("@"), 13.228 + CUSTOM; 13.229 + 13.230 + public final String name; 13.231 + public final Tag tag; 13.232 + 13.233 + TokenKind() { 13.234 + this(null, Tag.DEFAULT); 13.235 + } 13.236 + 13.237 + TokenKind(String name) { 13.238 + this(name, Tag.DEFAULT); 13.239 + } 13.240 + 13.241 + TokenKind(Tag tag) { 13.242 + this(null, tag); 13.243 + } 13.244 + 13.245 + TokenKind(String name, Tag tag) { 13.246 + this.name = name; 13.247 + this.tag = tag; 13.248 + } 13.249 + 13.250 + public String toString() { 13.251 + switch (this) { 13.252 + case IDENTIFIER: 13.253 + return "token.identifier"; 13.254 + case CHARLITERAL: 13.255 + return "token.character"; 13.256 + case STRINGLITERAL: 13.257 + return "token.string"; 13.258 + case INTLITERAL: 13.259 + return "token.integer"; 13.260 + case LONGLITERAL: 13.261 + return "token.long-integer"; 13.262 + case FLOATLITERAL: 13.263 + return "token.float"; 13.264 + case DOUBLELITERAL: 13.265 + return "token.double"; 13.266 + case ERROR: 13.267 + return "token.bad-symbol"; 13.268 + case EOF: 13.269 + return "token.end-of-input"; 13.270 + case DOT: case COMMA: case SEMI: case LPAREN: case RPAREN: 13.271 + case LBRACKET: case RBRACKET: case LBRACE: case RBRACE: 13.272 + return "'" + name + "'"; 13.273 + default: 13.274 + return name; 13.275 + } 13.276 + } 13.277 + 13.278 + public String getKind() { 13.279 + return "Token"; 13.280 + } 13.281 + 13.282 + public String toString(Locale locale, Messages messages) { 13.283 + return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString()); 13.284 + } 13.285 + } 13.286 + 13.287 + /** 13.288 + * This is the class representing a javac token. Each token has several fields 13.289 + * that are set by the javac lexer (i.e. start/end position, string value, etc). 13.290 + */ 13.291 + public static class Token { 13.292 + 13.293 + /** tags constants **/ 13.294 + enum Tag { 13.295 + DEFAULT, 13.296 + NAMED, 13.297 + STRING, 13.298 + NUMERIC; 13.299 + } 13.300 + 13.301 + /** The token kind */ 13.302 + public final TokenKind kind; 13.303 + 13.304 + /** The start position of this token */ 13.305 + public final int pos; 13.306 + 13.307 + /** The end position of this token */ 13.308 + public final int endPos; 13.309 + 13.310 + /** Is this token preceeded by a deprecated comment? */ 13.311 + public final boolean deprecatedFlag; 13.312 + 13.313 + /** Is this token preceeded by a deprecated comment? */ 13.314 + public String docComment; 13.315 + 13.316 + Token(TokenKind kind, int pos, int endPos, 13.317 + boolean deprecatedFlag) { 13.318 + this.kind = kind; 13.319 + this.pos = pos; 13.320 + this.endPos = endPos; 13.321 + this.deprecatedFlag = deprecatedFlag; 13.322 + checkKind(); 13.323 + } 13.324 + 13.325 + Token[] split(Tokens tokens) { 13.326 + if (kind.name.length() < 2 || kind.tag != Tag.DEFAULT) { 13.327 + throw new AssertionError("Cant split" + kind); 13.328 + } 13.329 + 13.330 + TokenKind t1 = tokens.lookupKind(kind.name.substring(0, 1)); 13.331 + TokenKind t2 = tokens.lookupKind(kind.name.substring(1)); 13.332 + 13.333 + if (t1 == null || t2 == null) { 13.334 + throw new AssertionError("Cant split - bad subtokens"); 13.335 + } 13.336 + return new Token[] { 13.337 + new Token(t1, pos, pos + t1.name.length(), deprecatedFlag), 13.338 + new Token(t2, pos + t1.name.length(), endPos, false) 13.339 + }; 13.340 + } 13.341 + 13.342 + protected void checkKind() { 13.343 + if (kind.tag != Tag.DEFAULT) { 13.344 + throw new AssertionError("Bad token kind - expected " + Tag.STRING); 13.345 + } 13.346 + } 13.347 + 13.348 + public Name name() { 13.349 + throw new UnsupportedOperationException(); 13.350 + } 13.351 + 13.352 + public String stringVal() { 13.353 + throw new UnsupportedOperationException(); 13.354 + } 13.355 + 13.356 + public int radix() { 13.357 + throw new UnsupportedOperationException(); 13.358 + } 13.359 + } 13.360 + 13.361 + final static class NamedToken extends Token { 13.362 + /** The name of this token */ 13.363 + public final Name name; 13.364 + 13.365 + public NamedToken(TokenKind kind, int pos, int endPos, Name name, boolean deprecatedFlag) { 13.366 + super(kind, pos, endPos, deprecatedFlag); 13.367 + this.name = name; 13.368 + } 13.369 + 13.370 + protected void checkKind() { 13.371 + if (kind.tag != Tag.NAMED) { 13.372 + throw new AssertionError("Bad token kind - expected " + Tag.NAMED); 13.373 + } 13.374 + } 13.375 + 13.376 + @Override 13.377 + public Name name() { 13.378 + return name; 13.379 + } 13.380 + } 13.381 + 13.382 + static class StringToken extends Token { 13.383 + /** The string value of this token */ 13.384 + public final String stringVal; 13.385 + 13.386 + public StringToken(TokenKind kind, int pos, int endPos, String stringVal, boolean deprecatedFlag) { 13.387 + super(kind, pos, endPos, deprecatedFlag); 13.388 + this.stringVal = stringVal; 13.389 + } 13.390 + 13.391 + protected void checkKind() { 13.392 + if (kind.tag != Tag.STRING) { 13.393 + throw new AssertionError("Bad token kind - expected " + Tag.STRING); 13.394 + } 13.395 + } 13.396 + 13.397 + @Override 13.398 + public String stringVal() { 13.399 + return stringVal; 13.400 + } 13.401 + } 13.402 + 13.403 + final static class NumericToken extends StringToken { 13.404 + /** The 'radix' value of this token */ 13.405 + public final int radix; 13.406 + 13.407 + public NumericToken(TokenKind kind, int pos, int endPos, String stringVal, int radix, boolean deprecatedFlag) { 13.408 + super(kind, pos, endPos, stringVal, deprecatedFlag); 13.409 + this.radix = radix; 13.410 + } 13.411 + 13.412 + protected void checkKind() { 13.413 + if (kind.tag != Tag.NUMERIC) { 13.414 + throw new AssertionError("Bad token kind - expected " + Tag.NUMERIC); 13.415 + } 13.416 + } 13.417 + 13.418 + @Override 13.419 + public int radix() { 13.420 + return radix; 13.421 + } 13.422 + } 13.423 + 13.424 + public static final Token DUMMY = 13.425 + new Token(TokenKind.ERROR, 0, 0, false); 13.426 +}
14.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 14.2 +++ b/src/share/classes/com/sun/tools/javac/parser/UnicodeReader.java Mon Oct 24 13:00:20 2011 +0100 14.3 @@ -0,0 +1,227 @@ 14.4 +/* 14.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 14.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 14.7 + * 14.8 + * This code is free software; you can redistribute it and/or modify it 14.9 + * under the terms of the GNU General Public License version 2 only, as 14.10 + * published by the Free Software Foundation. Oracle designates this 14.11 + * particular file as subject to the "Classpath" exception as provided 14.12 + * by Oracle in the LICENSE file that accompanied this code. 14.13 + * 14.14 + * This code is distributed in the hope that it will be useful, but WITHOUT 14.15 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14.16 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14.17 + * version 2 for more details (a copy is included in the LICENSE file that 14.18 + * accompanied this code). 14.19 + * 14.20 + * You should have received a copy of the GNU General Public License version 14.21 + * 2 along with this work; if not, write to the Free Software Foundation, 14.22 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 14.23 + * 14.24 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 14.25 + * or visit www.oracle.com if you need additional information or have any 14.26 + * questions. 14.27 + */ 14.28 + 14.29 +package com.sun.tools.javac.parser; 14.30 + 14.31 +import com.sun.tools.javac.file.JavacFileManager; 14.32 +import java.nio.CharBuffer; 14.33 +import com.sun.tools.javac.util.Log; 14.34 +import static com.sun.tools.javac.util.LayoutCharacters.*; 14.35 + 14.36 +/** The char reader used by the javac lexer/tokenizer. Returns the sequence of 14.37 + * characters contained in the input stream, handling unicode escape accordingly. 14.38 + * Additionally, it provide features for saving chars into a buffer and to retrieve 14.39 + * them at a later stage. 14.40 + * 14.41 + * <p><b>This is NOT part of any supported API. 14.42 + * If you write code that depends on this, you do so at your own risk. 14.43 + * This code and its internal interfaces are subject to change or 14.44 + * deletion without notice.</b> 14.45 + */ 14.46 +public class UnicodeReader { 14.47 + 14.48 + /** The input buffer, index of next character to be read, 14.49 + * index of one past last character in buffer. 14.50 + */ 14.51 + protected char[] buf; 14.52 + protected int bp; 14.53 + protected final int buflen; 14.54 + 14.55 + /** The current character. 14.56 + */ 14.57 + protected char ch; 14.58 + 14.59 + /** The buffer index of the last converted unicode character 14.60 + */ 14.61 + protected int unicodeConversionBp = -1; 14.62 + 14.63 + protected Log log; 14.64 + 14.65 + /** 14.66 + * Create a scanner from the input array. This method might 14.67 + * modify the array. To avoid copying the input array, ensure 14.68 + * that {@code inputLength < input.length} or 14.69 + * {@code input[input.length -1]} is a white space character. 14.70 + * 14.71 + * @param fac the factory which created this Scanner 14.72 + * @param input the input, might be modified 14.73 + * @param inputLength the size of the input. 14.74 + * Must be positive and less than or equal to input.length. 14.75 + */ 14.76 + protected UnicodeReader(ScannerFactory sf, CharBuffer buffer) { 14.77 + this(sf, JavacFileManager.toArray(buffer), buffer.limit()); 14.78 + } 14.79 + 14.80 + protected UnicodeReader(ScannerFactory sf, char[] input, int inputLength) { 14.81 + log = sf.log; 14.82 + if (inputLength == input.length) { 14.83 + if (input.length > 0 && Character.isWhitespace(input[input.length - 1])) { 14.84 + inputLength--; 14.85 + } else { 14.86 + char[] newInput = new char[inputLength + 1]; 14.87 + System.arraycopy(input, 0, newInput, 0, input.length); 14.88 + input = newInput; 14.89 + } 14.90 + } 14.91 + buf = input; 14.92 + buflen = inputLength; 14.93 + buf[buflen] = EOI; 14.94 + bp = -1; 14.95 + scanChar(); 14.96 + } 14.97 + 14.98 + /** Read next character. 14.99 + */ 14.100 + protected void scanChar() { 14.101 + if (bp < buflen) { 14.102 + ch = buf[++bp]; 14.103 + if (ch == '\\') { 14.104 + convertUnicode(); 14.105 + } 14.106 + } 14.107 + } 14.108 + 14.109 + /** Convert unicode escape; bp points to initial '\' character 14.110 + * (Spec 3.3). 14.111 + */ 14.112 + protected void convertUnicode() { 14.113 + if (ch == '\\' && unicodeConversionBp != bp) { 14.114 + bp++; ch = buf[bp]; 14.115 + if (ch == 'u') { 14.116 + do { 14.117 + bp++; ch = buf[bp]; 14.118 + } while (ch == 'u'); 14.119 + int limit = bp + 3; 14.120 + if (limit < buflen) { 14.121 + int d = digit(bp, 16); 14.122 + int code = d; 14.123 + while (bp < limit && d >= 0) { 14.124 + bp++; ch = buf[bp]; 14.125 + d = digit(bp, 16); 14.126 + code = (code << 4) + d; 14.127 + } 14.128 + if (d >= 0) { 14.129 + ch = (char)code; 14.130 + unicodeConversionBp = bp; 14.131 + return; 14.132 + } 14.133 + } 14.134 + log.error(bp, "illegal.unicode.esc"); 14.135 + } else { 14.136 + bp--; 14.137 + ch = '\\'; 14.138 + } 14.139 + } 14.140 + } 14.141 + 14.142 + /** Are surrogates supported? 14.143 + */ 14.144 + final static boolean surrogatesSupported = surrogatesSupported(); 14.145 + private static boolean surrogatesSupported() { 14.146 + try { 14.147 + Character.isHighSurrogate('a'); 14.148 + return true; 14.149 + } catch (NoSuchMethodError ex) { 14.150 + return false; 14.151 + } 14.152 + } 14.153 + 14.154 + /** Scan surrogate pairs. If 'ch' is a high surrogate and 14.155 + * the next character is a low surrogate, then put the low 14.156 + * surrogate in 'ch', and return the high surrogate. 14.157 + * otherwise, just return 0. 14.158 + */ 14.159 + protected char scanSurrogates() { 14.160 + if (surrogatesSupported && Character.isHighSurrogate(ch)) { 14.161 + char high = ch; 14.162 + 14.163 + scanChar(); 14.164 + 14.165 + if (Character.isLowSurrogate(ch)) { 14.166 + return high; 14.167 + } 14.168 + 14.169 + ch = high; 14.170 + } 14.171 + 14.172 + return 0; 14.173 + } 14.174 + 14.175 + /** Convert an ASCII digit from its base (8, 10, or 16) 14.176 + * to its value. 14.177 + */ 14.178 + protected int digit(int pos, int base) { 14.179 + char c = ch; 14.180 + int result = Character.digit(c, base); 14.181 + if (result >= 0 && c > 0x7f) { 14.182 + log.error(pos + 1, "illegal.nonascii.digit"); 14.183 + ch = "0123456789abcdef".charAt(result); 14.184 + } 14.185 + return result; 14.186 + } 14.187 + 14.188 + protected boolean isUnicode() { 14.189 + return unicodeConversionBp == bp; 14.190 + } 14.191 + 14.192 + protected void skipChar() { 14.193 + bp++; 14.194 + } 14.195 + 14.196 + protected char peekChar() { 14.197 + return buf[bp + 1]; 14.198 + } 14.199 + 14.200 + /** 14.201 + * Returns a copy of the input buffer, up to its inputLength. 14.202 + * Unicode escape sequences are not translated. 14.203 + */ 14.204 + public char[] getRawCharacters() { 14.205 + char[] chars = new char[buflen]; 14.206 + System.arraycopy(buf, 0, chars, 0, buflen); 14.207 + return chars; 14.208 + } 14.209 + 14.210 + /** 14.211 + * Returns a copy of a character array subset of the input buffer. 14.212 + * The returned array begins at the <code>beginIndex</code> and 14.213 + * extends to the character at index <code>endIndex - 1</code>. 14.214 + * Thus the length of the substring is <code>endIndex-beginIndex</code>. 14.215 + * This behavior is like 14.216 + * <code>String.substring(beginIndex, endIndex)</code>. 14.217 + * Unicode escape sequences are not translated. 14.218 + * 14.219 + * @param beginIndex the beginning index, inclusive. 14.220 + * @param endIndex the ending index, exclusive. 14.221 + * @throws IndexOutOfBounds if either offset is outside of the 14.222 + * array bounds 14.223 + */ 14.224 + public char[] getRawCharacters(int beginIndex, int endIndex) { 14.225 + int length = endIndex - beginIndex; 14.226 + char[] chars = new char[length]; 14.227 + System.arraycopy(buf, beginIndex, chars, 0, length); 14.228 + return chars; 14.229 + } 14.230 +}
15.1 --- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Fri Oct 21 14:14:29 2011 -0700 15.2 +++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java Mon Oct 24 13:00:20 2011 +0100 15.3 @@ -1072,9 +1072,9 @@ 15.4 Assert.checkNonNull(names); 15.5 next.put(Names.namesKey, names); 15.6 15.7 - Keywords keywords = Keywords.instance(context); 15.8 - Assert.checkNonNull(keywords); 15.9 - next.put(Keywords.keywordsKey, keywords); 15.10 + Tokens tokens = Tokens.instance(context); 15.11 + Assert.checkNonNull(tokens); 15.12 + next.put(Tokens.tokensKey, tokens); 15.13 15.14 JavaCompiler oldCompiler = JavaCompiler.instance(context); 15.15 JavaCompiler nextCompiler = JavaCompiler.instance(next);
16.1 --- a/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Fri Oct 21 14:14:29 2011 -0700 16.2 +++ b/src/share/classes/com/sun/tools/javadoc/JavadocTool.java Mon Oct 24 13:00:20 2011 +0100 16.3 @@ -39,7 +39,6 @@ 16.4 16.5 import com.sun.tools.javac.code.Symbol.CompletionFailure; 16.6 import com.sun.tools.javac.comp.Annotate; 16.7 -import com.sun.tools.javac.parser.DocCommentScanner; 16.8 import com.sun.tools.javac.tree.JCTree; 16.9 import com.sun.tools.javac.tree.JCTree.JCClassDecl; 16.10 import com.sun.tools.javac.tree.JCTree.JCCompilationUnit;
17.1 --- a/test/tools/javac/api/TestJavacTaskScanner.java Fri Oct 21 14:14:29 2011 -0700 17.2 +++ b/test/tools/javac/api/TestJavacTaskScanner.java Mon Oct 24 13:00:20 2011 +0100 17.3 @@ -32,6 +32,7 @@ 17.4 17.5 import com.sun.tools.javac.api.JavacTaskImpl; 17.6 import com.sun.tools.javac.parser.*; 17.7 +import com.sun.tools.javac.parser.Tokens.Token; 17.8 import com.sun.tools.javac.util.*; 17.9 import java.io.*; 17.10 import java.net.*; 17.11 @@ -93,7 +94,7 @@ 17.12 17.13 check(numTokens, "#Tokens", 1222); 17.14 check(numParseTypeElements, "#parseTypeElements", 136); 17.15 - check(numAllMembers, "#allMembers", 67); 17.16 + check(numAllMembers, "#allMembers", 52); 17.17 } 17.18 17.19 void check(int value, String name, int expected) { 17.20 @@ -206,7 +207,8 @@ 17.21 17.22 public void nextToken() { 17.23 super.nextToken(); 17.24 - System.err.format("Saw token %s (%s)%n", token(), name()); 17.25 + Token tk = token(); 17.26 + System.err.format("Saw token %s %n", tk.kind); 17.27 test.numTokens++; 17.28 } 17.29
18.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 18.2 +++ b/test/tools/javac/depDocComment/DeprecatedDocComment3.java Mon Oct 24 13:00:20 2011 +0100 18.3 @@ -0,0 +1,41 @@ 18.4 +/* 18.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 18.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 18.7 + * 18.8 + * This code is free software; you can redistribute it and/or modify it 18.9 + * under the terms of the GNU General Public License version 2 only, as 18.10 + * published by the Free Software Foundation. 18.11 + * 18.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 18.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 18.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 18.15 + * version 2 for more details (a copy is included in the LICENSE file that 18.16 + * accompanied this code). 18.17 + * 18.18 + * You should have received a copy of the GNU General Public License version 18.19 + * 2 along with this work; if not, write to the Free Software Foundation, 18.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18.21 + * 18.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 18.23 + * or visit www.oracle.com if you need additional information or have any 18.24 + * questions. 18.25 + */ 18.26 + 18.27 +/** 18.28 + * @test 18.29 + * @bug 7096014 18.30 + * @summary Javac tokens should retain state 18.31 + * @compile -Xlint -Werror DeprecatedDocComment3.java 18.32 + */ 18.33 + 18.34 +class DeprecatedDocComment3 { 18.35 + static class Foo { } 18.36 + 18.37 + ; /** @deprecated */ ; 18.38 + 18.39 + static class A {} 18.40 + 18.41 + static class B { 18.42 + A a; //not deprecated! 18.43 + } 18.44 +}
19.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 19.2 +++ b/test/tools/javac/tree/DocCommentToplevelTest.java Mon Oct 24 13:00:20 2011 +0100 19.3 @@ -0,0 +1,196 @@ 19.4 +/* 19.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved. 19.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 19.7 + * 19.8 + * This code is free software; you can redistribute it and/or modify it 19.9 + * under the terms of the GNU General Public License version 2 only, as 19.10 + * published by the Free Software Foundation. 19.11 + * 19.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 19.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 19.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 19.15 + * version 2 for more details (a copy is included in the LICENSE file that 19.16 + * accompanied this code). 19.17 + * 19.18 + * You should have received a copy of the GNU General Public License version 19.19 + * 2 along with this work; if not, write to the Free Software Foundation, 19.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19.21 + * 19.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 19.23 + * or visit www.oracle.com if you need additional information or have any 19.24 + * questions. 19.25 + */ 19.26 + 19.27 +/* 19.28 + * @test 19.29 + * @bug 7096014 19.30 + * @summary Javac tokens should retain state 19.31 + */ 19.32 + 19.33 +import com.sun.source.tree.*; 19.34 +import com.sun.source.util.*; 19.35 +import com.sun.tools.javac.tree.JCTree; 19.36 + 19.37 +import java.net.URI; 19.38 +import java.util.*; 19.39 +import javax.tools.*; 19.40 + 19.41 + 19.42 +public class DocCommentToplevelTest { 19.43 + 19.44 + enum PackageKind { 19.45 + HAS_PKG("package pkg;"), 19.46 + NO_PKG(""); 19.47 + 19.48 + String pkgStr; 19.49 + 19.50 + PackageKind(String pkgStr) { 19.51 + this.pkgStr = pkgStr; 19.52 + } 19.53 + } 19.54 + 19.55 + enum ImportKind { 19.56 + ZERO(""), 19.57 + ONE("import java.lang.*;"), 19.58 + TWO("import java.lang.*; import java.util.*;"); 19.59 + 19.60 + String importStr; 19.61 + 19.62 + ImportKind(String importStr) { 19.63 + this.importStr = importStr; 19.64 + } 19.65 + } 19.66 + 19.67 + enum ModifierKind { 19.68 + DEFAULT(""), 19.69 + PUBLIC("public"); 19.70 + 19.71 + String modStr; 19.72 + 19.73 + ModifierKind(String modStr) { 19.74 + this.modStr = modStr; 19.75 + } 19.76 + } 19.77 + 19.78 + enum ToplevelDocKind { 19.79 + HAS_DOC("/** Toplevel! */"), 19.80 + NO_DOC(""); 19.81 + 19.82 + String docStr; 19.83 + 19.84 + ToplevelDocKind(String docStr) { 19.85 + this.docStr = docStr; 19.86 + } 19.87 + } 19.88 + 19.89 + static int errors; 19.90 + static int checks; 19.91 + 19.92 + public static void main(String... args) throws Exception { 19.93 + //create default shared JavaCompiler - reused across multiple compilations 19.94 + JavaCompiler comp = ToolProvider.getSystemJavaCompiler(); 19.95 + StandardJavaFileManager fm = comp.getStandardFileManager(null, null, null); 19.96 + 19.97 + for (PackageKind pk : PackageKind.values()) { 19.98 + for (ImportKind ik : ImportKind.values()) { 19.99 + for (ModifierKind mk1 : ModifierKind.values()) { 19.100 + for (ModifierKind mk2 : ModifierKind.values()) { 19.101 + for (ToplevelDocKind tdk : ToplevelDocKind.values()) { 19.102 + new DocCommentToplevelTest(pk, ik, mk1, mk2, tdk).run(comp, fm); 19.103 + } 19.104 + } 19.105 + } 19.106 + } 19.107 + } 19.108 + 19.109 + if (errors > 0) 19.110 + throw new AssertionError(errors + " errors found"); 19.111 + 19.112 + System.out.println(checks + " checks were made"); 19.113 + } 19.114 + 19.115 + PackageKind pk; 19.116 + ImportKind ik; 19.117 + ModifierKind mk1; 19.118 + ModifierKind mk2; 19.119 + ToplevelDocKind tdk; 19.120 + JavaSource source; 19.121 + 19.122 + DocCommentToplevelTest(PackageKind pk, ImportKind ik, ModifierKind mk1, ModifierKind mk2, ToplevelDocKind tdk) { 19.123 + this.pk = pk; 19.124 + this.ik = ik; 19.125 + this.mk1 = mk1; 19.126 + this.mk2 = mk2; 19.127 + this.tdk = tdk; 19.128 + source = new JavaSource(); 19.129 + } 19.130 + 19.131 + void run(JavaCompiler comp, JavaFileManager fm) throws Exception { 19.132 + JavacTask task = (JavacTask)comp.getTask(null, fm, null, Arrays.asList("-printsource"), null, Arrays.asList(source)); 19.133 + for (CompilationUnitTree cu: task.parse()) { 19.134 + check(cu); 19.135 + } 19.136 + } 19.137 + 19.138 + void check(CompilationUnitTree cu) { 19.139 + checks++; 19.140 + 19.141 + new TreeScanner<ClassTree,Void>() { 19.142 + 19.143 + Map<JCTree, String> docComments; 19.144 + 19.145 + @Override 19.146 + public ClassTree visitCompilationUnit(CompilationUnitTree node, Void unused) { 19.147 + docComments = ((JCTree.JCCompilationUnit)node).docComments; 19.148 + boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && 19.149 + (pk != PackageKind.NO_PKG || ik != ImportKind.ZERO); 19.150 + boolean foundComment = docComments.get(node) != null; 19.151 + if (expectedComment != foundComment) { 19.152 + error("Unexpected comment " + docComments.get(node) + " on toplevel"); 19.153 + } 19.154 + return super.visitCompilationUnit(node, null); 19.155 + } 19.156 + 19.157 + @Override 19.158 + public ClassTree visitClass(ClassTree node, Void unused) { 19.159 + boolean expectedComment = tdk == ToplevelDocKind.HAS_DOC && 19.160 + pk == PackageKind.NO_PKG && ik == ImportKind.ZERO && 19.161 + node.getSimpleName().toString().equals("First"); 19.162 + boolean foundComment = docComments.get(node) != null; 19.163 + if (expectedComment != foundComment) { 19.164 + error("Unexpected comment " + docComments.get(node) + " on class " + node.getSimpleName()); 19.165 + } 19.166 + return super.visitClass(node, unused); 19.167 + } 19.168 + }.scan(cu, null); 19.169 + } 19.170 + 19.171 + void error(String msg) { 19.172 + System.err.println("Error: " + msg); 19.173 + System.err.println("Source: " + source.source); 19.174 + errors++; 19.175 + } 19.176 + 19.177 + class JavaSource extends SimpleJavaFileObject { 19.178 + 19.179 + String template = "#D\n#P\n#I\n" + 19.180 + "#M1 class First { }\n" + 19.181 + "#M2 class Second { }\n"; 19.182 + 19.183 + String source; 19.184 + 19.185 + public JavaSource() { 19.186 + super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE); 19.187 + source = template.replace("#P", pk.pkgStr) 19.188 + .replace("#I", ik.importStr) 19.189 + .replace("#M1", mk1.modStr) 19.190 + .replace("#M2", mk2.modStr) 19.191 + .replace("#D", tdk.docStr); 19.192 + } 19.193 + 19.194 + @Override 19.195 + public CharSequence getCharContent(boolean ignoreEncodingErrors) { 19.196 + return source; 19.197 + } 19.198 + } 19.199 +}