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 }