1 /* 2 * Copyright (c) 1996, 2020, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 package org.openjdk.asmtools.jasm; 24 25 import java.io.PrintWriter; 26 27 /** 28 * Type annotation types: target_type, target_info && target_path 29 */ 30 public class TypeAnnotationTypes { 31 32 /** 33 * Interpretation of type_path_kind values (Table 4.7.20.2-A) 34 */ 35 public enum EPathKind { 36 ARRAY(0), 37 INNER_TYPE(1), 38 WILDCARD(2), 39 TYPE_ARGUMENT(3); 40 41 private final int tag; 42 public static final int maxLen = 3; 43 44 EPathKind(int tag) { 45 this.tag = tag; 46 } 47 48 public int tag() { 49 return tag; 50 } 51 52 public String parseKey() { 53 return this.toString(); 54 } 55 56 static EPathKind getPathKind(String token) { 57 for (EPathKind pk : values()) { 58 if( pk.parseKey().equals(token)) { 59 return pk; 60 } 61 } 62 return null; 63 } 64 } 65 66 // will throw ArrayIndexOutOfBounds if i < 0 or i > 3 67 static public EPathKind getPathKind(int i) { 68 return EPathKind.values()[i]; 69 } 70 71 static public class TypePathEntry { 72 73 private final EPathKind kind; 74 private final int typeArgumentIndex; 75 76 public TypePathEntry(int kind, int typeArgumentIndex) { 77 this.kind = getPathKind(kind); 78 this.typeArgumentIndex = typeArgumentIndex; 79 } 80 81 public TypePathEntry(EPathKind kind, int typeArgumentIndex) { 82 this.kind = kind; 83 this.typeArgumentIndex = typeArgumentIndex; 84 } 85 86 public int getTypePathKind() { 87 return kind.tag(); 88 } 89 90 public int getTypeArgumentIndex() { 91 return typeArgumentIndex; 92 } 93 94 @Override 95 public String toString() { 96 // Chapter 4.7.20.2 The type_path structure 97 // if the value of the type_path_kind is 0,1, or 2, thebn the value of the 98 // type_argument_index item is 0. 99 return kind.parseKey() + ( kind.tag == 3 ? 100 JasmTokens.Token.LBRACE.parseKey() + typeArgumentIndex + JasmTokens.Token.RBRACE.parseKey() : 101 ""); 102 } 103 } 104 105 /** 106 * union { 107 * type_parameter_target; 108 * supertype_target; 109 * type_parameter_bound_target; 110 * empty_target; 111 * method_formal_parameter_target; 112 * throws_target; 113 * localvar_target; 114 * catch_target; 115 * offset_target; 116 * type_argument_target; 117 * } target_info; 118 */ 119 public enum ETargetInfo { 120 TYPEPARAM ("TYPEPARAM", "type_parameter"), 121 SUPERTYPE ("SUPERTYPE", "supertype"), 122 TYPEPARAM_BOUND ("TYPEPARAM_BOUND", "type_parameter_bound"), 123 EMPTY ("EMPTY", "empty"), 124 METHODPARAM ("METHODPARAM", "formal_parameter"), 125 EXCEPTION ("EXCEPTION", "throws"), 126 LOCALVAR ("LOCALVAR", "localvar"), 127 CATCH ("CATCH", "catch"), 128 OFFSET ("OFFSET", "offset"), 129 TYPEARG ("TYPEARG", "type_argument"); 130 131 private final String parseKey; 132 private final String printValue; 133 134 ETargetInfo(String parse, String printValue) { 135 parseKey = parse; 136 this.printValue = printValue; 137 } 138 public String parseKey() { 139 return this.parseKey; 140 } 141 142 public String printValue() { 143 return this.printValue; 144 } 145 } 146 147 /** 148 * Interpretation of target_type values (Table 4.7.20-A./B.) 149 */ 150 static public enum ETargetType { 151 class_type_param (0x00, "CLASS_TYPE_PARAMETER", ETargetInfo.TYPEPARAM, "class/interface type parameter"), 152 meth_type_param (0x01, "METHOD_TYPE_PARAMETER", ETargetInfo.TYPEPARAM, "method/constructor type parameter"), 153 class_exts_impls (0x10, "CLASS_EXTENDS", ETargetInfo.SUPERTYPE, "class extends/implements"), 154 class_type_param_bnds (0x11, "CLASS_TYPE_PARAMETER_BOUND", ETargetInfo.TYPEPARAM_BOUND, "class/interface type parameter bounds"), 155 meth_type_param_bnds (0x12, "METHOD_TYPE_PARAMETER_BOUND", ETargetInfo.TYPEPARAM_BOUND, "method/constructor type parameter bounds"), 156 field (0x13, "FIELD", ETargetInfo.EMPTY, "field"), 157 meth_ret_type (0x14, "METHOD_RETURN", ETargetInfo.EMPTY, "method return type"), 158 meth_receiver (0x15, "METHOD_RECEIVER", ETargetInfo.EMPTY, "method receiver"), 159 meth_formal_param (0x16, "METHOD_FORMAL_PARAMETER", ETargetInfo.METHODPARAM, "method formal parameter type"), 160 throws_type (0x17, "THROWS", ETargetInfo.EXCEPTION, "exception type in throws"), 161 162 local_var (0x40, "LOCAL_VARIABLE", ETargetInfo.LOCALVAR, "local variable"), 163 resource_var (0x41, "RESOURCE_VARIABLE", ETargetInfo.LOCALVAR, "resource variable"), 164 exception_param (0x42, "EXCEPTION_PARAM", ETargetInfo.CATCH, "exception parameter"), 165 type_test (0x43, "INSTANCEOF", ETargetInfo.OFFSET, "type test (instanceof)"), 166 obj_creat (0x44, "NEW", ETargetInfo.OFFSET, "object creation (new)"), 167 constr_ref_receiver (0x45, "CONSTRUCTOR_REFERENCE_RECEIVER", ETargetInfo.OFFSET, "constructor reference receiver"), 168 meth_ref_receiver (0x46, "METHOD_REFERENCE_RECEIVER", ETargetInfo.OFFSET, "method reference receiver"), 169 cast (0x47, "CAST", ETargetInfo.TYPEARG, "cast"), 170 constr_invoc_typearg (0x48, "CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in constructor call"), 171 meth_invoc_typearg (0x49, "METHOD_INVOCATION_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in method call"), 172 constr_ref_typearg (0x4A, "CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in constructor reference"), 173 meth_ref_typearg (0x4B, "METHOD_REFERENCE_TYPE_ARGUMENT", ETargetInfo.TYPEARG, "type argument in method reference"); 174 175 public static final int maxTag = 0x9A; 176 public static final int maxLen = 36; 177 178 public final int value; 179 private final String parseKey; 180 private final ETargetInfo targetInfo; 181 private final String printVal; 182 183 ETargetType(int val, String parse, ETargetInfo targetInfo, String printVal) { 184 value = val; 185 parseKey = parse; 186 this.targetInfo = targetInfo; 187 this.printVal = printVal; 188 } 189 190 public String parseKey() { 191 return parseKey; 192 } 193 194 public String infoKey() { 195 return targetInfo.parseKey(); 196 } 197 198 public ETargetInfo targetInfo() { 199 return targetInfo; 200 } 201 202 public void print(PrintWriter out) { 203 out.print(parseKey); 204 } 205 206 @Override 207 public String toString() { 208 return String.format("%s[%#x]", parseKey, value); 209 } 210 211 public static ETargetType getTargetType(int typeCode) { 212 for( ETargetType type: ETargetType.values() ) { 213 if (type.value == typeCode) { 214 return type; 215 } 216 } 217 return null; 218 } 219 220 static public ETargetType getTargetType(String typeName) { 221 for( ETargetType type: ETargetType.values() ) { 222 if (type.parseKey.equals(typeName)) { 223 return type; 224 } 225 } 226 return null; 227 } 228 }; 229 230 /* TypeAnnotationVisitor Methods */ 231 public static class TypeAnnotationTargetVisitor { 232 233 public final void visit(ETargetType tt) { 234 switch (tt) { 235 case class_type_param: 236 case meth_type_param: 237 visit_type_param_target(tt); 238 break; 239 case class_exts_impls: 240 visit_supertype_target(tt); 241 break; 242 case class_type_param_bnds: 243 case meth_type_param_bnds: 244 visit_typeparam_bound_target(tt); 245 break; 246 case field: 247 case meth_ret_type: 248 case meth_receiver: 249 visit_empty_target(tt); 250 break; 251 case meth_formal_param: 252 visit_methodformalparam_target(tt); 253 break; 254 case throws_type: 255 visit_throws_target(tt); 256 break; 257 case local_var: 258 case resource_var: 259 visit_localvar_target(tt); 260 break; 261 case exception_param: 262 visit_catch_target(tt); 263 break; 264 case type_test: 265 case obj_creat: 266 case constr_ref_receiver: 267 case meth_ref_receiver: 268 visit_offset_target(tt); 269 break; 270 271 case cast: 272 case constr_invoc_typearg: 273 case meth_invoc_typearg: 274 case constr_ref_typearg: 275 case meth_ref_typearg: 276 277 visit_typearg_target(tt); 278 break; 279 } 280 } 281 282 public void visit_type_param_target(ETargetType tt) { 283 } 284 285 public void visit_supertype_target(ETargetType tt) { 286 } 287 288 public void visit_typeparam_bound_target(ETargetType tt) { 289 } 290 291 public void visit_empty_target(ETargetType tt) { 292 } 293 294 public void visit_methodformalparam_target(ETargetType tt) { 295 } 296 297 public void visit_throws_target(ETargetType tt) { 298 } 299 300 public void visit_localvar_target(ETargetType tt) { 301 } 302 303 public void visit_catch_target(ETargetType tt) { 304 } 305 306 public void visit_offset_target(ETargetType tt) { 307 } 308 309 public void visit_typearg_target(ETargetType tt) { 310 } 311 } 312 }