1adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/*
2adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
3adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
4adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
5adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * you may not use this file except in compliance with the License.
6adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * You may obtain a copy of the License at
7adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
8adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
9adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
10adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Unless required by applicable law or agreed to in writing, software
11adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
12adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * See the License for the specific language governing permissions and
14adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * limitations under the License.
15adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
16adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
17adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpackage org.apache.harmony.luni.lang.reflect;
18adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
19adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Constructor;
20adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.GenericDeclaration;
21adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.GenericSignatureFormatError;
22adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Method;
23adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.Type;
24adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectimport java.lang.reflect.TypeVariable;
25adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
26adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project/**
27adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * Implements a parser for the generics signature attribute.
285558f048777e00c8ecb389482b947bea4a1fd589Elliott Hughes * Uses a top-down, recursive descent parsing approach for the following grammar:
29adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * <pre>
30f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * ClassSignature ::=
31adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     OptFormalTypeParams SuperclassSignature {SuperinterfaceSignature}.
32adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SuperclassSignature ::= ClassTypeSignature.
33adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * SuperinterfaceSignature ::= ClassTypeSignature.
34adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
35f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * OptFormalTypeParams ::=
36adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     ["<" FormalTypeParameter {FormalTypeParameter} ">"].
37adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
38adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * FormalTypeParameter ::= Ident ClassBound {InterfaceBound}.
39adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ClassBound ::= ":" [FieldTypeSignature].
40adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * InterfaceBound ::= ":" FieldTypeSignature.
41adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
42f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * FieldTypeSignature ::=
43adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     ClassTypeSignature | ArrayTypeSignature | TypeVariableSignature.
44adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ArrayTypeSignature ::= "[" TypSignature.
45adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
46f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * ClassTypeSignature ::=
47adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     "L" {Ident "/"} Ident OptTypeArguments {"." Ident OptTypeArguments} ";".
48adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
49adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * OptTypeArguments ::= "<" TypeArgument {TypeArgument} ">".
50adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
51adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TypeArgument ::= ([WildcardIndicator] FieldTypeSignature) | "*".
52adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * WildcardIndicator ::= "+" | "-".
53adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
54adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TypeVariableSignature ::= "T" Ident ";".
55adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
56adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * TypSignature ::= FieldTypeSignature | BaseType.
57adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * BaseType ::= "B" | "C" | "D" | "F" | "I" | "J" | "S" | "Z".
58adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
59f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes * MethodTypeSignature ::=
60adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *     OptFormalTypeParams "(" {TypeSignature} ")" ReturnType {ThrowsSignature}.
61adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ThrowsSignature ::= ("^" ClassTypeSignature) | ("^" TypeVariableSignature).
62adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project *
63adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * ReturnType ::= TypSignature | VoidDescriptor.
64adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * VoidDescriptor ::= "V".
65adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project * </pre>
66adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project */
67adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Projectpublic class GenericSignatureParser {
68adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
69adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ListOfTypes exceptionTypes;
70adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ListOfTypes parameterTypes;
71adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public TypeVariable[] formalTypeParameters;
72adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Type returnType;
73adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Type fieldType;
74adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ListOfTypes interfaceTypes;
75adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public Type superclassType;
76adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public ClassLoader loader;
77f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
78adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    GenericDeclaration genericDecl;
79adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
80adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /*
81adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Parser:
82adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
83adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    char symbol; // 0: eof; else valid term symbol or first char of identifier.
84adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    String identifier;
85adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
86adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
87f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    /*
88adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Scanner:
89adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * eof is private to the scan methods
90adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * and it's set only when a scan is issued at the end of the buffer.
91adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
92adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    private boolean eof;
93adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
94adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    char[] buffer;
95adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    int pos;
96adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
97adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    public GenericSignatureParser(ClassLoader loader) {
98adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.loader = loader;
99adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
100adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
101adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void setInput(GenericDeclaration genericDecl, String input) {
102adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (input != null) {
103adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.genericDecl = genericDecl;
104adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.buffer = input.toCharArray();
105adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.eof = false;
106adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
107adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
108adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
109adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.eof = true;
110adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
111adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
112adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
113adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
114adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Parses the generic signature of a class and creates the data structure
115adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representing the signature.
116f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
117adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param genericDecl the GenericDeclaration calling this method
118adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param signature the generic signature of the class
119adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
120f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public void parseForClass(GenericDeclaration genericDecl,
121adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String signature) {
122adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setInput(genericDecl, signature);
123adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!eof) {
124adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parseClassSignature();
125adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
126adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(genericDecl instanceof Class) {
127adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Class c = (Class) genericDecl;
1286aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes                this.formalTypeParameters = ListOfVariables.EMPTY;
129adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.superclassType = c.getSuperclass();
130adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.interfaceTypes = new ListOfTypes(c.getInterfaces());
131adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1326aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes                this.formalTypeParameters = ListOfVariables.EMPTY;
133adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.superclassType = Object.class;
134297f4f85f303725a64c2038ff81c0d1be1f10560Jesse Wilson                this.interfaceTypes = ListOfTypes.EMPTY;
135adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
136adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
137adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
138adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
139adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
140adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * Parses the generic signature of a method and creates the data structure
141adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representing the signature.
142f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
143adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param genericDecl the GenericDeclaration calling this method
144adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param signature the generic signature of the class
145adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
146f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public void parseForMethod(GenericDeclaration genericDecl,
14798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            String signature, Class<?>[] rawExceptionTypes) {
148adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setInput(genericDecl, signature);
149adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!eof) {
15098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            parseMethodTypeSignature(rawExceptionTypes);
151adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
152adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(genericDecl instanceof Method) {
153adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Method m = (Method) genericDecl;
1546aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes                this.formalTypeParameters = ListOfVariables.EMPTY;
155adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.parameterTypes = new ListOfTypes(m.getParameterTypes());
156adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.exceptionTypes = new ListOfTypes(m.getExceptionTypes());
157adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.returnType = m.getReturnType();
158adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1596aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes                this.formalTypeParameters = ListOfVariables.EMPTY;
160297f4f85f303725a64c2038ff81c0d1be1f10560Jesse Wilson                this.parameterTypes = ListOfTypes.EMPTY;
161297f4f85f303725a64c2038ff81c0d1be1f10560Jesse Wilson                this.exceptionTypes = ListOfTypes.EMPTY;
162adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.returnType = void.class;
163adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
164adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
165adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
166f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes
167adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
168f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * Parses the generic signature of a constructor and creates the data
169adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * structure representing the signature.
170f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
171adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param genericDecl the GenericDeclaration calling this method
172adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param signature the generic signature of the class
173adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
174f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public void parseForConstructor(GenericDeclaration genericDecl,
17598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            String signature, Class<?>[] rawExceptionTypes) {
176adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setInput(genericDecl, signature);
177adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!eof) {
17898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            parseMethodTypeSignature(rawExceptionTypes);
179adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
180adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if(genericDecl instanceof Constructor) {
181adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                Constructor c = (Constructor) genericDecl;
1826aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes                this.formalTypeParameters = ListOfVariables.EMPTY;
183adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.parameterTypes = new ListOfTypes(c.getParameterTypes());
184adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                this.exceptionTypes = new ListOfTypes(c.getExceptionTypes());
185adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
1866aa068b481cc4cca7765ce90fdf32f3eb2b5a77cElliott Hughes                this.formalTypeParameters = ListOfVariables.EMPTY;
187297f4f85f303725a64c2038ff81c0d1be1f10560Jesse Wilson                this.parameterTypes = ListOfTypes.EMPTY;
188297f4f85f303725a64c2038ff81c0d1be1f10560Jesse Wilson                this.exceptionTypes = ListOfTypes.EMPTY;
189adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
190adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
191adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
192adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
193adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    /**
194f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     * Parses the generic signature of a field and creates the data structure
195adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * representing the signature.
196f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes     *
197adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param genericDecl the GenericDeclaration calling this method
198adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     * @param signature the generic signature of the class
199adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project     */
200f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    public void parseForField(GenericDeclaration genericDecl,
201adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            String signature) {
202adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        setInput(genericDecl, signature);
203adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!eof) {
204adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            this.fieldType = parseFieldTypeSignature();
205adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
206adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
207adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
208adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
209adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //
210adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Parser:
211adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //
212adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
213adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void parseClassSignature() {
214f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // ClassSignature ::=
215adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // OptFormalTypeParameters SuperclassSignature {SuperinterfaceSignature}.
216adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
217adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        parseOptFormalTypeParameters();
218adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
219adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // SuperclassSignature ::= ClassTypeSignature.
220adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.superclassType = parseClassTypeSignature();
221adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
222adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        interfaceTypes = new ListOfTypes(16);
223adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (symbol > 0) {
224adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // SuperinterfaceSignature ::= ClassTypeSignature.
225adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            interfaceTypes.add(parseClassTypeSignature());
226adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
227adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
228adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
229adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void parseOptFormalTypeParameters() {
230f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // OptFormalTypeParameters ::=
231adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // ["<" FormalTypeParameter {FormalTypeParameter} ">"].
232adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
233adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ListOfVariables typeParams = new ListOfVariables();
234adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
235adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (symbol == '<') {
236adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
237adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            typeParams.add(parseFormalTypeParameter());
238adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while ((symbol != '>') && (symbol > 0)) {
239adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                typeParams.add(parseFormalTypeParameter());
240adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
241adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            expect('>');
242adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
243adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        this.formalTypeParameters = typeParams.getArray();
244adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
245adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
246adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    ImplForVariable<GenericDeclaration> parseFormalTypeParameter() {
247adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // FormalTypeParameter ::= Ident ClassBound {InterfaceBound}.
248adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
249adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        scanIdentifier();
250adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        String name = identifier.intern(); // FIXME: is this o.k.?
251adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
252adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ListOfTypes bounds = new ListOfTypes(8);
253adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
254adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // ClassBound ::= ":" [FieldTypeSignature].
255adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect(':');
256adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (symbol == 'L' || symbol == '[' || symbol == 'T') {
257adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bounds.add(parseFieldTypeSignature());
258adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
259adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
260adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (symbol == ':') {
261adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // InterfaceBound ::= ":" FieldTypeSignature.
262adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
263adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            bounds.add(parseFieldTypeSignature());
264adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
265adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
266adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new ImplForVariable<GenericDeclaration>(genericDecl, name, bounds);
267adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
268adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
269adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Type parseFieldTypeSignature() {
270f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // FieldTypeSignature ::= ClassTypeSignature | ArrayTypeSignature
271adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //         | TypeVariableSignature.
272adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
273adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (symbol) {
274adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'L':
275adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return parseClassTypeSignature();
276adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case '[':
277adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // ArrayTypeSignature ::= "[" TypSignature.
278adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
279adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new ImplForArray(parseTypeSignature());
280adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'T':
281adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return parseTypeVariableSignature();
282adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        default:
283adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new GenericSignatureFormatError();
284adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
285adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
286adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
287adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Type parseClassTypeSignature() {
288f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // ClassTypeSignature ::= "L" {Ident "/"} Ident
289adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //         OptTypeArguments {"." Ident OptTypeArguments} ";".
290adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
291adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect('L');
292adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
293adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        StringBuilder qualIdent = new StringBuilder();
294adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        scanIdentifier();
295adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (symbol == '/') {
296adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
297adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            qualIdent.append(identifier).append(".");
298adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanIdentifier();
299adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
300adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
301adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        qualIdent.append(this.identifier);
302adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
303adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ListOfTypes typeArgs = parseOptTypeArguments();
304f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        ImplForType parentType =
305adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                new ImplForType(null, qualIdent.toString(), typeArgs, loader);
306adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ImplForType type = parentType;
307adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
308adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (symbol == '.') {
309adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Deal with Member Classes:
310adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
311adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanIdentifier();
312adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            qualIdent.append("$").append(identifier); // FIXME: is "$" correct?
313adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            typeArgs = parseOptTypeArguments();
314f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes            type = new ImplForType(parentType, qualIdent.toString(), typeArgs,
315adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    loader);
316adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
317adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
318adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect(';');
319adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
320adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return type;
321adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
322adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
323adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    ListOfTypes parseOptTypeArguments() {
324adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // OptTypeArguments ::= "<" TypeArgument {TypeArgument} ">".
325adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
326adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ListOfTypes typeArgs = new ListOfTypes(8);
327adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (symbol == '<') {
328adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
329adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
330adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            typeArgs.add(parseTypeArgument());
331adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            while ((symbol != '>') && (symbol > 0)) {
332adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                typeArgs.add(parseTypeArgument());
333adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
334adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            expect('>');
335adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
336adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return typeArgs;
337adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
338adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
339adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Type parseTypeArgument() {
340adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // TypeArgument ::= (["+" | "-"] FieldTypeSignature) | "*".
341adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ListOfTypes extendsBound = new ListOfTypes(1);
342adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        ListOfTypes superBound = new ListOfTypes(1);
343adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (symbol == '*') {
344adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
345adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            extendsBound.add(Object.class);
346adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new ImplForWildcard(extendsBound, superBound);
347adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
348adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else if (symbol == '+') {
349adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
350adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            extendsBound.add(parseFieldTypeSignature());
351adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new ImplForWildcard(extendsBound, superBound);
352adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
353adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else if (symbol == '-') {
354adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
355adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            superBound.add(parseFieldTypeSignature());
356adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            extendsBound.add(Object.class);
357adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return new ImplForWildcard(extendsBound, superBound);
358adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
359adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else {
360adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return parseFieldTypeSignature();
361adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
362adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
363adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
364adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    ImplForVariable<GenericDeclaration> parseTypeVariableSignature() {
365adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // TypeVariableSignature ::= "T" Ident ";".
366adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect('T');
367adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        scanIdentifier();
368adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect(';');
369adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Reference to type variable:
370adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // Note: we don't know the declaring GenericDeclaration yet.
371adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return new ImplForVariable<GenericDeclaration>(genericDecl, identifier);
372adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
373adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
374adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Type parseTypeSignature() {
375adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (symbol) {
376adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'B': scanSymbol(); return byte.class;
377adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'C': scanSymbol(); return char.class;
378adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'D': scanSymbol(); return double.class;
379adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'F': scanSymbol(); return float.class;
380adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'I': scanSymbol(); return int.class;
381adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'J': scanSymbol(); return long.class;
382adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'S': scanSymbol(); return short.class;
383adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case 'Z': scanSymbol(); return boolean.class;
384adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        default:
385adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            // Not an elementary type, but a FieldTypeSignature.
386adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return parseFieldTypeSignature();
387adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
388adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
389adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
39098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    /**
39198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson     * @param rawExceptionTypes the non-generic exceptions. This is necessary
39298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson     *     because the signature may omit the exceptions when none are generic.
39398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson     *     May be null for methods that declare no exceptions.
39498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson     */
39598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson    void parseMethodTypeSignature(Class<?>[] rawExceptionTypes) {
396f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes        // MethodTypeSignature ::= [FormalTypeParameters]
397adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        //         "(" {TypeSignature} ")" ReturnType {ThrowsSignature}.
398adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
399adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        parseOptFormalTypeParameters();
400adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
401adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        parameterTypes = new ListOfTypes(16);
402adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect('(');
403adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        while (symbol != ')' && (symbol > 0)) {
404adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            parameterTypes.add(parseTypeSignature());
405adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
406adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        expect(')');
407adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
408adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        returnType = parseReturnType();
409adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
41098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        if (symbol == '^') {
41198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            exceptionTypes = new ListOfTypes(8);
41298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            do {
41398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                scanSymbol();
41498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson
41598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                // ThrowsSignature ::= ("^" ClassTypeSignature) |
41698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                //     ("^" TypeVariableSignature).
41798a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                if (symbol == 'T') {
41898a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                    exceptionTypes.add(parseTypeVariableSignature());
41998a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                } else {
42098a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                    exceptionTypes.add(parseClassTypeSignature());
42198a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson                }
42298a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            } while (symbol == '^');
42398a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        } else if (rawExceptionTypes != null) {
42498a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            exceptionTypes = new ListOfTypes(rawExceptionTypes);
42598a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson        } else {
42698a7a76fe5c0dd5ff949b38da809368681169205Jesse Wilson            exceptionTypes = new ListOfTypes(0);
427adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
428adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
429adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
430adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    Type parseReturnType() {
431adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        // ReturnType ::= TypeSignature | "V".
432adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (symbol != 'V') { return parseTypeSignature(); }
433adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        else { scanSymbol(); return void.class; }
434adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
435adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
436adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
437adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //
438adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // Scanner:
439adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    //
440adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
441adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void scanSymbol() {
442adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!eof) {
443adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (pos < buffer.length) {
444adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                symbol = buffer[pos];
445adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                pos++;
446adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
447adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                symbol = 0;
448adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                eof = true;
449adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
450adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
451adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new GenericSignatureFormatError();
452adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
453adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
454adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
455adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void expect(char c) {
456adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (symbol == c) {
457adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            scanSymbol();
458adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
459adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new GenericSignatureFormatError();
460adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
461adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
462adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
463adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    boolean isStopSymbol(char ch) {
464adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        switch (ch) {
465adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case ':':
466adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case '/':
467adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case ';':
468adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case '<':
469adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        case '.':
470adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            return true;
471adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
472adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        return false;
473adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
474adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
475adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    // PRE: symbol is the first char of the identifier.
476f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes    // POST: symbol = the next symbol AFTER the identifier.
477adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    void scanIdentifier() {
478adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        if (!eof) {
479adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            StringBuilder identBuf = new StringBuilder(32);
480adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            if (!isStopSymbol(symbol)) {
481adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                identBuf.append(symbol);
482adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                do {
483adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    char ch = buffer[pos];
484adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    if ((ch >= 'a') && (ch <= 'z') || (ch >= 'A') && (ch <= 'Z')
485adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                            || !isStopSymbol(ch)) {
486adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        identBuf.append(buffer[pos]);
487adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        pos++;
488adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    } else {
489adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        identifier = identBuf.toString();
490adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        scanSymbol();
491adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                        return;
492adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                    }
493adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                } while (pos != buffer.length);
494adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                identifier = identBuf.toString();
495adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                symbol = 0;
496adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                eof = true;
497adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            } else {
498adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                // Ident starts with incorrect char.
499adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                symbol = 0;
500adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project                eof = true;
501f33eae7e84eb6d3b0f4e86b59605bb3de73009f3Elliott Hughes                throw new GenericSignatureFormatError();
502adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            }
503adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        } else {
504adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project            throw new GenericSignatureFormatError();
505adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project        }
506adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project    }
507adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project
508adc854b798c1cfe3bfd4c27d68d5cee38ca617daThe Android Open Source Project}
509