src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java

changeset 1570
f91144b7da75
parent 1521
71f35e4b93a5
child 1563
bc456436c613
     1.1 --- a/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Mon Jan 21 01:27:42 2013 -0500
     1.2 +++ b/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Mon Feb 04 18:08:53 2013 -0500
     1.3 @@ -1,5 +1,5 @@
     1.4  /*
     1.5 - * Copyright (c) 2003, 2010, Oracle and/or its affiliates. All rights reserved.
     1.6 + * Copyright (c) 2003, 2013, Oracle and/or its affiliates. All rights reserved.
     1.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     1.8   *
     1.9   * This code is free software; you can redistribute it and/or modify it
    1.10 @@ -25,6 +25,8 @@
    1.11  
    1.12  package com.sun.tools.javac.code;
    1.13  
    1.14 +import java.util.Iterator;
    1.15 +
    1.16  import com.sun.tools.javac.util.*;
    1.17  
    1.18  /** A type annotation position.
    1.19 @@ -34,12 +36,92 @@
    1.20  *  This code and its internal interfaces are subject to change or
    1.21  *  deletion without notice.</b>
    1.22  */
    1.23 +// Code duplicated in com.sun.tools.classfile.TypeAnnotation.Position
    1.24  public class TypeAnnotationPosition {
    1.25  
    1.26 +    public enum TypePathEntryKind {
    1.27 +        ARRAY(0),
    1.28 +        INNER_TYPE(1),
    1.29 +        WILDCARD(2),
    1.30 +        TYPE_ARGUMENT(3);
    1.31 +
    1.32 +        public final int tag;
    1.33 +
    1.34 +        private TypePathEntryKind(int tag) {
    1.35 +            this.tag = tag;
    1.36 +        }
    1.37 +    }
    1.38 +
    1.39 +    public static class TypePathEntry {
    1.40 +        /** The fixed number of bytes per TypePathEntry. */
    1.41 +        public static final int bytesPerEntry = 2;
    1.42 +
    1.43 +        public final TypePathEntryKind tag;
    1.44 +        public final int arg;
    1.45 +
    1.46 +        public static final TypePathEntry ARRAY = new TypePathEntry(TypePathEntryKind.ARRAY);
    1.47 +        public static final TypePathEntry INNER_TYPE = new TypePathEntry(TypePathEntryKind.INNER_TYPE);
    1.48 +        public static final TypePathEntry WILDCARD = new TypePathEntry(TypePathEntryKind.WILDCARD);
    1.49 +
    1.50 +        private TypePathEntry(TypePathEntryKind tag) {
    1.51 +            Assert.check(tag == TypePathEntryKind.ARRAY ||
    1.52 +                    tag == TypePathEntryKind.INNER_TYPE ||
    1.53 +                    tag == TypePathEntryKind.WILDCARD,
    1.54 +                    "Invalid TypePathEntryKind: " + tag);
    1.55 +            this.tag = tag;
    1.56 +            this.arg = 0;
    1.57 +        }
    1.58 +
    1.59 +        public TypePathEntry(TypePathEntryKind tag, int arg) {
    1.60 +            Assert.check(tag == TypePathEntryKind.TYPE_ARGUMENT,
    1.61 +                    "Invalid TypePathEntryKind: " + tag);
    1.62 +            this.tag = tag;
    1.63 +            this.arg = arg;
    1.64 +        }
    1.65 +
    1.66 +        public static TypePathEntry fromBinary(int tag, int arg) {
    1.67 +            Assert.check(arg == 0 || tag == TypePathEntryKind.TYPE_ARGUMENT.tag,
    1.68 +                    "Invalid TypePathEntry tag/arg: " + tag + "/" + arg);
    1.69 +            switch (tag) {
    1.70 +            case 0:
    1.71 +                return ARRAY;
    1.72 +            case 1:
    1.73 +                return INNER_TYPE;
    1.74 +            case 2:
    1.75 +                return WILDCARD;
    1.76 +            case 3:
    1.77 +                return new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg);
    1.78 +            default:
    1.79 +                Assert.error("Invalid TypePathEntryKind tag: " + tag);
    1.80 +                return null;
    1.81 +            }
    1.82 +        }
    1.83 +
    1.84 +        @Override
    1.85 +        public String toString() {
    1.86 +            return tag.toString() +
    1.87 +                    (tag == TypePathEntryKind.TYPE_ARGUMENT ? ("(" + arg + ")") : "");
    1.88 +        }
    1.89 +
    1.90 +        @Override
    1.91 +        public boolean equals(Object other) {
    1.92 +            if (! (other instanceof TypePathEntry)) {
    1.93 +                return false;
    1.94 +            }
    1.95 +            TypePathEntry tpe = (TypePathEntry) other;
    1.96 +            return this.tag == tpe.tag && this.arg == tpe.arg;
    1.97 +        }
    1.98 +
    1.99 +        @Override
   1.100 +        public int hashCode() {
   1.101 +            return this.tag.hashCode() * 17 + this.arg;
   1.102 +        }
   1.103 +    }
   1.104 +
   1.105      public TargetType type = TargetType.UNKNOWN;
   1.106  
   1.107      // For generic/array types.
   1.108 -    public List<Integer> location = List.nil();
   1.109 +    public List<TypePathEntry> location = List.nil();
   1.110  
   1.111      // Tree position.
   1.112      public int pos = -1;
   1.113 @@ -59,11 +141,13 @@
   1.114      // For type parameter and method parameter
   1.115      public int parameter_index = Integer.MIN_VALUE;
   1.116  
   1.117 -    // For class extends, implements, and throws classes
   1.118 +    // For class extends, implements, and throws clauses
   1.119      public int type_index = Integer.MIN_VALUE;
   1.120  
   1.121 -    // For wildcards
   1.122 -    public TypeAnnotationPosition wildcard_position = null;
   1.123 +    // For exception parameters, index into exception table
   1.124 +    public int exception_index = Integer.MIN_VALUE;
   1.125 +
   1.126 +    public TypeAnnotationPosition() {}
   1.127  
   1.128      @Override
   1.129      public String toString() {
   1.130 @@ -72,27 +156,27 @@
   1.131          sb.append(type);
   1.132  
   1.133          switch (type) {
   1.134 -        // type case
   1.135 -        case TYPECAST:
   1.136 -        case TYPECAST_GENERIC_OR_ARRAY:
   1.137 -            // object creation
   1.138 +        // type cast
   1.139 +        case CAST:
   1.140 +        // instanceof
   1.141          case INSTANCEOF:
   1.142 -        case INSTANCEOF_GENERIC_OR_ARRAY:
   1.143 -            // new expression
   1.144 +        // new expression
   1.145          case NEW:
   1.146 -        case NEW_GENERIC_OR_ARRAY:
   1.147 -        case NEW_TYPE_ARGUMENT:
   1.148 -        case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
   1.149              sb.append(", offset = ");
   1.150              sb.append(offset);
   1.151              break;
   1.152 -            // local variable
   1.153 +        // local variable
   1.154          case LOCAL_VARIABLE:
   1.155 -        case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
   1.156 +        // resource variable
   1.157 +        case RESOURCE_VARIABLE:
   1.158 +            if (lvarOffset == null) {
   1.159 +                sb.append(", lvarOffset is null!");
   1.160 +                break;
   1.161 +            }
   1.162              sb.append(", {");
   1.163              for (int i = 0; i < lvarOffset.length; ++i) {
   1.164                  if (i != 0) sb.append("; ");
   1.165 -                sb.append(", start_pc = ");
   1.166 +                sb.append("start_pc = ");
   1.167                  sb.append(lvarOffset[i]);
   1.168                  sb.append(", length = ");
   1.169                  sb.append(lvarLength[i]);
   1.170 @@ -101,73 +185,72 @@
   1.171              }
   1.172              sb.append("}");
   1.173              break;
   1.174 -            // method receiver
   1.175 +        // method receiver
   1.176          case METHOD_RECEIVER:
   1.177              // Do nothing
   1.178              break;
   1.179 -            // type parameters
   1.180 +        // type parameter
   1.181          case CLASS_TYPE_PARAMETER:
   1.182          case METHOD_TYPE_PARAMETER:
   1.183              sb.append(", param_index = ");
   1.184              sb.append(parameter_index);
   1.185              break;
   1.186 -            // type parameters bound
   1.187 +        // type parameter bound
   1.188          case CLASS_TYPE_PARAMETER_BOUND:
   1.189 -        case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
   1.190          case METHOD_TYPE_PARAMETER_BOUND:
   1.191 -        case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
   1.192              sb.append(", param_index = ");
   1.193              sb.append(parameter_index);
   1.194              sb.append(", bound_index = ");
   1.195              sb.append(bound_index);
   1.196              break;
   1.197 -            // wildcard
   1.198 -        case WILDCARD_BOUND:
   1.199 -        case WILDCARD_BOUND_GENERIC_OR_ARRAY:
   1.200 -            sb.append(", wild_card = ");
   1.201 -            sb.append(wildcard_position);
   1.202 -            break;
   1.203 -            // Class extends and implements clauses
   1.204 +        // class extends or implements clause
   1.205          case CLASS_EXTENDS:
   1.206 -        case CLASS_EXTENDS_GENERIC_OR_ARRAY:
   1.207              sb.append(", type_index = ");
   1.208              sb.append(type_index);
   1.209              break;
   1.210 -            // throws
   1.211 +        // throws
   1.212          case THROWS:
   1.213              sb.append(", type_index = ");
   1.214              sb.append(type_index);
   1.215              break;
   1.216 -        case CLASS_LITERAL:
   1.217 -        case CLASS_LITERAL_GENERIC_OR_ARRAY:
   1.218 -            sb.append(", offset = ");
   1.219 -            sb.append(offset);
   1.220 +        // exception parameter
   1.221 +        case EXCEPTION_PARAMETER:
   1.222 +            sb.append(", exception_index = ");
   1.223 +            sb.append(exception_index);
   1.224              break;
   1.225 -            // method parameter: not specified
   1.226 -        case METHOD_PARAMETER_GENERIC_OR_ARRAY:
   1.227 +        // method parameter
   1.228 +        case METHOD_FORMAL_PARAMETER:
   1.229              sb.append(", param_index = ");
   1.230              sb.append(parameter_index);
   1.231              break;
   1.232 -            // method type argument: wasn't specified
   1.233 -        case METHOD_TYPE_ARGUMENT:
   1.234 -        case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
   1.235 +        // method/constructor/reference type argument
   1.236 +        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
   1.237 +        case METHOD_INVOCATION_TYPE_ARGUMENT:
   1.238 +        case METHOD_REFERENCE_TYPE_ARGUMENT:
   1.239              sb.append(", offset = ");
   1.240              sb.append(offset);
   1.241              sb.append(", type_index = ");
   1.242              sb.append(type_index);
   1.243              break;
   1.244 -            // We don't need to worry abut these
   1.245 -        case METHOD_RETURN_GENERIC_OR_ARRAY:
   1.246 -        case FIELD_GENERIC_OR_ARRAY:
   1.247 +        // We don't need to worry about these
   1.248 +        case METHOD_RETURN:
   1.249 +        case FIELD:
   1.250 +            break;
   1.251 +        // lambda formal parameter
   1.252 +        case LAMBDA_FORMAL_PARAMETER:
   1.253 +            // TODO: also needs an offset?
   1.254 +            sb.append(", param_index = ");
   1.255 +            sb.append(parameter_index);
   1.256              break;
   1.257          case UNKNOWN:
   1.258 +            sb.append(", position UNKNOWN!");
   1.259              break;
   1.260          default:
   1.261 -            //                throw new AssertionError("unknown type: " + type);
   1.262 +            Assert.error("Unknown target type: " + type);
   1.263          }
   1.264  
   1.265          // Append location data for generics/arrays.
   1.266 -        if (type.hasLocation()) {
   1.267 +        if (!location.isEmpty()) {
   1.268              sb.append(", location = (");
   1.269              sb.append(location);
   1.270              sb.append(")");
   1.271 @@ -186,10 +269,33 @@
   1.272       * @return true if the target has not been optimized away
   1.273       */
   1.274      public boolean emitToClassfile() {
   1.275 -        if (type == TargetType.WILDCARD_BOUND
   1.276 -            || type == TargetType.WILDCARD_BOUND_GENERIC_OR_ARRAY)
   1.277 -            return wildcard_position.isValidOffset;
   1.278 -        else
   1.279 -            return !type.isLocal() || isValidOffset;
   1.280 +        return !type.isLocal() || isValidOffset;
   1.281 +    }
   1.282 +
   1.283 +    /**
   1.284 +     * Decode the binary representation for a type path and set
   1.285 +     * the {@code location} field.
   1.286 +     *
   1.287 +     * @param list The bytecode representation of the type path.
   1.288 +     */
   1.289 +    public static List<TypePathEntry> getTypePathFromBinary(java.util.List<Integer> list) {
   1.290 +        ListBuffer<TypePathEntry> loc = ListBuffer.lb();
   1.291 +        Iterator<Integer> iter = list.iterator();
   1.292 +        while (iter.hasNext()) {
   1.293 +            Integer fst = iter.next();
   1.294 +            Assert.check(iter.hasNext(), "Could not decode type path: " + list);
   1.295 +            Integer snd = iter.next();
   1.296 +            loc = loc.append(TypePathEntry.fromBinary(fst, snd));
   1.297 +        }
   1.298 +        return loc.toList();
   1.299 +    }
   1.300 +
   1.301 +    public static List<Integer> getBinaryFromTypePath(java.util.List<TypePathEntry> locs) {
   1.302 +        ListBuffer<Integer> loc = ListBuffer.lb();
   1.303 +        for (TypePathEntry tpe : locs) {
   1.304 +            loc = loc.append(tpe.tag.tag);
   1.305 +            loc = loc.append(tpe.arg);
   1.306 +        }
   1.307 +        return loc.toList();
   1.308      }
   1.309  }

mercurial