45N/A/*
553N/A * Copyright (c) 2007, 2008, Oracle and/or its affiliates. All rights reserved.
45N/A * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
45N/A *
45N/A * This code is free software; you can redistribute it and/or modify it
45N/A * under the terms of the GNU General Public License version 2 only, as
553N/A * published by the Free Software Foundation. Oracle designates this
45N/A * particular file as subject to the "Classpath" exception as provided
553N/A * by Oracle in the LICENSE file that accompanied this code.
45N/A *
45N/A * This code is distributed in the hope that it will be useful, but WITHOUT
45N/A * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
45N/A * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
45N/A * version 2 for more details (a copy is included in the LICENSE file that
45N/A * accompanied this code).
45N/A *
45N/A * You should have received a copy of the GNU General Public License version
45N/A * 2 along with this work; if not, write to the Free Software Foundation,
45N/A * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
45N/A *
553N/A * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
553N/A * or visit www.oracle.com if you need additional information or have any
553N/A * questions.
45N/A */
45N/A
45N/Apackage com.sun.tools.classfile;
45N/A
45N/Aimport java.util.ArrayList;
45N/Aimport java.util.List;
426N/Aimport com.sun.tools.classfile.Type.*;
45N/A
45N/A/**
971N/A * See JVMS 4.4.4.
45N/A *
580N/A * <p><b>This is NOT part of any supported API.
580N/A * If you write code that depends on this, you do so at your own risk.
45N/A * This code and its internal interfaces are subject to change or
45N/A * deletion without notice.</b>
45N/A */
45N/Apublic class Signature extends Descriptor {
45N/A
45N/A public Signature(int index) {
45N/A super(index);
45N/A }
45N/A
45N/A public Type getType(ConstantPool constant_pool) throws ConstantPoolException {
45N/A if (type == null)
45N/A type = parse(getValue(constant_pool));
45N/A return type;
45N/A }
45N/A
45N/A @Override
45N/A public int getParameterCount(ConstantPool constant_pool) throws ConstantPoolException {
426N/A MethodType m = (MethodType) getType(constant_pool);
426N/A return m.paramTypes.size();
45N/A }
45N/A
45N/A @Override
45N/A public String getParameterTypes(ConstantPool constant_pool) throws ConstantPoolException {
426N/A MethodType m = (MethodType) getType(constant_pool);
45N/A StringBuilder sb = new StringBuilder();
45N/A sb.append("(");
45N/A String sep = "";
426N/A for (Type paramType: m.paramTypes) {
45N/A sb.append(sep);
426N/A sb.append(paramType);
45N/A sep = ", ";
45N/A }
45N/A sb.append(")");
45N/A return sb.toString();
45N/A }
45N/A
45N/A @Override
45N/A public String getReturnType(ConstantPool constant_pool) throws ConstantPoolException {
426N/A MethodType m = (MethodType) getType(constant_pool);
45N/A return m.returnType.toString();
45N/A }
45N/A
45N/A @Override
45N/A public String getFieldType(ConstantPool constant_pool) throws ConstantPoolException {
45N/A return getType(constant_pool).toString();
45N/A }
45N/A
45N/A private Type parse(String sig) {
45N/A this.sig = sig;
45N/A sigp = 0;
45N/A
426N/A List<TypeParamType> typeParamTypes = null;
45N/A if (sig.charAt(sigp) == '<')
426N/A typeParamTypes = parseTypeParamTypes();
45N/A
45N/A if (sig.charAt(sigp) == '(') {
426N/A List<Type> paramTypes = parseTypeSignatures(')');
45N/A Type returnType = parseTypeSignature();
45N/A List<Type> throwsTypes = null;
45N/A while (sigp < sig.length() && sig.charAt(sigp) == '^') {
45N/A sigp++;
45N/A if (throwsTypes == null)
45N/A throwsTypes = new ArrayList<Type>();
45N/A throwsTypes.add(parseTypeSignature());
45N/A }
426N/A return new MethodType(typeParamTypes, paramTypes, returnType, throwsTypes);
45N/A } else {
45N/A Type t = parseTypeSignature();
426N/A if (typeParamTypes == null && sigp == sig.length())
45N/A return t;
45N/A Type superclass = t;
426N/A List<Type> superinterfaces = null;
426N/A while (sigp < sig.length()) {
426N/A if (superinterfaces == null)
426N/A superinterfaces = new ArrayList<Type>();
45N/A superinterfaces.add(parseTypeSignature());
426N/A }
426N/A return new ClassSigType(typeParamTypes, superclass, superinterfaces);
45N/A
45N/A }
45N/A }
45N/A
45N/A private Type parseTypeSignature() {
45N/A switch (sig.charAt(sigp)) {
45N/A case 'B':
45N/A sigp++;
426N/A return new SimpleType("byte");
45N/A
45N/A case 'C':
45N/A sigp++;
426N/A return new SimpleType("char");
45N/A
45N/A case 'D':
45N/A sigp++;
426N/A return new SimpleType("double");
45N/A
45N/A case 'F':
45N/A sigp++;
426N/A return new SimpleType("float");
45N/A
45N/A case 'I':
45N/A sigp++;
426N/A return new SimpleType("int");
45N/A
45N/A case 'J':
45N/A sigp++;
426N/A return new SimpleType("long");
45N/A
45N/A case 'L':
45N/A return parseClassTypeSignature();
45N/A
45N/A case 'S':
45N/A sigp++;
426N/A return new SimpleType("short");
45N/A
45N/A case 'T':
45N/A return parseTypeVariableSignature();
45N/A
45N/A case 'V':
45N/A sigp++;
426N/A return new SimpleType("void");
45N/A
45N/A case 'Z':
45N/A sigp++;
426N/A return new SimpleType("boolean");
45N/A
45N/A case '[':
45N/A sigp++;
426N/A return new ArrayType(parseTypeSignature());
45N/A
45N/A case '*':
45N/A sigp++;
426N/A return new WildcardType();
45N/A
45N/A case '+':
45N/A sigp++;
426N/A return new WildcardType(WildcardType.Kind.EXTENDS, parseTypeSignature());
45N/A
45N/A case '-':
45N/A sigp++;
426N/A return new WildcardType(WildcardType.Kind.SUPER, parseTypeSignature());
45N/A
45N/A default:
45N/A throw new IllegalStateException(debugInfo());
45N/A }
45N/A }
45N/A
45N/A private List<Type> parseTypeSignatures(char term) {
45N/A sigp++;
45N/A List<Type> types = new ArrayList<Type>();
45N/A while (sig.charAt(sigp) != term)
45N/A types.add(parseTypeSignature());
45N/A sigp++;
45N/A return types;
45N/A }
45N/A
45N/A private Type parseClassTypeSignature() {
45N/A assert sig.charAt(sigp) == 'L';
45N/A sigp++;
45N/A return parseClassTypeSignatureRest();
45N/A }
45N/A
45N/A private Type parseClassTypeSignatureRest() {
45N/A StringBuilder sb = new StringBuilder();
426N/A List<Type> argTypes = null;
426N/A ClassType t = null;
426N/A char sigch ;
426N/A
426N/A do {
45N/A switch (sigch = sig.charAt(sigp)) {
426N/A case '<':
426N/A argTypes = parseTypeSignatures('>');
45N/A break;
45N/A
45N/A case '.':
45N/A case ';':
45N/A sigp++;
426N/A t = new ClassType(t, sb.toString(), argTypes);
426N/A sb.setLength(0);
426N/A argTypes = null;
45N/A break;
45N/A
45N/A default:
45N/A sigp++;
45N/A sb.append(sigch);
45N/A break;
45N/A }
426N/A } while (sigch != ';');
426N/A
426N/A return t;
45N/A }
45N/A
426N/A private List<TypeParamType> parseTypeParamTypes() {
45N/A assert sig.charAt(sigp) == '<';
45N/A sigp++;
426N/A List<TypeParamType> types = new ArrayList<TypeParamType>();
45N/A while (sig.charAt(sigp) != '>')
426N/A types.add(parseTypeParamType());
45N/A sigp++;
45N/A return types;
45N/A }
45N/A
426N/A private TypeParamType parseTypeParamType() {
45N/A int sep = sig.indexOf(":", sigp);
45N/A String name = sig.substring(sigp, sep);
45N/A Type classBound = null;
45N/A List<Type> interfaceBounds = null;
45N/A sigp = sep + 1;
45N/A if (sig.charAt(sigp) != ':')
45N/A classBound = parseTypeSignature();
45N/A while (sig.charAt(sigp) == ':') {
45N/A sigp++;
45N/A if (interfaceBounds == null)
45N/A interfaceBounds = new ArrayList<Type>();
45N/A interfaceBounds.add(parseTypeSignature());
45N/A }
426N/A return new TypeParamType(name, classBound, interfaceBounds);
45N/A }
45N/A
45N/A private Type parseTypeVariableSignature() {
45N/A sigp++;
45N/A int sep = sig.indexOf(';', sigp);
426N/A Type t = new SimpleType(sig.substring(sigp, sep));
45N/A sigp = sep + 1;
45N/A return t;
45N/A }
45N/A
45N/A private String debugInfo() {
45N/A return sig.substring(0, sigp) + "!" + sig.charAt(sigp) + "!" + sig.substring(sigp+1);
45N/A }
45N/A
45N/A private String sig;
45N/A private int sigp;
45N/A
45N/A private Type type;
45N/A}