langtools/src/jdk.compiler/share/classes/com/sun/tools/classfile/TypeAnnotation.java
changeset 30846 2b3f379840f0
parent 30845 43ddd58a5a56
child 30847 9385b9c8506b
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/classfile/TypeAnnotation.java	Wed May 27 11:27:42 2015 +0530
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,657 +0,0 @@
-/*
- * Copyright (c) 2009, 2013, Oracle and/or its affiliates. All rights reserved.
- * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
- *
- * This code is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License version 2 only, as
- * published by the Free Software Foundation.  Oracle designates this
- * particular file as subject to the "Classpath" exception as provided
- * by Oracle in the LICENSE file that accompanied this code.
- *
- * This code is distributed in the hope that it will be useful, but WITHOUT
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
- * version 2 for more details (a copy is included in the LICENSE file that
- * accompanied this code).
- *
- * You should have received a copy of the GNU General Public License version
- * 2 along with this work; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
- * or visit www.oracle.com if you need additional information or have any
- * questions.
- */
-
-package com.sun.tools.classfile;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import com.sun.tools.classfile.TypeAnnotation.Position.TypePathEntry;
-
-/**
- * See JSR 308 specification, Section 3.
- *
- *  <p><b>This is NOT part of any supported API.
- *  If you write code that depends on this, you do so at your own risk.
- *  This code and its internal interfaces are subject to change or
- *  deletion without notice.</b>
- */
-public class TypeAnnotation {
-    TypeAnnotation(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
-        constant_pool = cr.getConstantPool();
-        position = read_position(cr);
-        annotation = new Annotation(cr);
-    }
-
-    public TypeAnnotation(ConstantPool constant_pool,
-            Annotation annotation, Position position) {
-        this.constant_pool = constant_pool;
-        this.position = position;
-        this.annotation = annotation;
-    }
-
-    public int length() {
-        int n = annotation.length();
-        n += position_length(position);
-        return n;
-    }
-
-    @Override
-    public String toString() {
-        try {
-            return "@" + constant_pool.getUTF8Value(annotation.type_index).toString().substring(1) +
-                    " pos: " + position.toString();
-        } catch (Exception e) {
-            e.printStackTrace();
-            return e.toString();
-        }
-    }
-
-    public final ConstantPool constant_pool;
-    public final Position position;
-    public final Annotation annotation;
-
-    private static Position read_position(ClassReader cr) throws IOException, Annotation.InvalidAnnotation {
-        // Copied from ClassReader
-        int tag = cr.readUnsignedByte(); // TargetType tag is a byte
-        if (!TargetType.isValidTargetTypeValue(tag))
-            throw new Annotation.InvalidAnnotation("TypeAnnotation: Invalid type annotation target type value: " + String.format("0x%02X", tag));
-
-        TargetType type = TargetType.fromTargetTypeValue(tag);
-
-        Position position = new Position();
-        position.type = type;
-
-        switch (type) {
-        // instanceof
-        case INSTANCEOF:
-        // new expression
-        case NEW:
-        // constructor/method reference receiver
-        case CONSTRUCTOR_REFERENCE:
-        case METHOD_REFERENCE:
-            position.offset = cr.readUnsignedShort();
-            break;
-        // local variable
-        case LOCAL_VARIABLE:
-        // resource variable
-        case RESOURCE_VARIABLE:
-            int table_length = cr.readUnsignedShort();
-            position.lvarOffset = new int[table_length];
-            position.lvarLength = new int[table_length];
-            position.lvarIndex = new int[table_length];
-            for (int i = 0; i < table_length; ++i) {
-                position.lvarOffset[i] = cr.readUnsignedShort();
-                position.lvarLength[i] = cr.readUnsignedShort();
-                position.lvarIndex[i] = cr.readUnsignedShort();
-            }
-            break;
-        // exception parameter
-        case EXCEPTION_PARAMETER:
-            position.exception_index = cr.readUnsignedShort();
-            break;
-        // method receiver
-        case METHOD_RECEIVER:
-            // Do nothing
-            break;
-        // type parameter
-        case CLASS_TYPE_PARAMETER:
-        case METHOD_TYPE_PARAMETER:
-            position.parameter_index = cr.readUnsignedByte();
-            break;
-        // type parameter bound
-        case CLASS_TYPE_PARAMETER_BOUND:
-        case METHOD_TYPE_PARAMETER_BOUND:
-            position.parameter_index = cr.readUnsignedByte();
-            position.bound_index = cr.readUnsignedByte();
-            break;
-        // class extends or implements clause
-        case CLASS_EXTENDS:
-            int in = cr.readUnsignedShort();
-            if (in == 0xFFFF)
-                in = -1;
-            position.type_index = in;
-            break;
-        // throws
-        case THROWS:
-            position.type_index = cr.readUnsignedShort();
-            break;
-        // method parameter
-        case METHOD_FORMAL_PARAMETER:
-            position.parameter_index = cr.readUnsignedByte();
-            break;
-        // type cast
-        case CAST:
-        // method/constructor/reference type argument
-        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
-        case METHOD_INVOCATION_TYPE_ARGUMENT:
-        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
-        case METHOD_REFERENCE_TYPE_ARGUMENT:
-            position.offset = cr.readUnsignedShort();
-            position.type_index = cr.readUnsignedByte();
-            break;
-        // We don't need to worry about these
-        case METHOD_RETURN:
-        case FIELD:
-            break;
-        case UNKNOWN:
-            throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
-        default:
-            throw new AssertionError("TypeAnnotation: Unknown target type: " + type);
-        }
-
-        { // Write type path
-            int len = cr.readUnsignedByte();
-            List<Integer> loc = new ArrayList<>(len);
-            for (int i = 0; i < len * TypePathEntry.bytesPerEntry; ++i)
-                loc.add(cr.readUnsignedByte());
-            position.location = Position.getTypePathFromBinary(loc);
-        }
-        return position;
-    }
-
-    private static int position_length(Position pos) {
-        int n = 0;
-        n += 1; // TargetType tag is a byte
-        switch (pos.type) {
-        // instanceof
-        case INSTANCEOF:
-        // new expression
-        case NEW:
-        // constructor/method reference receiver
-        case CONSTRUCTOR_REFERENCE:
-        case METHOD_REFERENCE:
-            n += 2; // offset
-            break;
-        // local variable
-        case LOCAL_VARIABLE:
-        // resource variable
-        case RESOURCE_VARIABLE:
-            n += 2; // table_length;
-            int table_length = pos.lvarOffset.length;
-            n += 2 * table_length; // offset
-            n += 2 * table_length; // length
-            n += 2 * table_length; // index
-            break;
-        // exception parameter
-        case EXCEPTION_PARAMETER:
-            n += 2; // exception_index
-            break;
-        // method receiver
-        case METHOD_RECEIVER:
-            // Do nothing
-            break;
-        // type parameter
-        case CLASS_TYPE_PARAMETER:
-        case METHOD_TYPE_PARAMETER:
-            n += 1; // parameter_index
-            break;
-        // type parameter bound
-        case CLASS_TYPE_PARAMETER_BOUND:
-        case METHOD_TYPE_PARAMETER_BOUND:
-            n += 1; // parameter_index
-            n += 1; // bound_index
-            break;
-        // class extends or implements clause
-        case CLASS_EXTENDS:
-            n += 2; // type_index
-            break;
-        // throws
-        case THROWS:
-            n += 2; // type_index
-            break;
-        // method parameter
-        case METHOD_FORMAL_PARAMETER:
-            n += 1; // parameter_index
-            break;
-        // type cast
-        case CAST:
-        // method/constructor/reference type argument
-        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
-        case METHOD_INVOCATION_TYPE_ARGUMENT:
-        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
-        case METHOD_REFERENCE_TYPE_ARGUMENT:
-            n += 2; // offset
-            n += 1; // type index
-            break;
-        // We don't need to worry about these
-        case METHOD_RETURN:
-        case FIELD:
-            break;
-        case UNKNOWN:
-            throw new AssertionError("TypeAnnotation: UNKNOWN target type should never occur!");
-        default:
-            throw new AssertionError("TypeAnnotation: Unknown target type: " + pos.type);
-        }
-
-        {
-            n += 1; // length
-            n += TypePathEntry.bytesPerEntry * pos.location.size(); // bytes for actual array
-        }
-
-        return n;
-    }
-
-    // Code duplicated from com.sun.tools.javac.code.TypeAnnotationPosition
-    public static class Position {
-        public enum TypePathEntryKind {
-            ARRAY(0),
-            INNER_TYPE(1),
-            WILDCARD(2),
-            TYPE_ARGUMENT(3);
-
-            public final int tag;
-
-            private TypePathEntryKind(int tag) {
-                this.tag = tag;
-            }
-        }
-
-        public static class TypePathEntry {
-            /** The fixed number of bytes per TypePathEntry. */
-            public static final int bytesPerEntry = 2;
-
-            public final TypePathEntryKind tag;
-            public final int arg;
-
-            public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
-            public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
-            public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
-
-            private TypePathEntry(TypePathEntryKind tag) {
-                if (!(tag == TypePathEntryKind.ARRAY ||
-                        tag == TypePathEntryKind.INNER_TYPE ||
-                        tag == TypePathEntryKind.WILDCARD)) {
-                    throw new AssertionError("Invalid TypePathEntryKind: " + tag);
-                }
-                this.tag = tag;
-                this.arg = 0;
-            }
-
-            public TypePathEntry(TypePathEntryKind tag, int arg) {
-                if (tag != TypePathEntryKind.TYPE_ARGUMENT) {
-                    throw new AssertionError("Invalid TypePathEntryKind: " + tag);
-                }
-                this.tag = tag;
-                this.arg = arg;
-            }
-
-            public static TypePathEntry fromBinary(int tag, int arg) {
-                if (arg != 0 && tag != TypePathEntryKind.TYPE_ARGUMENT.tag) {
-                    throw new AssertionError("Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
-                }
-                switch (tag) {
-                case 0:
-                    return ARRAY;
-                case 1:
-                    return INNER_TYPE;
-                case 2:
-                    return WILDCARD;
-                case 3:
-                    return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
-                default:
-                    throw new AssertionError("Invalid TypePathEntryKind tag: " + tag);
-                }
-            }
-
-            @Override
-            public String toString() {
-                return tag.toString() +
-                        (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
-            }
-
-            @Override
-            public boolean equals(Object other) {
-                if (! (other instanceof TypePathEntry)) {
-                    return false;
-                }
-                TypePathEntry tpe = (TypePathEntry) other;
-                return this.tag == tpe.tag && this.arg == tpe.arg;
-            }
-
-            @Override
-            public int hashCode() {
-                return this.tag.hashCode() * 17 + this.arg;
-            }
-        }
-
-        public TargetType type = TargetType.UNKNOWN;
-
-        // For generic/array types.
-        // TODO: or should we use null? Noone will use this object.
-        public List<TypePathEntry> location = new ArrayList<>(0);
-
-        // Tree position.
-        public int pos = -1;
-
-        // For typecasts, type tests, new (and locals, as start_pc).
-        public boolean isValidOffset = false;
-        public int offset = -1;
-
-        // For locals. arrays same length
-        public int[] lvarOffset = null;
-        public int[] lvarLength = null;
-        public int[] lvarIndex = null;
-
-        // For type parameter bound
-        public int bound_index = Integer.MIN_VALUE;
-
-        // For type parameter and method parameter
-        public int parameter_index = Integer.MIN_VALUE;
-
-        // For class extends, implements, and throws clauses
-        public int type_index = Integer.MIN_VALUE;
-
-        // For exception parameters, index into exception table
-        public int exception_index = Integer.MIN_VALUE;
-
-        public Position() {}
-
-        @Override
-        public String toString() {
-            StringBuilder sb = new StringBuilder();
-            sb.append('[');
-            sb.append(type);
-
-            switch (type) {
-            // instanceof
-            case INSTANCEOF:
-            // new expression
-            case NEW:
-            // constructor/method reference receiver
-            case CONSTRUCTOR_REFERENCE:
-            case METHOD_REFERENCE:
-                sb.append(", offset = ");
-                sb.append(offset);
-                break;
-            // local variable
-            case LOCAL_VARIABLE:
-            // resource variable
-            case RESOURCE_VARIABLE:
-                if (lvarOffset == null) {
-                    sb.append(", lvarOffset is null!");
-                    break;
-                }
-                sb.append(", {");
-                for (int i = 0; i < lvarOffset.length; ++i) {
-                    if (i != 0) sb.append("; ");
-                    sb.append("start_pc = ");
-                    sb.append(lvarOffset[i]);
-                    sb.append(", length = ");
-                    sb.append(lvarLength[i]);
-                    sb.append(", index = ");
-                    sb.append(lvarIndex[i]);
-                }
-                sb.append("}");
-                break;
-            // method receiver
-            case METHOD_RECEIVER:
-                // Do nothing
-                break;
-            // type parameter
-            case CLASS_TYPE_PARAMETER:
-            case METHOD_TYPE_PARAMETER:
-                sb.append(", param_index = ");
-                sb.append(parameter_index);
-                break;
-            // type parameter bound
-            case CLASS_TYPE_PARAMETER_BOUND:
-            case METHOD_TYPE_PARAMETER_BOUND:
-                sb.append(", param_index = ");
-                sb.append(parameter_index);
-                sb.append(", bound_index = ");
-                sb.append(bound_index);
-                break;
-            // class extends or implements clause
-            case CLASS_EXTENDS:
-                sb.append(", type_index = ");
-                sb.append(type_index);
-                break;
-            // throws
-            case THROWS:
-                sb.append(", type_index = ");
-                sb.append(type_index);
-                break;
-            // exception parameter
-            case EXCEPTION_PARAMETER:
-                sb.append(", exception_index = ");
-                sb.append(exception_index);
-                break;
-            // method parameter
-            case METHOD_FORMAL_PARAMETER:
-                sb.append(", param_index = ");
-                sb.append(parameter_index);
-                break;
-            // type cast
-            case CAST:
-            // method/constructor/reference type argument
-            case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
-            case METHOD_INVOCATION_TYPE_ARGUMENT:
-            case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
-            case METHOD_REFERENCE_TYPE_ARGUMENT:
-                sb.append(", offset = ");
-                sb.append(offset);
-                sb.append(", type_index = ");
-                sb.append(type_index);
-                break;
-            // We don't need to worry about these
-            case METHOD_RETURN:
-            case FIELD:
-                break;
-            case UNKNOWN:
-                sb.append(", position UNKNOWN!");
-                break;
-            default:
-                throw new AssertionError("Unknown target type: " + type);
-            }
-
-            // Append location data for generics/arrays.
-            if (!location.isEmpty()) {
-                sb.append(", location = (");
-                sb.append(location);
-                sb.append(")");
-            }
-
-            sb.append(", pos = ");
-            sb.append(pos);
-
-            sb.append(']');
-            return sb.toString();
-        }
-
-        /**
-         * Indicates whether the target tree of the annotation has been optimized
-         * away from classfile or not.
-         * @return true if the target has not been optimized away
-         */
-        public boolean emitToClassfile() {
-            return !type.isLocal() || isValidOffset;
-        }
-
-        /**
-         * Decode the binary representation for a type path and set
-         * the {@code location} field.
-         *
-         * @param list The bytecode representation of the type path.
-         */
-        public static List<TypePathEntry> getTypePathFromBinary(List<Integer> list) {
-            List<TypePathEntry> loc = new ArrayList<>(list.size() / TypePathEntry.bytesPerEntry);
-            int idx = 0;
-            while (idx < list.size()) {
-                if (idx + 1 == list.size()) {
-                    throw new AssertionError("Could not decode type path: " + list);
-                }
-                loc.add(TypePathEntry.fromBinary(list.get(idx), list.get(idx + 1)));
-                idx += 2;
-            }
-            return loc;
-        }
-
-        public static List<Integer> getBinaryFromTypePath(List<TypePathEntry> locs) {
-            List<Integer> loc = new ArrayList<>(locs.size() * TypePathEntry.bytesPerEntry);
-            for (TypePathEntry tpe : locs) {
-                loc.add(tpe.tag.tag);
-                loc.add(tpe.arg);
-            }
-            return loc;
-        }
-    }
-
-    // Code duplicated from com.sun.tools.javac.code.TargetType
-    // The IsLocal flag could be removed here.
-    public enum TargetType {
-        /** For annotations on a class type parameter declaration. */
-        CLASS_TYPE_PARAMETER(0x00),
-
-        /** For annotations on a method type parameter declaration. */
-        METHOD_TYPE_PARAMETER(0x01),
-
-        /** For annotations on the type of an "extends" or "implements" clause. */
-        CLASS_EXTENDS(0x10),
-
-        /** For annotations on a bound of a type parameter of a class. */
-        CLASS_TYPE_PARAMETER_BOUND(0x11),
-
-        /** For annotations on a bound of a type parameter of a method. */
-        METHOD_TYPE_PARAMETER_BOUND(0x12),
-
-        /** For annotations on a field. */
-        FIELD(0x13),
-
-        /** For annotations on a method return type. */
-        METHOD_RETURN(0x14),
-
-        /** For annotations on the method receiver. */
-        METHOD_RECEIVER(0x15),
-
-        /** For annotations on a method parameter. */
-        METHOD_FORMAL_PARAMETER(0x16),
-
-        /** For annotations on a throws clause in a method declaration. */
-        THROWS(0x17),
-
-        /** For annotations on a local variable. */
-        LOCAL_VARIABLE(0x40, true),
-
-        /** For annotations on a resource variable. */
-        RESOURCE_VARIABLE(0x41, true),
-
-        /** For annotations on an exception parameter. */
-        EXCEPTION_PARAMETER(0x42, true),
-
-        /** For annotations on a type test. */
-        INSTANCEOF(0x43, true),
-
-        /** For annotations on an object creation expression. */
-        NEW(0x44, true),
-
-        /** For annotations on a constructor reference receiver. */
-        CONSTRUCTOR_REFERENCE(0x45, true),
-
-        /** For annotations on a method reference receiver. */
-        METHOD_REFERENCE(0x46, true),
-
-        /** For annotations on a typecast. */
-        CAST(0x47, true),
-
-        /** For annotations on a type argument of an object creation expression. */
-        CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT(0x48, true),
-
-        /** For annotations on a type argument of a method call. */
-        METHOD_INVOCATION_TYPE_ARGUMENT(0x49, true),
-
-        /** For annotations on a type argument of a constructor reference. */
-        CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT(0x4A, true),
-
-        /** For annotations on a type argument of a method reference. */
-        METHOD_REFERENCE_TYPE_ARGUMENT(0x4B, true),
-
-        /** For annotations with an unknown target. */
-        UNKNOWN(0xFF);
-
-        private static final int MAXIMUM_TARGET_TYPE_VALUE = 0x4B;
-
-        private final int targetTypeValue;
-        private final boolean isLocal;
-
-        private TargetType(int targetTypeValue) {
-            this(targetTypeValue, false);
-        }
-
-        private TargetType(int targetTypeValue, boolean isLocal) {
-            if (targetTypeValue < 0
-                    || targetTypeValue > 255)
-                    throw new AssertionError("Attribute type value needs to be an unsigned byte: " + String.format("0x%02X", targetTypeValue));
-            this.targetTypeValue = targetTypeValue;
-            this.isLocal = isLocal;
-        }
-
-        /**
-         * Returns whether or not this TargetType represents an annotation whose
-         * target is exclusively a tree in a method body
-         *
-         * Note: wildcard bound targets could target a local tree and a class
-         * member declaration signature tree
-         */
-        public boolean isLocal() {
-            return isLocal;
-        }
-
-        public int targetTypeValue() {
-            return this.targetTypeValue;
-        }
-
-        private static final TargetType[] targets;
-
-        static {
-            targets = new TargetType[MAXIMUM_TARGET_TYPE_VALUE + 1];
-            TargetType[] alltargets = values();
-            for (TargetType target : alltargets) {
-                if (target.targetTypeValue != UNKNOWN.targetTypeValue)
-                    targets[target.targetTypeValue] = target;
-            }
-            for (int i = 0; i <= MAXIMUM_TARGET_TYPE_VALUE; ++i) {
-                if (targets[i] == null)
-                    targets[i] = UNKNOWN;
-            }
-        }
-
-        public static boolean isValidTargetTypeValue(int tag) {
-            if (tag == UNKNOWN.targetTypeValue)
-                return true;
-            return (tag >= 0 && tag < targets.length);
-        }
-
-        public static TargetType fromTargetTypeValue(int tag) {
-            if (tag == UNKNOWN.targetTypeValue)
-                return UNKNOWN;
-
-            if (tag < 0 || tag >= targets.length)
-                throw new AssertionError("Unknown TargetType: " + tag);
-            return targets[tag];
-        }
-    }
-}