1.1 --- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java Wed Jan 23 20:57:40 2013 +0000 1.2 +++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.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 @@ -31,12 +31,14 @@ 1.11 import java.util.Set; 1.12 import java.util.HashSet; 1.13 1.14 +import javax.lang.model.type.TypeKind; 1.15 import javax.tools.JavaFileManager; 1.16 import javax.tools.FileObject; 1.17 import javax.tools.JavaFileObject; 1.18 1.19 import com.sun.tools.javac.code.*; 1.20 import com.sun.tools.javac.code.Attribute.RetentionPolicy; 1.21 +import com.sun.tools.javac.code.Attribute.TypeCompound; 1.22 import com.sun.tools.javac.code.Symbol.*; 1.23 import com.sun.tools.javac.code.Type.*; 1.24 import com.sun.tools.javac.code.Types.UniqueType; 1.25 @@ -47,7 +49,6 @@ 1.26 import com.sun.tools.javac.jvm.Pool.Variable; 1.27 import com.sun.tools.javac.util.*; 1.28 1.29 -import static com.sun.tools.javac.code.BoundKind.*; 1.30 import static com.sun.tools.javac.code.Flags.*; 1.31 import static com.sun.tools.javac.code.Kinds.*; 1.32 import static com.sun.tools.javac.code.TypeTag.*; 1.33 @@ -68,19 +69,17 @@ 1.34 protected static final Context.Key<ClassWriter> classWriterKey = 1.35 new Context.Key<ClassWriter>(); 1.36 1.37 - private final Symtab syms; 1.38 - 1.39 private final Options options; 1.40 1.41 /** Switch: verbose output. 1.42 */ 1.43 private boolean verbose; 1.44 1.45 - /** Switch: scramble private names. 1.46 + /** Switch: scramble private field names. 1.47 */ 1.48 private boolean scramble; 1.49 1.50 - /** Switch: scramble private names. 1.51 + /** Switch: scramble all field names. 1.52 */ 1.53 private boolean scrambleAll; 1.54 1.55 @@ -96,7 +95,7 @@ 1.56 */ 1.57 private boolean genCrt; 1.58 1.59 - /** Switch: describe the generated stackmap 1.60 + /** Switch: describe the generated stackmap. 1.61 */ 1.62 boolean debugstackmap; 1.63 1.64 @@ -114,7 +113,7 @@ 1.65 private Types types; 1.66 1.67 /** The initial sizes of the data and constant pool buffers. 1.68 - * sizes are increased when buffers get full. 1.69 + * Sizes are increased when buffers get full. 1.70 */ 1.71 static final int DATA_BUF_SIZE = 0x0fff0; 1.72 static final int POOL_BUF_SIZE = 0x1fff0; 1.73 @@ -181,7 +180,6 @@ 1.74 1.75 log = Log.instance(context); 1.76 names = Names.instance(context); 1.77 - syms = Symtab.instance(context); 1.78 options = Options.instance(context); 1.79 target = Target.instance(context); 1.80 source = Source.instance(context); 1.81 @@ -279,6 +277,7 @@ 1.82 /** Assemble signature of given type in string buffer. 1.83 */ 1.84 void assembleSig(Type type) { 1.85 + type = type.unannotatedType(); 1.86 switch (type.getTag()) { 1.87 case BYTE: 1.88 sigbuf.appendByte('B'); 1.89 @@ -379,6 +378,7 @@ 1.90 } 1.91 1.92 void assembleClassSig(Type type) { 1.93 + type = type.unannotatedType(); 1.94 ClassType ct = (ClassType)type; 1.95 ClassSymbol c = (ClassSymbol)ct.tsym; 1.96 enterInner(c); 1.97 @@ -722,6 +722,7 @@ 1.98 acount++; 1.99 } 1.100 acount += writeJavaAnnotations(sym.getRawAttributes()); 1.101 + acount += writeTypeAnnotations(sym.getRawTypeAttributes()); 1.102 return acount; 1.103 } 1.104 1.105 @@ -838,6 +839,76 @@ 1.106 return attrCount; 1.107 } 1.108 1.109 + int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos) { 1.110 + if (typeAnnos.isEmpty()) return 0; 1.111 + 1.112 + ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb(); 1.113 + ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb(); 1.114 + 1.115 + for (Attribute.TypeCompound tc : typeAnnos) { 1.116 + if (tc.position == null || tc.position.type == TargetType.UNKNOWN) { 1.117 + boolean found = false; 1.118 + // TODO: the position for the container annotation of a 1.119 + // repeating type annotation has to be set. 1.120 + // This cannot be done when the container is created, because 1.121 + // then the position is not determined yet. 1.122 + // How can we link these pieces better together? 1.123 + if (tc.values.size() == 1) { 1.124 + Pair<MethodSymbol, Attribute> val = tc.values.get(0); 1.125 + if (val.fst.getSimpleName().contentEquals("value") && 1.126 + val.snd instanceof Attribute.Array) { 1.127 + Attribute.Array arr = (Attribute.Array) val.snd; 1.128 + if (arr.values.length != 0 && 1.129 + arr.values[0] instanceof Attribute.TypeCompound) { 1.130 + TypeCompound atycomp = (Attribute.TypeCompound) arr.values[0]; 1.131 + if (atycomp.position.type != TargetType.UNKNOWN) { 1.132 + tc.position = atycomp.position; 1.133 + found = true; 1.134 + } 1.135 + } 1.136 + } 1.137 + } 1.138 + if (!found) { 1.139 + // This happens for nested types like @A Outer. @B Inner. 1.140 + // For method parameters we get the annotation twice! Once with 1.141 + // a valid position, once unknown. 1.142 + // TODO: find a cleaner solution. 1.143 + // System.err.println("ClassWriter: Position UNKNOWN in type annotation: " + tc); 1.144 + continue; 1.145 + } 1.146 + } 1.147 + if (!tc.position.emitToClassfile()) 1.148 + continue; 1.149 + switch (types.getRetention(tc)) { 1.150 + case SOURCE: break; 1.151 + case CLASS: invisibles.append(tc); break; 1.152 + case RUNTIME: visibles.append(tc); break; 1.153 + default: ;// /* fail soft */ throw new AssertionError(vis); 1.154 + } 1.155 + } 1.156 + 1.157 + int attrCount = 0; 1.158 + if (visibles.length() != 0) { 1.159 + int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations); 1.160 + databuf.appendChar(visibles.length()); 1.161 + for (Attribute.TypeCompound p : visibles) 1.162 + writeTypeAnnotation(p); 1.163 + endAttr(attrIndex); 1.164 + attrCount++; 1.165 + } 1.166 + 1.167 + if (invisibles.length() != 0) { 1.168 + int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations); 1.169 + databuf.appendChar(invisibles.length()); 1.170 + for (Attribute.TypeCompound p : invisibles) 1.171 + writeTypeAnnotation(p); 1.172 + endAttr(attrIndex); 1.173 + attrCount++; 1.174 + } 1.175 + 1.176 + return attrCount; 1.177 + } 1.178 + 1.179 /** A visitor to write an attribute including its leading 1.180 * single-character marker. 1.181 */ 1.182 @@ -914,6 +985,94 @@ 1.183 p.snd.accept(awriter); 1.184 } 1.185 } 1.186 + 1.187 + void writeTypeAnnotation(Attribute.TypeCompound c) { 1.188 + writePosition(c.position); 1.189 + writeCompoundAttribute(c); 1.190 + } 1.191 + 1.192 + void writePosition(TypeAnnotationPosition p) { 1.193 + databuf.appendByte(p.type.targetTypeValue()); // TargetType tag is a byte 1.194 + switch (p.type) { 1.195 + // type cast 1.196 + case CAST: 1.197 + // instanceof 1.198 + case INSTANCEOF: 1.199 + // new expression 1.200 + case NEW: 1.201 + databuf.appendChar(p.offset); 1.202 + break; 1.203 + // local variable 1.204 + case LOCAL_VARIABLE: 1.205 + // resource variable 1.206 + case RESOURCE_VARIABLE: 1.207 + databuf.appendChar(p.lvarOffset.length); // for table length 1.208 + for (int i = 0; i < p.lvarOffset.length; ++i) { 1.209 + databuf.appendChar(p.lvarOffset[i]); 1.210 + databuf.appendChar(p.lvarLength[i]); 1.211 + databuf.appendChar(p.lvarIndex[i]); 1.212 + } 1.213 + break; 1.214 + // exception parameter 1.215 + case EXCEPTION_PARAMETER: 1.216 + databuf.appendByte(p.exception_index); 1.217 + break; 1.218 + // method receiver 1.219 + case METHOD_RECEIVER: 1.220 + // Do nothing 1.221 + break; 1.222 + // type parameter 1.223 + case CLASS_TYPE_PARAMETER: 1.224 + case METHOD_TYPE_PARAMETER: 1.225 + databuf.appendByte(p.parameter_index); 1.226 + break; 1.227 + // type parameter bound 1.228 + case CLASS_TYPE_PARAMETER_BOUND: 1.229 + case METHOD_TYPE_PARAMETER_BOUND: 1.230 + databuf.appendByte(p.parameter_index); 1.231 + databuf.appendByte(p.bound_index); 1.232 + break; 1.233 + // class extends or implements clause 1.234 + case CLASS_EXTENDS: 1.235 + databuf.appendChar(p.type_index); 1.236 + break; 1.237 + // throws 1.238 + case THROWS: 1.239 + databuf.appendChar(p.type_index); 1.240 + break; 1.241 + // method parameter 1.242 + case METHOD_FORMAL_PARAMETER: 1.243 + databuf.appendByte(p.parameter_index); 1.244 + break; 1.245 + // method/constructor/reference type argument 1.246 + case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: 1.247 + case METHOD_INVOCATION_TYPE_ARGUMENT: 1.248 + case METHOD_REFERENCE_TYPE_ARGUMENT: 1.249 + databuf.appendChar(p.offset); 1.250 + databuf.appendByte(p.type_index); 1.251 + break; 1.252 + // We don't need to worry about these 1.253 + case METHOD_RETURN: 1.254 + case FIELD: 1.255 + break; 1.256 + // lambda formal parameter 1.257 + case LAMBDA_FORMAL_PARAMETER: 1.258 + databuf.appendByte(p.parameter_index); 1.259 + break; 1.260 + case UNKNOWN: 1.261 + throw new AssertionError("jvm.ClassWriter: UNKNOWN target type should never occur!"); 1.262 + default: 1.263 + throw new AssertionError("jvm.ClassWriter: Unknown target type for position: " + p); 1.264 + } 1.265 + 1.266 + { // Append location data for generics/arrays. 1.267 + databuf.appendByte(p.location.size()); 1.268 + java.util.List<Integer> loc = TypeAnnotationPosition.getBinaryFromTypePath(p.location); 1.269 + for (int i : loc) 1.270 + databuf.appendByte((byte)i); 1.271 + } 1.272 + } 1.273 + 1.274 /********************************************************************** 1.275 * Writing Objects 1.276 **********************************************************************/ 1.277 @@ -1661,6 +1820,7 @@ 1.278 1.279 acount += writeFlagAttrs(c.flags()); 1.280 acount += writeJavaAnnotations(c.getRawAttributes()); 1.281 + acount += writeTypeAnnotations(c.getRawTypeAttributes()); 1.282 acount += writeEnclosingMethodAttribute(c); 1.283 acount += writeExtraClassAttributes(c); 1.284