jdk/src/share/classes/sun/tools/java/Type.java
author psandoz
Mon, 16 Jun 2014 17:45:26 +0100
changeset 24969 afa6934dd8e8
parent 5506 202f599c92aa
child 25799 1afc4675dc75
permissions -rw-r--r--
8041679: Replace uses of StringBuffer with StringBuilder within core library classes Reviewed-by: psandoz, alanb, xuelei, dfuchs, jfranck, prr, serb, chegar Contributed-by: otaviopolianasantana@gmail.com
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     2
 * Copyright (c) 1994, 2003, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 2
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package sun.tools.java;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.Hashtable;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
 * This class represents an Java Type.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * It encapsulates an Java type signature and it provides
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * quick access to the components of the type. Note that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * all types are hashed into a hashtable (typeHash), that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * means that each distinct type is only allocated once,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * saving space and making equality checks cheap.<p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * For simple types use the constants defined in this class.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * (Type.tInt, Type.tShort, ...). To create complex types use
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * the static methods Type.tArray, Type.tMethod or Type.tClass.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * For classes, arrays and method types a sub class of class
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * type is created which defines the extra type components.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 * WARNING: The contents of this source file are not part of any
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * supported API.  Code that depends on them does so at its own risk:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * they are subject to change or removal without notice.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * @see         ArrayType
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 * @see         ClassType
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * @see         MethodType
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 * @author      Arthur van Hoff
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
public
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
class Type implements Constants {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
     * This hashtable is used to cache types
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
    private static final Hashtable typeHash = new Hashtable(231);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
     * The TypeCode of this type. The value of this field is one
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
     * of the TC_* contant values defined in Constants.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
     * @see Constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
    protected int typeCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
     * The TypeSignature of this type. This type signature is
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
     * equivalent to the runtime type signatures used by the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
     * interpreter.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    protected String typeSig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    75
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
     * Predefined types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
    public static final Type noArgs[]   = new Type[0];
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
    public static final Type tError     = new Type(TC_ERROR,    "?");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
    public static final Type tPackage   = new Type(TC_ERROR,    ".");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
    public static final Type tNull      = new Type(TC_NULL,     "*");
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
    public static final Type tVoid      = new Type(TC_VOID,     SIG_VOID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
    public static final Type tBoolean   = new Type(TC_BOOLEAN,  SIG_BOOLEAN);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
    public static final Type tByte      = new Type(TC_BYTE,     SIG_BYTE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
    public static final Type tChar      = new Type(TC_CHAR,     SIG_CHAR);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
    public static final Type tShort     = new Type(TC_SHORT,    SIG_SHORT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    public static final Type tInt       = new Type(TC_INT,      SIG_INT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
    public static final Type tFloat     = new Type(TC_FLOAT,    SIG_FLOAT);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
    public static final Type tLong      = new Type(TC_LONG,     SIG_LONG);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
    public static final Type tDouble    = new Type(TC_DOUBLE,   SIG_DOUBLE);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
    public static final Type tObject    = Type.tClass(idJavaLangObject);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
    public static final Type tClassDesc = Type.tClass(idJavaLangClass);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
    public static final Type tString    = Type.tClass(idJavaLangString);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
    public static final Type tCloneable = Type.tClass(idJavaLangCloneable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
    public static final Type tSerializable = Type.tClass(idJavaIoSerializable);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
     * Create a type given a typecode and a type signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
    protected Type(int typeCode, String typeSig) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        this.typeCode = typeCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
        this.typeSig = typeSig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        typeHash.put(typeSig, this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
     * Return the Java type signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
    public final String getTypeSignature() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
        return typeSig;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
     * Return the type code.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    public final int getTypeCode() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
        return typeCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * Return the type mask. The bits in this mask correspond
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     * to the TM_* constants defined in Constants. Only one bit
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * is set at a type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     * @see Constants
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
    public final int getTypeMask() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
        return 1 << typeCode;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * Check for a certain type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
    public final boolean isType(int tc) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
        return typeCode == tc;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
     * Check to see if this is the bogus type "array of void"
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
     * Although this highly degenerate "type" is not constructable from
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * the grammar, the Parser accepts it.  Rather than monkey with the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     * Parser, we check for the bogus type at specific points and give
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * a nice error.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    public boolean isVoidArray() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
        // a void type is not a void array.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        if (!isType(TC_ARRAY)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   151
        // If this is an array, find out what its element type is.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
        Type type = this;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   153
        while (type.isType(TC_ARRAY))
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
            type = type.getElementType();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
        return type.isType(TC_VOID);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
90ce3da70b43 Initial load
duke
parents:
diff changeset
   160
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
     * Check for a certain set of types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
    public final boolean inMask(int tm) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
        return ((1 << typeCode) & tm) != 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * Create an array type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    public static synchronized Type tArray(Type elem) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        String sig = new String(SIG_ARRAY + elem.getTypeSignature());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        Type t = (Type)typeHash.get(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
        if (t == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
            t = new ArrayType(sig, elem);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   176
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
     * Return the element type of an array type. Only works
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
     * for array types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    public Type getElementType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
        throw new CompilerError("getElementType");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
     * Return the array dimension. Only works for
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
     * array types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
    public int getArrayDimension() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
     * Create a class type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * @arg className the fully qualified class name
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
    public static synchronized Type tClass(Identifier className) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
        if (className.isInner()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
            Type t = tClass(mangleInnerType(className));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
            if (t.getClassName() != className)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
                // Somebody got here first with a mangled name.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
                // (Perhaps it came from a binary.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
                changeClassName(t.getClassName(), className);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
            return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        // see if we've cached the object in the Identifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
        if (className.typeObject != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
            return className.typeObject;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   212
        String sig =
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            new String(SIG_CLASS +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
                       className.toString().replace('.', SIGC_PACKAGE) +
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
                       SIG_ENDCLASS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
        Type t = (Type)typeHash.get(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
        if (t == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            t = new ClassType(sig, className);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        className.typeObject = t; // cache the Type object in the Identifier
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
     * Return the ClassName. Only works on class types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
    public Identifier getClassName() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
        throw new CompilerError("getClassName:" + this);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     * Given an inner identifier, return the non-inner, mangled
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
     * representation used to manage signatures.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
     * Note: It is changed to 'public' for Jcov file generation.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
     * (see Assembler.java)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
    public static Identifier mangleInnerType(Identifier className) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        // Map "pkg.Foo. Bar" to "pkg.Foo$Bar".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
        if (!className.isInner())  return className;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        Identifier mname = Identifier.lookup(
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
                                className.getFlatName().toString().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
                                replace('.', SIGC_INNERCLASS) );
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        if (mname.isInner())  throw new CompilerError("mangle "+mname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
        return Identifier.lookup(className.getQualifier(), mname);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
90ce3da70b43 Initial load
duke
parents:
diff changeset
   250
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
     * We have learned that a signature means something other
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
     * that what we thought it meant.  Live with it:  Change all
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
     * affected data structures to reflect the new name of the old type.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
     * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
     * (This is necessary because of an ambiguity between the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
     * low-level signatures of inner types and their manglings.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
     * Note that the latter are also valid class names.)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
    static void changeClassName(Identifier oldName, Identifier newName) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
        // Note:  If we are upgrading "pkg.Foo$Bar" to "pkg.Foo. Bar",
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
        // we assume someone else will come along and deal with any types
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
        // inner within Bar.  So, there's only one change to make.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
        ((ClassType)Type.tClass(oldName)).className = newName;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
     * Create a method type with no arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
    public static synchronized Type tMethod(Type ret) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
        return tMethod(ret, noArgs);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
     * Create a method type with arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   275
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
    public static synchronized Type tMethod(Type returnType, Type argTypes[]) {
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 5506
diff changeset
   277
        StringBuilder sb = new StringBuilder();
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 5506
diff changeset
   278
        sb.append(SIG_METHOD);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
        for (int i = 0 ; i < argTypes.length ; i++) {
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 5506
diff changeset
   280
            sb.append(argTypes[i].getTypeSignature());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        }
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 5506
diff changeset
   282
        sb.append(SIG_ENDMETHOD);
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 5506
diff changeset
   283
        sb.append(returnType.getTypeSignature());
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
24969
afa6934dd8e8 8041679: Replace uses of StringBuffer with StringBuilder within core library classes
psandoz
parents: 5506
diff changeset
   285
        String sig = sb.toString();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
        Type t = (Type)typeHash.get(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
        if (t == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
            t = new MethodType(sig, returnType, argTypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
        return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
     * Return the return type. Only works for method types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
    public Type getReturnType() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        throw new CompilerError("getReturnType");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
     * Return the argument types. Only works for method types.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   303
    public Type getArgumentTypes()[] {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        throw new CompilerError("getArgumentTypes");
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
     * Create a Type from an Java type signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
     * @exception CompilerError invalid type signature.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
    public static synchronized Type tType(String sig) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
        Type t = (Type)typeHash.get(sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
        if (t != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            return t;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
        switch (sig.charAt(0)) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
          case SIGC_ARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            return Type.tArray(tType(sig.substring(1)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
          case SIGC_CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
            return Type.tClass(Identifier.lookup(sig.substring(1, sig.length() - 1).replace(SIGC_PACKAGE, '.')));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   323
90ce3da70b43 Initial load
duke
parents:
diff changeset
   324
          case SIGC_METHOD: {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
            Type argv[] = new Type[8];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            int argc = 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            int i, j;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            for (i = 1 ; sig.charAt(i) != SIGC_ENDMETHOD ; i = j) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
                for (j = i ; sig.charAt(j) == SIGC_ARRAY ; j++);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                if (sig.charAt(j++) == SIGC_CLASS) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
                    while (sig.charAt(j++) != SIGC_ENDCLASS);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
                if (argc == argv.length) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
                    Type newargv[] = new Type[argc * 2];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
                    System.arraycopy(argv, 0, newargv, 0, argc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
                    argv = newargv;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
                argv[argc++] = tType(sig.substring(i, j));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
            Type argtypes[] = new Type[argc];
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            System.arraycopy(argv, 0, argtypes, 0, argc);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
            return Type.tMethod(tType(sig.substring(i + 1)), argtypes);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        throw new CompilerError("invalid TypeSignature:" + sig);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
     * Check if the type arguments are the same.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
     * @return true if both types are method types and the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
     * argument types are identical.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    public boolean equalArguments(Type t) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
        return false;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
     * Return the amount of space this type takes up on the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
     * Java operand stack. For a method this is equal to the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
     * total space taken up by the arguments.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
    public int stackSize() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
        switch (typeCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
          case TC_ERROR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
          case TC_VOID:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
          case TC_BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
          case TC_BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
          case TC_SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
          case TC_CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
          case TC_INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
          case TC_FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
          case TC_ARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
          case TC_CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
          case TC_LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
          case TC_DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
            return 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   382
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   383
        throw new CompilerError("stackSize " + toString());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   384
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   385
90ce3da70b43 Initial load
duke
parents:
diff changeset
   386
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   387
     * Return the type code offset. This offset can be added to
90ce3da70b43 Initial load
duke
parents:
diff changeset
   388
     * an opcode to get the right opcode type. Most opcodes
90ce3da70b43 Initial load
duke
parents:
diff changeset
   389
     * are ordered: int, long, float, double, array. For
90ce3da70b43 Initial load
duke
parents:
diff changeset
   390
     * example: iload, lload fload, dload, aload. So the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   391
     * appropriate opcode is iadd + type.getTypeCodeOffset().
90ce3da70b43 Initial load
duke
parents:
diff changeset
   392
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   393
    public int getTypeCodeOffset() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   394
        switch (typeCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   395
          case TC_BOOLEAN:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   396
          case TC_BYTE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   397
          case TC_SHORT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   398
          case TC_CHAR:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   399
          case TC_INT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   400
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   401
          case TC_LONG:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   402
            return 1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   403
          case TC_FLOAT:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   404
            return 2;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   405
          case TC_DOUBLE:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   406
            return 3;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   407
          case TC_NULL:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   408
          case TC_ARRAY:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   409
          case TC_CLASS:
90ce3da70b43 Initial load
duke
parents:
diff changeset
   410
            return 4;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   411
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   412
        throw new CompilerError("invalid typecode: " + typeCode);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   413
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   414
90ce3da70b43 Initial load
duke
parents:
diff changeset
   415
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   416
     * Convert a Type to a string, if abbrev is true class names are
90ce3da70b43 Initial load
duke
parents:
diff changeset
   417
     * not fully qualified, if ret is true the return type is included.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   418
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   419
    public String typeString(String id, boolean abbrev, boolean ret) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   420
        String s = null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   421
90ce3da70b43 Initial load
duke
parents:
diff changeset
   422
        switch (typeCode) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   423
          case TC_NULL:         s = "null";    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   424
          case TC_VOID:         s = "void";    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   425
          case TC_BOOLEAN:      s = "boolean"; break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   426
          case TC_BYTE:         s = "byte";    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   427
          case TC_CHAR:         s = "char";    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   428
          case TC_SHORT:        s = "short";   break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   429
          case TC_INT:          s = "int";     break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   430
          case TC_LONG:         s = "long";    break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   431
          case TC_FLOAT:        s = "float";   break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   432
          case TC_DOUBLE:       s = "double";  break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   433
          case TC_ERROR:        s = "<error>";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   434
                                if (this==tPackage) s = "<package>";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   435
                                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   436
          default:              s = "unknown";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   437
          }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   438
90ce3da70b43 Initial load
duke
parents:
diff changeset
   439
        return (id.length() > 0) ? s + " " + id : s;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   440
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   441
90ce3da70b43 Initial load
duke
parents:
diff changeset
   442
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   443
     * Create a type string, given an identifier.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   444
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   445
    public String typeString(String id) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   446
        return typeString(id, false, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   447
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   448
90ce3da70b43 Initial load
duke
parents:
diff changeset
   449
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   450
     * Convert to a String
90ce3da70b43 Initial load
duke
parents:
diff changeset
   451
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   452
    public String toString() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   453
        return typeString("", false, true);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   454
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   455
}