4375N/A * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved. 0N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 0N/A * This code is free software; you can redistribute it and/or modify it 0N/A * under the terms of the GNU General Public License version 2 only, as 2362N/A * published by the Free Software Foundation. Oracle designates this 0N/A * particular file as subject to the "Classpath" exception as provided 2362N/A * by Oracle in the LICENSE file that accompanied this code. 0N/A * This code is distributed in the hope that it will be useful, but WITHOUT 0N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 0N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 0N/A * version 2 for more details (a copy is included in the LICENSE file that 0N/A * accompanied this code). 0N/A * You should have received a copy of the GNU General Public License version 0N/A * 2 along with this work; if not, write to the Free Software Foundation, 0N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 2362N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 2362N/A * or visit www.oracle.com if you need additional information or have any 0N/A * Parser for type signatures, as defined in the Java Virtual 4375N/A * Machine Specification (JVMS) chapter 4. 0N/A * Converts the signatures into an abstract syntax tree (AST) representation. 4375N/A * See the package sun.reflect.generics.tree for details of the AST. 0N/A // The input is conceptually a character stream (though currently it's 0N/A // a string). This is slightly different than traditional parsers, 0N/A // because there is no lexical scanner performing tokenization. 0N/A // Having a separate tokenizer does not fit with the nature of the 0N/A // Other than the absence of a tokenizer, this parser is a classic 0N/A // recursive descent parser. Its structure corresponds as closely 0N/A // as possible to the grammar in the JVMS. 0N/A // A note on asserts vs. errors: The code contains assertions 0N/A // in situations that should never occur. An assertion failure 0N/A // indicates a failure of the parser logic. A common pattern 0N/A // is an assertion that the current input is a particular 0N/A // character. This is often paired with a separate check 0N/A // that this is the case, which seems redundant. For example: 0N/A // assert(current() != x); 0N/A // if (current != x {error("expected an x"); 0N/A // where x is some character constant. 4375N/A // The assertion indicates, that, as currently written, 4375N/A // the code should never reach this point unless the input is an 0N/A // x. On the other hand, the test is there to check the legality 0N/A // of the input wrt to a given production. It may be that at a later 0N/A // time the code might be called directly, and if the input is 0N/A // invalid, the parser should flag an error in accordance 0N/A private char[]
input;
// the input signature 0N/A private int index =
0;
// index into the input 4375N/A // used to mark end of input 0N/A private static final char EOI =
':';
0N/A private static final boolean DEBUG =
false;
0N/A // private constructor - enforces use of static factory 0N/A // Most parsing routines use the following routines to access the 0N/A // input stream, and advance it as necessary. 0N/A // This makes it easy to adapt the parser to operate on streams 0N/A // of various kinds as well as strings. 0N/A // returns current element of the input and advances the input 0N/A // returns current element of the input 0N/A // advance the input 4375N/A // For debugging, prints current character to the end of the input. 0N/A // Match c against a "set" of characters 0N/A if (c == e)
return true;
0N/A // Error handling routine. Encapsulates error handling. 0N/A // Takes a string error message as argument. 0N/A // Currently throws a GenericSignatureFormatError. 4375N/A * Verify the parse has made forward progress; throw an exception 0N/A * Static factory method. Produces a parser instance. 0N/A * @return an instance of <tt>SignatureParser</tt> 0N/A * Parses a class signature (as defined in the JVMS, chapter 4) 0N/A * and produces an abstract syntax tree representing it. 0N/A * @param s a string representing the input class signature 0N/A * @return An abstract syntax tree for a class signature 0N/A * corresponding to the input string 0N/A * @throws GenericSignatureFormatError if the input is not a valid 0N/A * Parses a method signature (as defined in the JVMS, chapter 4) 0N/A * and produces an abstract syntax tree representing it. 0N/A * @param s a string representing the input method signature 0N/A * @return An abstract syntax tree for a method signature 0N/A * corresponding to the input string 0N/A * @throws GenericSignatureFormatError if the input is not a valid 0N/A * Parses a type signature 0N/A * and produces an abstract syntax tree representing it. 0N/A * @param s a string representing the input type signature 0N/A * @return An abstract syntax tree for a type signature 0N/A * corresponding to the input string 0N/A * @throws GenericSignatureFormatError if the input is not a valid 0N/A // Parsing routines. 0N/A // As a rule, the parsing routines access the input using the 0N/A // utilities current(), getNext() and/or advance(). 0N/A // The convention is that when a parsing routine is invoked 0N/A // it expects the current input to be the first character it should parse 0N/A // and when it completes parsing, it leaves the input at the first 0N/A // character after the input parses. 4375N/A * Note on grammar conventions: a trailing "*" matches zero or 4375N/A * more occurrences, a trailing "+" matches one or more occurrences, 4375N/A * "_opt" indicates an optional component. 4375N/A * FormalTypeParameters_opt SuperclassSignature SuperinterfaceSignature* 4375N/A // parse a class signature based on the implicit input. 4375N/A * "<" FormalTypeParameter+ ">" 0N/A assert(
current() ==
'<');
// should not have been called at all 4375N/A * Identifier ClassBound InterfaceBound* 0N/A default:
throw error(
"Expected Field Type Signature");
4375N/A * "L" PackageSpecifier_opt SimpleClassTypeSignature ClassTypeSignatureSuffix* ";" 4375N/A * Identifier "/" PackageSpecifier* 4375N/A // Parse both any optional leading PackageSpecifier as well as 4375N/A // the following SimpleClassTypeSignature. 4375N/A * SimpleClassTypeSignature: 4375N/A * Identifier TypeArguments_opt 4375N/A throw error(
"expected '<' or ';' or '.', got '" + c +
"'.");
4375N/A * ClassTypeSignatureSuffix: 4375N/A * "." SimpleClassTypeSignature 0N/A //(matches(current(), '+', '-', 'L', '[', 'T', '*')) { 4375N/A * WildcardIndicator_opt FieldTypeSignature 0N/A throw error(
"; expected in signature of type variable named" +
4375N/A * ":" FieldTypeSignature_opt 0N/A case ':':
// empty class bound 0N/A default:
// parse class bound 0N/A // zero or more interface bounds 4375N/A * FormalTypeParameters_opt "(" TypeSignature* ")" ReturnType ThrowsSignature* 4375N/A // Parse a method signature based on the implicit input. 4375N/A * "^" TypeVariableSignature