1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jan 23 20:57:40 2013 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Wed Jan 23 13:27:24 2013 -0800 1.3 @@ -1,5 +1,5 @@ 1.4 /* 1.5 - * Copyright (c) 1999, 2012, Oracle and/or its affiliates. All rights reserved. 1.6 + * Copyright (c) 1999, 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 @@ -351,8 +351,8 @@ 1.11 1.12 /** Read a byte. 1.13 */ 1.14 - byte nextByte() { 1.15 - return buf[bp++]; 1.16 + int nextByte() { 1.17 + return buf[bp++] & 0xFF; 1.18 } 1.19 1.20 /** Read an integer. 1.21 @@ -1172,6 +1172,19 @@ 1.22 } 1.23 }, 1.24 1.25 + new AttributeReader(names.RuntimeVisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) { 1.26 + protected void read(Symbol sym, int attrLen) { 1.27 + attachTypeAnnotations(sym); 1.28 + } 1.29 + }, 1.30 + 1.31 + new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V52, CLASS_OR_MEMBER_ATTRIBUTE) { 1.32 + protected void read(Symbol sym, int attrLen) { 1.33 + attachTypeAnnotations(sym); 1.34 + } 1.35 + }, 1.36 + 1.37 + 1.38 // The following attributes for a Code attribute are not currently handled 1.39 // StackMapTable 1.40 // SourceDebugExtension 1.41 @@ -1381,6 +1394,17 @@ 1.42 } 1.43 } 1.44 1.45 + void attachTypeAnnotations(final Symbol sym) { 1.46 + int numAttributes = nextChar(); 1.47 + if (numAttributes != 0) { 1.48 + ListBuffer<TypeAnnotationProxy> proxies = 1.49 + ListBuffer.lb(); 1.50 + for (int i = 0; i < numAttributes; i++) 1.51 + proxies.append(readTypeAnnotation()); 1.52 + annotate.normal(new TypeAnnotationCompleter(sym, proxies.toList())); 1.53 + } 1.54 + } 1.55 + 1.56 /** Attach the default value for an annotation element. 1.57 */ 1.58 void attachAnnotationDefault(final Symbol sym) { 1.59 @@ -1427,6 +1451,111 @@ 1.60 return new CompoundAnnotationProxy(t, pairs.toList()); 1.61 } 1.62 1.63 + TypeAnnotationProxy readTypeAnnotation() { 1.64 + TypeAnnotationPosition position = readPosition(); 1.65 + CompoundAnnotationProxy proxy = readCompoundAnnotation(); 1.66 + 1.67 + return new TypeAnnotationProxy(proxy, position); 1.68 + } 1.69 + 1.70 + TypeAnnotationPosition readPosition() { 1.71 + int tag = nextByte(); // TargetType tag is a byte 1.72 + 1.73 + if (!TargetType.isValidTargetTypeValue(tag)) 1.74 + throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag)); 1.75 + 1.76 + TypeAnnotationPosition position = new TypeAnnotationPosition(); 1.77 + TargetType type = TargetType.fromTargetTypeValue(tag); 1.78 + 1.79 + position.type = type; 1.80 + 1.81 + switch (type) { 1.82 + // type cast 1.83 + case CAST: 1.84 + // instanceof 1.85 + case INSTANCEOF: 1.86 + // new expression 1.87 + case NEW: 1.88 + position.offset = nextChar(); 1.89 + break; 1.90 + // local variable 1.91 + case LOCAL_VARIABLE: 1.92 + // resource variable 1.93 + case RESOURCE_VARIABLE: 1.94 + int table_length = nextChar(); 1.95 + position.lvarOffset = new int[table_length]; 1.96 + position.lvarLength = new int[table_length]; 1.97 + position.lvarIndex = new int[table_length]; 1.98 + 1.99 + for (int i = 0; i < table_length; ++i) { 1.100 + position.lvarOffset[i] = nextChar(); 1.101 + position.lvarLength[i] = nextChar(); 1.102 + position.lvarIndex[i] = nextChar(); 1.103 + } 1.104 + break; 1.105 + // exception parameter 1.106 + case EXCEPTION_PARAMETER: 1.107 + position.exception_index = nextByte(); 1.108 + break; 1.109 + // method receiver 1.110 + case METHOD_RECEIVER: 1.111 + // Do nothing 1.112 + break; 1.113 + // type parameter 1.114 + case CLASS_TYPE_PARAMETER: 1.115 + case METHOD_TYPE_PARAMETER: 1.116 + position.parameter_index = nextByte(); 1.117 + break; 1.118 + // type parameter bound 1.119 + case CLASS_TYPE_PARAMETER_BOUND: 1.120 + case METHOD_TYPE_PARAMETER_BOUND: 1.121 + position.parameter_index = nextByte(); 1.122 + position.bound_index = nextByte(); 1.123 + break; 1.124 + // class extends or implements clause 1.125 + case CLASS_EXTENDS: 1.126 + position.type_index = nextChar(); 1.127 + break; 1.128 + // throws 1.129 + case THROWS: 1.130 + position.type_index = nextChar(); 1.131 + break; 1.132 + // method parameter 1.133 + case METHOD_FORMAL_PARAMETER: 1.134 + position.parameter_index = nextByte(); 1.135 + break; 1.136 + // method/constructor/reference type argument 1.137 + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 1.138 + case METHOD_INVOCATION_TYPE_ARGUMENT: 1.139 + case METHOD_REFERENCE_TYPE_ARGUMENT: 1.140 + position.offset = nextChar(); 1.141 + position.type_index = nextByte(); 1.142 + break; 1.143 + // We don't need to worry about these 1.144 + case METHOD_RETURN: 1.145 + case FIELD: 1.146 + break; 1.147 + // lambda formal parameter 1.148 + case LAMBDA_FORMAL_PARAMETER: 1.149 + position.parameter_index = nextByte(); 1.150 + break; 1.151 + case UNKNOWN: 1.152 + throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!"); 1.153 + default: 1.154 + throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + position); 1.155 + } 1.156 + 1.157 + { // See whether there is location info and read it 1.158 + int len = nextByte(); 1.159 + ListBuffer<Integer> loc = ListBuffer.lb(); 1.160 + for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i) 1.161 + loc = loc.append(nextByte()); 1.162 + position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList()); 1.163 + } 1.164 + 1.165 + return position; 1.166 + } 1.167 + 1.168 Attribute readAttributeValue() { 1.169 char c = (char) buf[bp++]; 1.170 switch (c) { 1.171 @@ -1748,7 +1877,7 @@ 1.172 Annotations annotations = sym.annotations; 1.173 List<Attribute.Compound> newList = deproxyCompoundList(l); 1.174 if (annotations.pendingCompletion()) { 1.175 - annotations.setAttributes(newList); 1.176 + annotations.setDeclarationAttributes(newList); 1.177 } else { 1.178 annotations.append(newList); 1.179 } 1.180 @@ -1758,6 +1887,39 @@ 1.181 } 1.182 } 1.183 1.184 + class TypeAnnotationCompleter extends AnnotationCompleter { 1.185 + 1.186 + List<TypeAnnotationProxy> proxies; 1.187 + 1.188 + TypeAnnotationCompleter(Symbol sym, 1.189 + List<TypeAnnotationProxy> proxies) { 1.190 + super(sym, List.<CompoundAnnotationProxy>nil()); 1.191 + this.proxies = proxies; 1.192 + } 1.193 + 1.194 + List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) { 1.195 + ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb(); 1.196 + for (TypeAnnotationProxy proxy: proxies) { 1.197 + Attribute.Compound compound = deproxyCompound(proxy.compound); 1.198 + Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position); 1.199 + buf.add(typeCompound); 1.200 + } 1.201 + return buf.toList(); 1.202 + } 1.203 + 1.204 + @Override 1.205 + public void enterAnnotation() { 1.206 + JavaFileObject previousClassFile = currentClassFile; 1.207 + try { 1.208 + currentClassFile = classFile; 1.209 + List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies); 1.210 + sym.annotations.setTypeAttributes(newList.prependList(sym.getRawTypeAttributes())); 1.211 + } finally { 1.212 + currentClassFile = previousClassFile; 1.213 + } 1.214 + } 1.215 + } 1.216 + 1.217 1.218 /************************************************************************ 1.219 * Reading Symbols