--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Jun 26 12:22:40 2009 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java Fri Jun 26 18:51:39 2009 -0700
@@ -47,7 +47,6 @@
import com.sun.tools.javac.code.Symtab;
import com.sun.tools.javac.file.BaseFileObject;
import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
import static com.sun.tools.javac.code.Flags.*;
import static com.sun.tools.javac.code.Kinds.*;
@@ -187,6 +186,10 @@
/** The minor version number of the class file being read. */
int minorVersion;
+ /** Switch: debug output for JSR 308-related operations.
+ */
+ boolean debugJSR308;
+
/** Get the ClassReader instance for this invocation. */
public static ClassReader instance(Context context) {
ClassReader instance = context.get(classReaderKey);
@@ -256,6 +259,7 @@
: null;
typevars = new Scope(syms.noSymbol);
+ debugJSR308 = options.get("TA:reader") != null;
initAttributeReaders();
}
@@ -303,6 +307,12 @@
return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
}
+ /** Read a byte.
+ */
+ byte nextByte() {
+ return buf[bp++];
+ }
+
/** Read an integer.
*/
int nextInt() {
@@ -1060,7 +1070,21 @@
if (allowVarargs)
sym.flags_field |= VARARGS;
}
- }
+ },
+
+ // v51 attributes
+ new AttributeReader(names.RuntimeVisibleTypeAnnotations, V51, CLASS_OR_MEMBER_ATTRIBUTE) {
+ void read(Symbol sym, int attrLen) {
+ attachTypeAnnotations(sym);
+ }
+ },
+
+ new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V51, CLASS_OR_MEMBER_ATTRIBUTE) {
+ void read(Symbol sym, int attrLen) {
+ attachTypeAnnotations(sym);
+ }
+ },
+
// The following attributes for a Code attribute are not currently handled
// StackMapTable
@@ -1268,6 +1292,17 @@
}
}
+ void attachTypeAnnotations(final Symbol sym) {
+ int numAttributes = nextChar();
+ if (numAttributes != 0) {
+ ListBuffer<TypeAnnotationProxy> proxies =
+ ListBuffer.lb();
+ for (int i = 0; i < numAttributes; i++)
+ proxies.append(readTypeAnnotation());
+ annotate.later(new TypeAnnotationCompleter(sym, proxies.toList()));
+ }
+ }
+
/** Attach the default value for an annotation element.
*/
void attachAnnotationDefault(final Symbol sym) {
@@ -1304,6 +1339,121 @@
return new CompoundAnnotationProxy(t, pairs.toList());
}
+ TypeAnnotationProxy readTypeAnnotation() {
+ CompoundAnnotationProxy proxy = readCompoundAnnotation();
+ TypeAnnotationPosition position = readPosition();
+
+ if (debugJSR308)
+ System.out.println("TA: reading: " + proxy + " @ " + position
+ + " in " + log.currentSourceFile());
+
+ return new TypeAnnotationProxy(proxy, position);
+ }
+
+ TypeAnnotationPosition readPosition() {
+ byte tag = nextByte();
+
+ if (!TargetType.isValidTargetTypeValue(tag))
+ throw this.badClassFile("bad.type.annotation.value", tag);
+
+ TypeAnnotationPosition position = new TypeAnnotationPosition();
+ TargetType type = TargetType.fromTargetTypeValue(tag);
+
+ position.type = type;
+
+ switch (type) {
+ // type case
+ case TYPECAST:
+ case TYPECAST_GENERIC_OR_ARRAY:
+ // object creation
+ case INSTANCEOF:
+ case INSTANCEOF_GENERIC_OR_ARRAY:
+ // new expression
+ case NEW:
+ case NEW_GENERIC_OR_ARRAY:
+ position.offset = nextChar();
+ break;
+ // local variable
+ case LOCAL_VARIABLE:
+ case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
+ int table_length = nextChar();
+ position.lvarOffset = new int[table_length];
+ position.lvarLength = new int[table_length];
+ position.lvarIndex = new int[table_length];
+
+ for (int i = 0; i < table_length; ++i) {
+ position.lvarOffset[i] = nextChar();
+ position.lvarLength[i] = nextChar();
+ position.lvarIndex[i] = nextChar();
+ }
+ break;
+ // method receiver
+ case METHOD_RECEIVER:
+ // Do nothing
+ break;
+ // type parameters
+ case CLASS_TYPE_PARAMETER:
+ case METHOD_TYPE_PARAMETER:
+ position.parameter_index = nextByte();
+ break;
+ // type parameter bounds
+ case CLASS_TYPE_PARAMETER_BOUND:
+ case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+ case METHOD_TYPE_PARAMETER_BOUND:
+ case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+ position.parameter_index = nextByte();
+ position.bound_index = nextByte();
+ break;
+ // wildcard
+ case WILDCARD_BOUND:
+ case WILDCARD_BOUND_GENERIC_OR_ARRAY:
+ position.wildcard_position = readPosition();
+ break;
+ // Class extends and implements clauses
+ case CLASS_EXTENDS:
+ case CLASS_EXTENDS_GENERIC_OR_ARRAY:
+ position.type_index = nextByte();
+ break;
+ // throws
+ case THROWS:
+ position.type_index = nextByte();
+ break;
+ case CLASS_LITERAL:
+ case CLASS_LITERAL_GENERIC_OR_ARRAY:
+ position.offset = nextChar();
+ break;
+ // method parameter: not specified
+ case METHOD_PARAMETER_GENERIC_OR_ARRAY:
+ position.parameter_index = nextByte();
+ break;
+ // method type argument: wasn't specified
+ case NEW_TYPE_ARGUMENT:
+ case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+ case METHOD_TYPE_ARGUMENT:
+ case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+ position.offset = nextChar();
+ position.type_index = nextByte();
+ break;
+ // We don't need to worry abut these
+ case METHOD_RETURN_GENERIC_OR_ARRAY:
+ case FIELD_GENERIC_OR_ARRAY:
+ break;
+ case UNKNOWN:
+ break;
+ default:
+ throw new AssertionError("unknown type: " + position);
+ }
+
+ if (type.hasLocation()) {
+ int len = nextChar();
+ ListBuffer<Integer> loc = ListBuffer.lb();
+ for (int i = 0; i < len; i++)
+ loc = loc.append((int)nextByte());
+ position.location = loc.toList();
+ }
+
+ return position;
+ }
Attribute readAttributeValue() {
char c = (char) buf[bp++];
switch (c) {
@@ -1408,6 +1558,18 @@
}
}
+ /** A temporary proxy representing a type annotation.
+ */
+ static class TypeAnnotationProxy {
+ final CompoundAnnotationProxy compound;
+ final TypeAnnotationPosition position;
+ public TypeAnnotationProxy(CompoundAnnotationProxy compound,
+ TypeAnnotationPosition position) {
+ this.compound = compound;
+ this.position = position;
+ }
+ }
+
class AnnotationDeproxy implements ProxyVisitor {
private ClassSymbol requestingOwner = currentOwner.kind == MTH
? currentOwner.enclClass() : (ClassSymbol)currentOwner;
@@ -1604,6 +1766,45 @@
}
}
+ class TypeAnnotationCompleter extends AnnotationCompleter {
+
+ List<TypeAnnotationProxy> proxies;
+
+ TypeAnnotationCompleter(Symbol sym,
+ List<TypeAnnotationProxy> proxies) {
+ super(sym, List.<CompoundAnnotationProxy>nil());
+ this.proxies = proxies;
+ }
+
+ List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
+ ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
+ for (TypeAnnotationProxy proxy: proxies) {
+ Attribute.Compound compound = deproxyCompound(proxy.compound);
+ Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
+ buf.add(typeCompound);
+ }
+ return buf.toList();
+ }
+
+ @Override
+ public void enterAnnotation() {
+ JavaFileObject previousClassFile = currentClassFile;
+ try {
+ currentClassFile = classFile;
+ List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies);
+ if (debugJSR308)
+ System.out.println("TA: reading: adding " + newList
+ + " to symbol " + sym + " in " + log.currentSourceFile());
+ sym.typeAnnotations = ((sym.typeAnnotations == null)
+ ? newList
+ : newList.prependList(sym.typeAnnotations));
+
+ } finally {
+ currentClassFile = previousClassFile;
+ }
+ }
+ }
+
/************************************************************************
* Reading Symbols