src/share/classes/com/sun/tools/javac/parser/Tokens.java

Sat, 07 Nov 2020 10:30:02 +0800

author
aoqi
date
Sat, 07 Nov 2020 10:30:02 +0800
changeset 3938
93012e2a5d1d
parent 2525
2eb010b6cb22
permissions
-rw-r--r--

Added tag mips-jdk8u275-b01 for changeset eb6ee6a5f2fe

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 1999, 2013, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javac.parser;
aoqi@0 27
aoqi@0 28 import java.util.Locale;
aoqi@0 29
aoqi@0 30 import com.sun.tools.javac.api.Formattable;
aoqi@0 31 import com.sun.tools.javac.api.Messages;
aoqi@0 32 import com.sun.tools.javac.parser.Tokens.Token.Tag;
aoqi@0 33 import com.sun.tools.javac.util.List;
aoqi@0 34 import com.sun.tools.javac.util.Name;
aoqi@0 35 import com.sun.tools.javac.util.Context;
aoqi@0 36 import com.sun.tools.javac.util.Filter;
aoqi@0 37 import com.sun.tools.javac.util.ListBuffer;
aoqi@0 38 import com.sun.tools.javac.util.Names;
aoqi@0 39
aoqi@0 40 /** A class that defines codes/utilities for Java source tokens
aoqi@0 41 * returned from lexical analysis.
aoqi@0 42 *
aoqi@0 43 * <p><b>This is NOT part of any supported API.
aoqi@0 44 * If you write code that depends on this, you do so at your own risk.
aoqi@0 45 * This code and its internal interfaces are subject to change or
aoqi@0 46 * deletion without notice.</b>
aoqi@0 47 */
aoqi@0 48 public class Tokens {
aoqi@0 49
aoqi@0 50 private final Names names;
aoqi@0 51
aoqi@0 52 /**
aoqi@0 53 * Keyword array. Maps name indices to Token.
aoqi@0 54 */
aoqi@0 55 private final TokenKind[] key;
aoqi@0 56
aoqi@0 57 /** The number of the last entered keyword.
aoqi@0 58 */
aoqi@0 59 private int maxKey = 0;
aoqi@0 60
aoqi@0 61 /** The names of all tokens.
aoqi@0 62 */
aoqi@0 63 private Name[] tokenName = new Name[TokenKind.values().length];
aoqi@0 64
aoqi@0 65 public static final Context.Key<Tokens> tokensKey =
aoqi@0 66 new Context.Key<Tokens>();
aoqi@0 67
aoqi@0 68 public static Tokens instance(Context context) {
aoqi@0 69 Tokens instance = context.get(tokensKey);
aoqi@0 70 if (instance == null)
aoqi@0 71 instance = new Tokens(context);
aoqi@0 72 return instance;
aoqi@0 73 }
aoqi@0 74
aoqi@0 75 protected Tokens(Context context) {
aoqi@0 76 context.put(tokensKey, this);
aoqi@0 77 names = Names.instance(context);
aoqi@0 78 for (TokenKind t : TokenKind.values()) {
aoqi@0 79 if (t.name != null)
aoqi@0 80 enterKeyword(t.name, t);
aoqi@0 81 else
aoqi@0 82 tokenName[t.ordinal()] = null;
aoqi@0 83 }
aoqi@0 84
aoqi@0 85 key = new TokenKind[maxKey+1];
aoqi@0 86 for (int i = 0; i <= maxKey; i++) key[i] = TokenKind.IDENTIFIER;
aoqi@0 87 for (TokenKind t : TokenKind.values()) {
aoqi@0 88 if (t.name != null)
aoqi@0 89 key[tokenName[t.ordinal()].getIndex()] = t;
aoqi@0 90 }
aoqi@0 91 }
aoqi@0 92
aoqi@0 93 private void enterKeyword(String s, TokenKind token) {
aoqi@0 94 Name n = names.fromString(s);
aoqi@0 95 tokenName[token.ordinal()] = n;
aoqi@0 96 if (n.getIndex() > maxKey) maxKey = n.getIndex();
aoqi@0 97 }
aoqi@0 98
aoqi@0 99 /**
aoqi@0 100 * Create a new token given a name; if the name corresponds to a token name,
aoqi@0 101 * a new token of the corresponding kind is returned; otherwise, an
aoqi@0 102 * identifier token is returned.
aoqi@0 103 */
aoqi@0 104 TokenKind lookupKind(Name name) {
aoqi@0 105 return (name.getIndex() > maxKey) ? TokenKind.IDENTIFIER : key[name.getIndex()];
aoqi@0 106 }
aoqi@0 107
aoqi@0 108 TokenKind lookupKind(String name) {
aoqi@0 109 return lookupKind(names.fromString(name));
aoqi@0 110 }
aoqi@0 111
aoqi@0 112 /**
aoqi@0 113 * This enum defines all tokens used by the javac scanner. A token is
aoqi@0 114 * optionally associated with a name.
aoqi@0 115 */
aoqi@0 116 public enum TokenKind implements Formattable, Filter<TokenKind> {
aoqi@0 117 EOF(),
aoqi@0 118 ERROR(),
aoqi@0 119 IDENTIFIER(Tag.NAMED),
aoqi@0 120 ABSTRACT("abstract"),
aoqi@0 121 ASSERT("assert", Tag.NAMED),
aoqi@0 122 BOOLEAN("boolean", Tag.NAMED),
aoqi@0 123 BREAK("break"),
aoqi@0 124 BYTE("byte", Tag.NAMED),
aoqi@0 125 CASE("case"),
aoqi@0 126 CATCH("catch"),
aoqi@0 127 CHAR("char", Tag.NAMED),
aoqi@0 128 CLASS("class"),
aoqi@0 129 CONST("const"),
aoqi@0 130 CONTINUE("continue"),
aoqi@0 131 DEFAULT("default"),
aoqi@0 132 DO("do"),
aoqi@0 133 DOUBLE("double", Tag.NAMED),
aoqi@0 134 ELSE("else"),
aoqi@0 135 ENUM("enum", Tag.NAMED),
aoqi@0 136 EXTENDS("extends"),
aoqi@0 137 FINAL("final"),
aoqi@0 138 FINALLY("finally"),
aoqi@0 139 FLOAT("float", Tag.NAMED),
aoqi@0 140 FOR("for"),
aoqi@0 141 GOTO("goto"),
aoqi@0 142 IF("if"),
aoqi@0 143 IMPLEMENTS("implements"),
aoqi@0 144 IMPORT("import"),
aoqi@0 145 INSTANCEOF("instanceof"),
aoqi@0 146 INT("int", Tag.NAMED),
aoqi@0 147 INTERFACE("interface"),
aoqi@0 148 LONG("long", Tag.NAMED),
aoqi@0 149 NATIVE("native"),
aoqi@0 150 NEW("new"),
aoqi@0 151 PACKAGE("package"),
aoqi@0 152 PRIVATE("private"),
aoqi@0 153 PROTECTED("protected"),
aoqi@0 154 PUBLIC("public"),
aoqi@0 155 RETURN("return"),
aoqi@0 156 SHORT("short", Tag.NAMED),
aoqi@0 157 STATIC("static"),
aoqi@0 158 STRICTFP("strictfp"),
aoqi@0 159 SUPER("super", Tag.NAMED),
aoqi@0 160 SWITCH("switch"),
aoqi@0 161 SYNCHRONIZED("synchronized"),
aoqi@0 162 THIS("this", Tag.NAMED),
aoqi@0 163 THROW("throw"),
aoqi@0 164 THROWS("throws"),
aoqi@0 165 TRANSIENT("transient"),
aoqi@0 166 TRY("try"),
aoqi@0 167 VOID("void", Tag.NAMED),
aoqi@0 168 VOLATILE("volatile"),
aoqi@0 169 WHILE("while"),
aoqi@0 170 INTLITERAL(Tag.NUMERIC),
aoqi@0 171 LONGLITERAL(Tag.NUMERIC),
aoqi@0 172 FLOATLITERAL(Tag.NUMERIC),
aoqi@0 173 DOUBLELITERAL(Tag.NUMERIC),
aoqi@0 174 CHARLITERAL(Tag.NUMERIC),
aoqi@0 175 STRINGLITERAL(Tag.STRING),
aoqi@0 176 TRUE("true", Tag.NAMED),
aoqi@0 177 FALSE("false", Tag.NAMED),
aoqi@0 178 NULL("null", Tag.NAMED),
aoqi@0 179 UNDERSCORE("_", Tag.NAMED),
aoqi@0 180 ARROW("->"),
aoqi@0 181 COLCOL("::"),
aoqi@0 182 LPAREN("("),
aoqi@0 183 RPAREN(")"),
aoqi@0 184 LBRACE("{"),
aoqi@0 185 RBRACE("}"),
aoqi@0 186 LBRACKET("["),
aoqi@0 187 RBRACKET("]"),
aoqi@0 188 SEMI(";"),
aoqi@0 189 COMMA(","),
aoqi@0 190 DOT("."),
aoqi@0 191 ELLIPSIS("..."),
aoqi@0 192 EQ("="),
aoqi@0 193 GT(">"),
aoqi@0 194 LT("<"),
aoqi@0 195 BANG("!"),
aoqi@0 196 TILDE("~"),
aoqi@0 197 QUES("?"),
aoqi@0 198 COLON(":"),
aoqi@0 199 EQEQ("=="),
aoqi@0 200 LTEQ("<="),
aoqi@0 201 GTEQ(">="),
aoqi@0 202 BANGEQ("!="),
aoqi@0 203 AMPAMP("&&"),
aoqi@0 204 BARBAR("||"),
aoqi@0 205 PLUSPLUS("++"),
aoqi@0 206 SUBSUB("--"),
aoqi@0 207 PLUS("+"),
aoqi@0 208 SUB("-"),
aoqi@0 209 STAR("*"),
aoqi@0 210 SLASH("/"),
aoqi@0 211 AMP("&"),
aoqi@0 212 BAR("|"),
aoqi@0 213 CARET("^"),
aoqi@0 214 PERCENT("%"),
aoqi@0 215 LTLT("<<"),
aoqi@0 216 GTGT(">>"),
aoqi@0 217 GTGTGT(">>>"),
aoqi@0 218 PLUSEQ("+="),
aoqi@0 219 SUBEQ("-="),
aoqi@0 220 STAREQ("*="),
aoqi@0 221 SLASHEQ("/="),
aoqi@0 222 AMPEQ("&="),
aoqi@0 223 BAREQ("|="),
aoqi@0 224 CARETEQ("^="),
aoqi@0 225 PERCENTEQ("%="),
aoqi@0 226 LTLTEQ("<<="),
aoqi@0 227 GTGTEQ(">>="),
aoqi@0 228 GTGTGTEQ(">>>="),
aoqi@0 229 MONKEYS_AT("@"),
aoqi@0 230 CUSTOM;
aoqi@0 231
aoqi@0 232 public final String name;
aoqi@0 233 public final Tag tag;
aoqi@0 234
aoqi@0 235 TokenKind() {
aoqi@0 236 this(null, Tag.DEFAULT);
aoqi@0 237 }
aoqi@0 238
aoqi@0 239 TokenKind(String name) {
aoqi@0 240 this(name, Tag.DEFAULT);
aoqi@0 241 }
aoqi@0 242
aoqi@0 243 TokenKind(Tag tag) {
aoqi@0 244 this(null, tag);
aoqi@0 245 }
aoqi@0 246
aoqi@0 247 TokenKind(String name, Tag tag) {
aoqi@0 248 this.name = name;
aoqi@0 249 this.tag = tag;
aoqi@0 250 }
aoqi@0 251
aoqi@0 252 public String toString() {
aoqi@0 253 switch (this) {
aoqi@0 254 case IDENTIFIER:
aoqi@0 255 return "token.identifier";
aoqi@0 256 case CHARLITERAL:
aoqi@0 257 return "token.character";
aoqi@0 258 case STRINGLITERAL:
aoqi@0 259 return "token.string";
aoqi@0 260 case INTLITERAL:
aoqi@0 261 return "token.integer";
aoqi@0 262 case LONGLITERAL:
aoqi@0 263 return "token.long-integer";
aoqi@0 264 case FLOATLITERAL:
aoqi@0 265 return "token.float";
aoqi@0 266 case DOUBLELITERAL:
aoqi@0 267 return "token.double";
aoqi@0 268 case ERROR:
aoqi@0 269 return "token.bad-symbol";
aoqi@0 270 case EOF:
aoqi@0 271 return "token.end-of-input";
aoqi@0 272 case DOT: case COMMA: case SEMI: case LPAREN: case RPAREN:
aoqi@0 273 case LBRACKET: case RBRACKET: case LBRACE: case RBRACE:
aoqi@0 274 return "'" + name + "'";
aoqi@0 275 default:
aoqi@0 276 return name;
aoqi@0 277 }
aoqi@0 278 }
aoqi@0 279
aoqi@0 280 public String getKind() {
aoqi@0 281 return "Token";
aoqi@0 282 }
aoqi@0 283
aoqi@0 284 public String toString(Locale locale, Messages messages) {
aoqi@0 285 return name != null ? toString() : messages.getLocalizedString(locale, "compiler.misc." + toString());
aoqi@0 286 }
aoqi@0 287
aoqi@0 288 @Override
aoqi@0 289 public boolean accepts(TokenKind that) {
aoqi@0 290 return this == that;
aoqi@0 291 }
aoqi@0 292 }
aoqi@0 293
aoqi@0 294 public interface Comment {
aoqi@0 295
aoqi@0 296 enum CommentStyle {
aoqi@0 297 LINE,
aoqi@0 298 BLOCK,
aoqi@0 299 JAVADOC,
aoqi@0 300 }
aoqi@0 301
aoqi@0 302 String getText();
aoqi@0 303 int getSourcePos(int index);
aoqi@0 304 CommentStyle getStyle();
aoqi@0 305 boolean isDeprecated();
aoqi@0 306 }
aoqi@0 307
aoqi@0 308 /**
aoqi@0 309 * This is the class representing a javac token. Each token has several fields
aoqi@0 310 * that are set by the javac lexer (i.e. start/end position, string value, etc).
aoqi@0 311 */
aoqi@0 312 public static class Token {
aoqi@0 313
aoqi@0 314 /** tags constants **/
aoqi@0 315 enum Tag {
aoqi@0 316 DEFAULT,
aoqi@0 317 NAMED,
aoqi@0 318 STRING,
aoqi@0 319 NUMERIC;
aoqi@0 320 }
aoqi@0 321
aoqi@0 322 /** The token kind */
aoqi@0 323 public final TokenKind kind;
aoqi@0 324
aoqi@0 325 /** The start position of this token */
aoqi@0 326 public final int pos;
aoqi@0 327
aoqi@0 328 /** The end position of this token */
aoqi@0 329 public final int endPos;
aoqi@0 330
aoqi@0 331 /** Comment reader associated with this token */
aoqi@0 332 public final List<Comment> comments;
aoqi@0 333
aoqi@0 334 Token(TokenKind kind, int pos, int endPos, List<Comment> comments) {
aoqi@0 335 this.kind = kind;
aoqi@0 336 this.pos = pos;
aoqi@0 337 this.endPos = endPos;
aoqi@0 338 this.comments = comments;
aoqi@0 339 checkKind();
aoqi@0 340 }
aoqi@0 341
aoqi@0 342 Token[] split(Tokens tokens) {
aoqi@0 343 if (kind.name.length() < 2 || kind.tag != Tag.DEFAULT) {
aoqi@0 344 throw new AssertionError("Cant split" + kind);
aoqi@0 345 }
aoqi@0 346
aoqi@0 347 TokenKind t1 = tokens.lookupKind(kind.name.substring(0, 1));
aoqi@0 348 TokenKind t2 = tokens.lookupKind(kind.name.substring(1));
aoqi@0 349
aoqi@0 350 if (t1 == null || t2 == null) {
aoqi@0 351 throw new AssertionError("Cant split - bad subtokens");
aoqi@0 352 }
aoqi@0 353 return new Token[] {
aoqi@0 354 new Token(t1, pos, pos + t1.name.length(), comments),
aoqi@0 355 new Token(t2, pos + t1.name.length(), endPos, null)
aoqi@0 356 };
aoqi@0 357 }
aoqi@0 358
aoqi@0 359 protected void checkKind() {
aoqi@0 360 if (kind.tag != Tag.DEFAULT) {
aoqi@0 361 throw new AssertionError("Bad token kind - expected " + Tag.STRING);
aoqi@0 362 }
aoqi@0 363 }
aoqi@0 364
aoqi@0 365 public Name name() {
aoqi@0 366 throw new UnsupportedOperationException();
aoqi@0 367 }
aoqi@0 368
aoqi@0 369 public String stringVal() {
aoqi@0 370 throw new UnsupportedOperationException();
aoqi@0 371 }
aoqi@0 372
aoqi@0 373 public int radix() {
aoqi@0 374 throw new UnsupportedOperationException();
aoqi@0 375 }
aoqi@0 376
aoqi@0 377 /**
aoqi@0 378 * Preserve classic semantics - if multiple javadocs are found on the token
aoqi@0 379 * the last one is returned
aoqi@0 380 */
aoqi@0 381 public Comment comment(Comment.CommentStyle style) {
aoqi@0 382 List<Comment> comments = getComments(Comment.CommentStyle.JAVADOC);
aoqi@0 383 return comments.isEmpty() ?
aoqi@0 384 null :
aoqi@0 385 comments.head;
aoqi@0 386 }
aoqi@0 387
aoqi@0 388 /**
aoqi@0 389 * Preserve classic semantics - deprecated should be set if at least one
aoqi@0 390 * javadoc comment attached to this token contains the '@deprecated' string
aoqi@0 391 */
aoqi@0 392 public boolean deprecatedFlag() {
aoqi@0 393 for (Comment c : getComments(Comment.CommentStyle.JAVADOC)) {
aoqi@0 394 if (c.isDeprecated()) {
aoqi@0 395 return true;
aoqi@0 396 }
aoqi@0 397 }
aoqi@0 398 return false;
aoqi@0 399 }
aoqi@0 400
aoqi@0 401 private List<Comment> getComments(Comment.CommentStyle style) {
aoqi@0 402 if (comments == null) {
aoqi@0 403 return List.nil();
aoqi@0 404 } else {
aoqi@0 405 ListBuffer<Comment> buf = new ListBuffer<>();
aoqi@0 406 for (Comment c : comments) {
aoqi@0 407 if (c.getStyle() == style) {
aoqi@0 408 buf.add(c);
aoqi@0 409 }
aoqi@0 410 }
aoqi@0 411 return buf.toList();
aoqi@0 412 }
aoqi@0 413 }
aoqi@0 414 }
aoqi@0 415
aoqi@0 416 final static class NamedToken extends Token {
aoqi@0 417 /** The name of this token */
aoqi@0 418 public final Name name;
aoqi@0 419
aoqi@0 420 public NamedToken(TokenKind kind, int pos, int endPos, Name name, List<Comment> comments) {
aoqi@0 421 super(kind, pos, endPos, comments);
aoqi@0 422 this.name = name;
aoqi@0 423 }
aoqi@0 424
aoqi@0 425 protected void checkKind() {
aoqi@0 426 if (kind.tag != Tag.NAMED) {
aoqi@0 427 throw new AssertionError("Bad token kind - expected " + Tag.NAMED);
aoqi@0 428 }
aoqi@0 429 }
aoqi@0 430
aoqi@0 431 @Override
aoqi@0 432 public Name name() {
aoqi@0 433 return name;
aoqi@0 434 }
aoqi@0 435 }
aoqi@0 436
aoqi@0 437 static class StringToken extends Token {
aoqi@0 438 /** The string value of this token */
aoqi@0 439 public final String stringVal;
aoqi@0 440
aoqi@0 441 public StringToken(TokenKind kind, int pos, int endPos, String stringVal, List<Comment> comments) {
aoqi@0 442 super(kind, pos, endPos, comments);
aoqi@0 443 this.stringVal = stringVal;
aoqi@0 444 }
aoqi@0 445
aoqi@0 446 protected void checkKind() {
aoqi@0 447 if (kind.tag != Tag.STRING) {
aoqi@0 448 throw new AssertionError("Bad token kind - expected " + Tag.STRING);
aoqi@0 449 }
aoqi@0 450 }
aoqi@0 451
aoqi@0 452 @Override
aoqi@0 453 public String stringVal() {
aoqi@0 454 return stringVal;
aoqi@0 455 }
aoqi@0 456 }
aoqi@0 457
aoqi@0 458 final static class NumericToken extends StringToken {
aoqi@0 459 /** The 'radix' value of this token */
aoqi@0 460 public final int radix;
aoqi@0 461
aoqi@0 462 public NumericToken(TokenKind kind, int pos, int endPos, String stringVal, int radix, List<Comment> comments) {
aoqi@0 463 super(kind, pos, endPos, stringVal, comments);
aoqi@0 464 this.radix = radix;
aoqi@0 465 }
aoqi@0 466
aoqi@0 467 protected void checkKind() {
aoqi@0 468 if (kind.tag != Tag.NUMERIC) {
aoqi@0 469 throw new AssertionError("Bad token kind - expected " + Tag.NUMERIC);
aoqi@0 470 }
aoqi@0 471 }
aoqi@0 472
aoqi@0 473 @Override
aoqi@0 474 public int radix() {
aoqi@0 475 return radix;
aoqi@0 476 }
aoqi@0 477 }
aoqi@0 478
aoqi@0 479 public static final Token DUMMY =
aoqi@0 480 new Token(TokenKind.ERROR, 0, 0, null);
aoqi@0 481 }

mercurial