8033004: Make base TypeAnnotationPosition data immutable, create better methods for creating base TypeAnnotationPositions
authoremc
Mon, 03 Feb 2014 17:19:15 -0500
changeset 22702 1297fbaf34fa
parent 22701 67811024e8b4
child 22703 322d8adeabe1
8033004: Make base TypeAnnotationPosition data immutable, create better methods for creating base TypeAnnotationPositions Summary: First of a series of major fixes to type annotations; cleans up interface with TypeAnnotationPosition Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java
langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java
langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java
langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java
langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java
langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java
--- a/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java	Sun Feb 02 12:12:01 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/SymbolMetadata.java	Mon Feb 03 17:19:15 2014 -0500
@@ -425,11 +425,15 @@
         private final List<T> placeholderFor;
         private final Symbol on;
 
-        public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx, List<T> placeholderFor, Symbol on) {
+        public Placeholder(Annotate.AnnotateRepeatedContext<T> ctx,
+                           List<T> placeholderFor, Symbol on) {
             super(on.type, List.<Pair<Symbol.MethodSymbol, Attribute>>nil(),
-                    ctx.isTypeCompound ?
-                            ((Attribute.TypeCompound)placeholderFor.head).position :
-                                new TypeAnnotationPosition());
+                  ctx.isTypeCompound ?
+                  ((Attribute.TypeCompound)placeholderFor.head).position :
+                  // TODO: Eventually, we will need to get rid of this
+                  // use of unknown, either by using null, or by
+                  // throwing an assertion failure here.
+                  TypeAnnotationPosition.unknown);
             this.ctx = ctx;
             this.placeholderFor = placeholderFor;
             this.on = on;
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Sun Feb 02 12:12:01 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotationPosition.java	Mon Feb 03 17:19:15 2014 -0500
@@ -119,13 +119,20 @@
         }
     }
 
-    public TargetType type = TargetType.UNKNOWN;
+    public static final List<TypePathEntry> emptyPath = List.nil();
+
+    // NOTE: All of these will be converted to final fields eventually.
+
+    public final TargetType type;
 
     // For generic/array types.
-    public List<TypePathEntry> location = List.nil();
+
+    // This field is in the process of being made final.  Do not
+    // introduce new mutations.
+    public List<TypePathEntry> location;
 
     // Tree position.
-    public int pos = -1;
+    public final int pos;
 
     // For type casts, type tests, new, locals (as start_pc),
     // and method and constructor reference type arguments.
@@ -138,13 +145,17 @@
     public int[] lvarIndex = null;
 
     // For type parameter bound
-    public int bound_index = Integer.MIN_VALUE;
+    public final int bound_index;
 
     // For type parameter and method parameter
-    public int parameter_index = Integer.MIN_VALUE;
+    public final int parameter_index;
 
     // For class extends, implements, and throws clauses
-    public int type_index = Integer.MIN_VALUE;
+
+    // This field is effectively final.  However, it needs to be
+    // modified by Gen for the time being.  Do not introduce new
+    // mutations.
+    public int type_index;
 
     // For exception parameters, index into exception table.
     // In com.sun.tools.javac.jvm.Gen.genCatch we first set the type_index
@@ -156,9 +167,10 @@
     // If this type annotation is within a lambda expression,
     // store a pointer to the lambda expression tree in order
     // to allow a later translation to the right method.
-    public JCLambda onLambda = null;
+    public final JCLambda onLambda;
 
-    public TypeAnnotationPosition() {}
+    // NOTE: This constructor will eventually go away, and be replaced
+    // by static builder methods.
 
     @Override
     public String toString() {
@@ -323,4 +335,847 @@
         }
         return loc.toList();
     }
+
+    // These methods are the new preferred way to create
+    // TypeAnnotationPositions
+
+    // Never make this a public constructor without creating a builder.
+    private TypeAnnotationPosition(final TargetType ttype,
+                                   final int pos,
+                                   final int parameter_index,
+                                   final JCLambda onLambda,
+                                   final int type_index,
+                                   final int bound_index,
+                                   final List<TypePathEntry> location) {
+        Assert.checkNonNull(location);
+        this.type = ttype;
+        this.pos = pos;
+        this.parameter_index = parameter_index;
+        this.onLambda = onLambda;
+        this.type_index = type_index;
+        this.bound_index = bound_index;
+        this.location = location;
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method return.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodReturn(final List<TypePathEntry> location,
+                     final JCLambda onLambda,
+                     final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_RETURN, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method return.
+     *
+     * @param location The type path.
+     */
+    public static TypeAnnotationPosition
+        methodReturn(final List<TypePathEntry> location) {
+        return methodReturn(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method return.
+     *
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition methodReturn(final int pos) {
+        return methodReturn(emptyPath, null, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method receiver.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodReceiver(final List<TypePathEntry> location,
+                     final JCLambda onLambda,
+                     final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_RECEIVER, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method receiver.
+     *
+     * @param location The type path.
+     */
+    public static TypeAnnotationPosition
+        methodReceiver(final List<TypePathEntry> location) {
+        return methodReceiver(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method receiver.
+     *
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition methodReceiver(final int pos) {
+        return methodReceiver(emptyPath, null, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method formal parameter.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this parameter.
+     * @param index The index of the parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodParameter(final List<TypePathEntry> location,
+                        final JCLambda onLambda,
+                        final int parameter_index,
+                        final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_FORMAL_PARAMETER,
+                                          pos, parameter_index, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method formal parameter.
+     *
+     * @param onLambda The lambda for this parameter.
+     * @param index The index of the parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodParameter(final JCLambda onLambda,
+                        final int parameter_index,
+                        final int pos) {
+        return methodParameter(emptyPath, onLambda,
+                               parameter_index, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method formal parameter.
+     *
+     * @param index The index of the parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodParameter(final int parameter_index,
+                        final int pos) {
+        return methodParameter(null, parameter_index, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method formal parameter.
+     *
+     * @param location The type path.
+     * @param index The index of the parameter.
+     */
+    public static TypeAnnotationPosition
+        methodParameter(final List<TypePathEntry> location,
+                        final int parameter_index) {
+        return methodParameter(location, null, parameter_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method reference.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this method reference.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodRef(final List<TypePathEntry> location,
+                  final JCLambda onLambda,
+                  final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_REFERENCE, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method reference.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this method reference.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodRef(final List<TypePathEntry> location) {
+        return methodRef(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a constructor reference.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this constructor reference.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        constructorRef(final List<TypePathEntry> location,
+                       final JCLambda onLambda,
+                       final int pos) {
+        return new TypeAnnotationPosition(TargetType.CONSTRUCTOR_REFERENCE, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a constructor reference.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this constructor reference.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        constructorRef(final List<TypePathEntry> location) {
+        return constructorRef(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a field.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        field(final List<TypePathEntry> location,
+              final JCLambda onLambda,
+              final int pos) {
+        return new TypeAnnotationPosition(TargetType.FIELD, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a field.
+     *
+     * @param location The type path.
+     */
+    public static TypeAnnotationPosition
+        field(final List<TypePathEntry> location) {
+        return field(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a field.
+     *
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition field(final int pos) {
+        return field(emptyPath, null, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a local variable.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        localVariable(final List<TypePathEntry> location,
+                      final JCLambda onLambda,
+                      final int pos) {
+        return new TypeAnnotationPosition(TargetType.LOCAL_VARIABLE, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a local variable.
+     *
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        localVariable(final JCLambda onLambda,
+                      final int pos) {
+        return localVariable(emptyPath, onLambda, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a local variable.
+     *
+     * @param location The type path.
+     */
+    public static TypeAnnotationPosition
+        localVariable(final List<TypePathEntry> location) {
+        return localVariable(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for an exception parameter.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        exceptionParameter(final List<TypePathEntry> location,
+                           final JCLambda onLambda,
+                           final int pos) {
+        return new TypeAnnotationPosition(TargetType.EXCEPTION_PARAMETER, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for an exception parameter.
+     *
+     * @param onLambda The lambda for this parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        exceptionParameter(final JCLambda onLambda,
+                           final int pos) {
+        return exceptionParameter(emptyPath, onLambda, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for an exception parameter.
+     *
+     * @param location The type path.
+     */
+    public static TypeAnnotationPosition
+        exceptionParameter(final List<TypePathEntry> location) {
+        return exceptionParameter(location, null, -1);
+    }
+
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a resource variable.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        resourceVariable(final List<TypePathEntry> location,
+                         final JCLambda onLambda,
+                         final int pos) {
+        return new TypeAnnotationPosition(TargetType.RESOURCE_VARIABLE, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a resource variable.
+     *
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        resourceVariable(final JCLambda onLambda,
+                         final int pos) {
+        return resourceVariable(emptyPath, onLambda, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a resource variable.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        resourceVariable(final List<TypePathEntry> location) {
+        return resourceVariable(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a new.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        newObj(final List<TypePathEntry> location,
+               final JCLambda onLambda,
+               final int pos) {
+        return new TypeAnnotationPosition(TargetType.NEW, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a new.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition newObj(final int pos) {
+        return newObj(emptyPath, null, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a new.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        newObj(final List<TypePathEntry> location) {
+        return newObj(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a class extension.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index of the interface.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        classExtends(final List<TypePathEntry> location,
+                     final JCLambda onLambda,
+                     final int type_index,
+                     final int pos) {
+        return new TypeAnnotationPosition(TargetType.CLASS_EXTENDS, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a class extension.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index of the interface.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        classExtends(final List<TypePathEntry> location,
+                     final JCLambda onLambda,
+                     final int pos) {
+        return classExtends(location, onLambda, -1, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a class extension.
+     *
+     * @param location The type path.
+     * @param type_index The index of the interface.
+     */
+    public static TypeAnnotationPosition
+        classExtends(final List<TypePathEntry> location,
+                     final int type_index) {
+        return classExtends(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a class extension.
+     *
+     * @param type_index The index of the interface.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition classExtends(final int type_index,
+                                                      final int pos) {
+        return classExtends(emptyPath, null, type_index, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a class extension.
+     *
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition classExtends(final int pos) {
+        return classExtends(-1, pos);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for an instanceof.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        instanceOf(final List<TypePathEntry> location,
+                   final JCLambda onLambda,
+                   final int pos) {
+        return new TypeAnnotationPosition(TargetType.INSTANCEOF, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+    /**
+     * Create a {@code TypeAnnotationPosition} for an instanceof.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        instanceOf(final List<TypePathEntry> location) {
+        return instanceOf(location, null, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a type cast.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index into an intersection type.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        typeCast(final List<TypePathEntry> location,
+                 final JCLambda onLambda,
+                 final int type_index,
+                 final int pos) {
+        return new TypeAnnotationPosition(TargetType.CAST, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a type cast.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index into an intersection type.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        typeCast(final List<TypePathEntry> location,
+                 final int type_index) {
+        return typeCast(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method
+     * invocation type argument.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index of the type argument.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodInvocationTypeArg(final List<TypePathEntry> location,
+                                final JCLambda onLambda,
+                                final int type_index,
+                                final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_INVOCATION_TYPE_ARGUMENT,
+                                          pos, Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method
+     * invocation type argument.
+     *
+     * @param location The type path.
+     * @param type_index The index of the type argument.
+     */
+    public static TypeAnnotationPosition
+        methodInvocationTypeArg(final List<TypePathEntry> location,
+                                final int type_index) {
+        return methodInvocationTypeArg(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a constructor
+     * invocation type argument.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index of the type argument.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        constructorInvocationTypeArg(final List<TypePathEntry> location,
+                                     final JCLambda onLambda,
+                                     final int type_index,
+                                     final int pos) {
+        return new TypeAnnotationPosition(TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT,
+                                          pos, Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a constructor
+     * invocation type argument.
+     *
+     * @param location The type path.
+     * @param type_index The index of the type argument.
+     */
+    public static TypeAnnotationPosition
+        constructorInvocationTypeArg(final List<TypePathEntry> location,
+                                     final int type_index) {
+        return constructorInvocationTypeArg(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a type parameter.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        typeParameter(final List<TypePathEntry> location,
+                      final JCLambda onLambda,
+                      final int parameter_index,
+                      final int pos) {
+        return new TypeAnnotationPosition(TargetType.CLASS_TYPE_PARAMETER, pos,
+                                          parameter_index, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a type parameter.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        typeParameter(final List<TypePathEntry> location,
+                      final int parameter_index) {
+        return typeParameter(location, null, parameter_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method type parameter.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type parameter.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodTypeParameter(final List<TypePathEntry> location,
+                            final JCLambda onLambda,
+                            final int parameter_index,
+                            final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_TYPE_PARAMETER,
+                                          pos, parameter_index, onLambda,
+                                          Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method type parameter.
+     *
+     * @param location The type path.
+     * @param parameter_index The index of the type parameter.
+     */
+    public static TypeAnnotationPosition
+        methodTypeParameter(final List<TypePathEntry> location,
+                            final int parameter_index) {
+        return methodTypeParameter(location, null, parameter_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a throws clause.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param type_index The index of the exception.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodThrows(final List<TypePathEntry> location,
+                     final JCLambda onLambda,
+                     final int type_index,
+                     final int pos) {
+        return new TypeAnnotationPosition(TargetType.THROWS, pos,
+                                          Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a throws clause.
+     *
+     * @param location The type path.
+     * @param type_index The index of the exception.
+     */
+    public static TypeAnnotationPosition
+        methodThrows(final List<TypePathEntry> location,
+                     final int type_index) {
+        return methodThrows(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method reference
+     * type argument.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type argument.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodRefTypeArg(final List<TypePathEntry> location,
+                         final JCLambda onLambda,
+                         final int type_index,
+                         final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_REFERENCE_TYPE_ARGUMENT,
+                                          pos, Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method reference
+     * type argument.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type argument.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodRefTypeArg(final List<TypePathEntry> location,
+                         final int type_index) {
+        return methodRefTypeArg(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a constructor reference
+     * type argument.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type argument.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        constructorRefTypeArg(final List<TypePathEntry> location,
+                              final JCLambda onLambda,
+                              final int type_index,
+                              final int pos) {
+        return new TypeAnnotationPosition(TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT,
+                                          pos, Integer.MIN_VALUE, onLambda,
+                                          type_index, Integer.MIN_VALUE,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a constructor reference
+     * type argument.
+     *
+     * @param location The type path.
+     * @param parameter_index The index of the type argument.
+     */
+    public static TypeAnnotationPosition
+        constructorRefTypeArg(final List<TypePathEntry> location,
+                              final int type_index) {
+        return constructorRefTypeArg(location, null, type_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a type parameter bound.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type parameter.
+     * @param bound_index The index of the type parameter bound.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        typeParameterBound(final List<TypePathEntry> location,
+                           final JCLambda onLambda,
+                           final int parameter_index,
+                           final int bound_index,
+                           final int pos) {
+        return new TypeAnnotationPosition(TargetType.CLASS_TYPE_PARAMETER_BOUND,
+                                          pos, parameter_index, onLambda,
+                                          Integer.MIN_VALUE, bound_index,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a type parameter bound.
+     *
+     * @param location The type path.
+     * @param parameter_index The index of the type parameter.
+     * @param bound_index The index of the type parameter bound.
+     */
+    public static TypeAnnotationPosition
+        typeParameterBound(final List<TypePathEntry> location,
+                           final int parameter_index,
+                           final int bound_index) {
+        return typeParameterBound(location, null, parameter_index,
+                                  bound_index, -1);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method type
+     * parameter bound.
+     *
+     * @param location The type path.
+     * @param onLambda The lambda for this variable.
+     * @param parameter_index The index of the type parameter.
+     * @param bound_index The index of the type parameter bound.
+     * @param pos The position from the associated tree node.
+     */
+    public static TypeAnnotationPosition
+        methodTypeParameterBound(final List<TypePathEntry> location,
+                                 final JCLambda onLambda,
+                                 final int parameter_index,
+                                 final int bound_index,
+                                 final int pos) {
+        return new TypeAnnotationPosition(TargetType.METHOD_TYPE_PARAMETER_BOUND,
+                                          pos, parameter_index, onLambda,
+                                          Integer.MIN_VALUE, bound_index,
+                                          location);
+    }
+
+    /**
+     * Create a {@code TypeAnnotationPosition} for a method type
+     * parameter bound.
+     *
+     * @param location The type path.
+     * @param parameter_index The index of the type parameter.
+     * @param bound_index The index of the type parameter bound.
+     */
+    public static TypeAnnotationPosition
+        methodTypeParameterBound(final List<TypePathEntry> location,
+                                 final int parameter_index,
+                                 final int bound_index) {
+        return methodTypeParameterBound(location, null, parameter_index,
+                                        bound_index, -1);
+    }
+
+    // Consider this deprecated on arrival.  We eventually want to get
+    // rid of this value altogether.  Do not use it for anything new.
+    public static final TypeAnnotationPosition unknown =
+        new TypeAnnotationPosition(TargetType.UNKNOWN, -1,
+                                   Integer.MIN_VALUE, null,
+                                   Integer.MIN_VALUE, Integer.MIN_VALUE,
+                                   emptyPath);
 }
--- a/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Sun Feb 02 12:12:01 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/code/TypeAnnotations.java	Mon Feb 03 17:19:15 2014 -0500
@@ -663,8 +663,15 @@
          * type annotations: determine the type annotation positions.
          */
 
-        private void resolveFrame(JCTree tree, JCTree frame,
-                List<JCTree> path, TypeAnnotationPosition p) {
+        // This method is considered deprecated, and will be removed
+        // in the near future.  Don't use it for anything new.
+        private TypeAnnotationPosition
+            resolveFrame(JCTree tree,
+                         JCTree frame,
+                         List<JCTree> path,
+                         JCLambda currentLambda,
+                         int outer_type_index,
+                         ListBuffer<TypePathEntry> location) {
             /*
             System.out.println("Resolving tree: " + tree + " kind: " + tree.getKind());
             System.out.println("    Framing tree: " + frame + " kind: " + frame.getKind());
@@ -675,87 +682,101 @@
 
             switch (frame.getKind()) {
                 case TYPE_CAST:
-                    JCTypeCast frameTC = (JCTypeCast) frame;
-                    p.type = TargetType.CAST;
-                    if (frameTC.clazz.hasTag(Tag.TYPEINTERSECTION)) {
-                        // This case was already handled by INTERSECTION_TYPE
-                    } else {
-                        p.type_index = 0;
-                    }
-                    p.pos = frame.pos;
-                    return;
+                    return TypeAnnotationPosition.typeCast(location.toList(),
+                                                           currentLambda,
+                                                           outer_type_index,
+                                                           frame.pos);
 
                 case INSTANCE_OF:
-                    p.type = TargetType.INSTANCEOF;
-                    p.pos = frame.pos;
-                    return;
+                    return TypeAnnotationPosition.instanceOf(location.toList(),
+                                                             currentLambda,
+                                                             frame.pos);
 
                 case NEW_CLASS:
-                    JCNewClass frameNewClass = (JCNewClass) frame;
+                    final JCNewClass frameNewClass = (JCNewClass) frame;
                     if (frameNewClass.def != null) {
                         // Special handling for anonymous class instantiations
-                        JCClassDecl frameClassDecl = frameNewClass.def;
+                        final JCClassDecl frameClassDecl = frameNewClass.def;
                         if (frameClassDecl.extending == tree) {
-                            p.type = TargetType.CLASS_EXTENDS;
-                            p.type_index = -1;
+                            return TypeAnnotationPosition
+                                .classExtends(location.toList(), currentLambda,
+                                              frame.pos);
                         } else if (frameClassDecl.implementing.contains(tree)) {
-                            p.type = TargetType.CLASS_EXTENDS;
-                            p.type_index = frameClassDecl.implementing.indexOf(tree);
+                            final int type_index =
+                                frameClassDecl.implementing.indexOf(tree);
+                            return TypeAnnotationPosition
+                                .classExtends(location.toList(), currentLambda,
+                                              type_index, frame.pos);
                         } else {
                             // In contrast to CLASS below, typarams cannot occur here.
-                            Assert.error("Could not determine position of tree " + tree +
-                                    " within frame " + frame);
+                            throw new AssertionError("Could not determine position of tree " + tree +
+                                                     " within frame " + frame);
                         }
                     } else if (frameNewClass.typeargs.contains(tree)) {
-                        p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
-                        p.type_index = frameNewClass.typeargs.indexOf(tree);
+                        final int type_index =
+                            frameNewClass.typeargs.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .constructorInvocationTypeArg(location.toList(),
+                                                          currentLambda,
+                                                          type_index,
+                                                          frame.pos);
                     } else {
-                        p.type = TargetType.NEW;
+                        return TypeAnnotationPosition
+                            .newObj(location.toList(), currentLambda,
+                                    frame.pos);
                     }
-                    p.pos = frame.pos;
-                    return;
 
                 case NEW_ARRAY:
-                    p.type = TargetType.NEW;
-                    p.pos = frame.pos;
-                    return;
+                    return TypeAnnotationPosition
+                        .newObj(location.toList(), currentLambda, frame.pos);
 
                 case ANNOTATION_TYPE:
                 case CLASS:
                 case ENUM:
                 case INTERFACE:
-                    p.pos = frame.pos;
                     if (((JCClassDecl)frame).extending == tree) {
-                        p.type = TargetType.CLASS_EXTENDS;
-                        p.type_index = -1;
+                        return TypeAnnotationPosition
+                            .classExtends(location.toList(), currentLambda,
+                                          frame.pos);
                     } else if (((JCClassDecl)frame).implementing.contains(tree)) {
-                        p.type = TargetType.CLASS_EXTENDS;
-                        p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
+                        final int type_index =
+                            ((JCClassDecl)frame).implementing.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .classExtends(location.toList(), currentLambda,
+                                          type_index, frame.pos);
                     } else if (((JCClassDecl)frame).typarams.contains(tree)) {
-                        p.type = TargetType.CLASS_TYPE_PARAMETER;
-                        p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
+                        final int parameter_index =
+                            ((JCClassDecl)frame).typarams.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .typeParameter(location.toList(), currentLambda,
+                                           parameter_index, frame.pos);
                     } else {
-                        Assert.error("Could not determine position of tree " + tree +
-                                " within frame " + frame);
+                        throw new AssertionError("Could not determine position of tree " +
+                                                 tree + " within frame " + frame);
                     }
-                    return;
 
                 case METHOD: {
-                    JCMethodDecl frameMethod = (JCMethodDecl) frame;
-                    p.pos = frame.pos;
+                    final JCMethodDecl frameMethod = (JCMethodDecl) frame;
                     if (frameMethod.thrown.contains(tree)) {
-                        p.type = TargetType.THROWS;
-                        p.type_index = frameMethod.thrown.indexOf(tree);
+                        final int type_index = frameMethod.thrown.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .methodThrows(location.toList(), currentLambda,
+                                          type_index, frame.pos);
                     } else if (frameMethod.restype == tree) {
-                        p.type = TargetType.METHOD_RETURN;
+                        return TypeAnnotationPosition
+                            .methodReturn(location.toList(), currentLambda,
+                                          frame.pos);
                     } else if (frameMethod.typarams.contains(tree)) {
-                        p.type = TargetType.METHOD_TYPE_PARAMETER;
-                        p.parameter_index = frameMethod.typarams.indexOf(tree);
+                        final int parameter_index =
+                            frameMethod.typarams.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .methodTypeParameter(location.toList(),
+                                                 currentLambda,
+                                                 parameter_index, frame.pos);
                     } else {
-                        Assert.error("Could not determine position of tree " + tree +
-                                " within frame " + frame);
+                        throw new AssertionError("Could not determine position of tree " + tree +
+                                                 " within frame " + frame);
                     }
-                    return;
                 }
 
                 case PARAMETERIZED_TYPE: {
@@ -766,25 +787,30 @@
                     } else if (((JCTypeApply)frame).arguments.contains(tree)) {
                         JCTypeApply taframe = (JCTypeApply) frame;
                         int arg = taframe.arguments.indexOf(tree);
-                        p.location = p.location.prepend(new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT, arg));
+                        location = location.prepend(
+                            new TypePathEntry(TypePathEntryKind.TYPE_ARGUMENT,
+                                              arg));
 
                         Type typeToUse;
-                        if (newPath.tail != null && newPath.tail.head.hasTag(Tag.NEWCLASS)) {
-                            // If we are within an anonymous class instantiation, use its type,
-                            // because it contains a correctly nested type.
+                        if (newPath.tail != null &&
+                            newPath.tail.head.hasTag(Tag.NEWCLASS)) {
+                            // If we are within an anonymous class
+                            // instantiation, use its type, because it
+                            // contains a correctly nested type.
                             typeToUse = newPath.tail.head.type;
                         } else {
                             typeToUse = taframe.type;
                         }
 
-                        locateNestedTypes(typeToUse, p);
+                        location = locateNestedTypes(typeToUse, location);
                     } else {
-                        Assert.error("Could not determine type argument position of tree " + tree +
-                                " within frame " + frame);
+                        throw new AssertionError("Could not determine type argument position of tree " + tree +
+                                                 " within frame " + frame);
                     }
 
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index, location);
                 }
 
                 case MEMBER_REFERENCE: {
@@ -793,117 +819,140 @@
                     if (mrframe.expr == tree) {
                         switch (mrframe.mode) {
                         case INVOKE:
-                            p.type = TargetType.METHOD_REFERENCE;
-                            break;
+                            return TypeAnnotationPosition
+                                .methodRef(location.toList(), currentLambda,
+                                           frame.pos);
                         case NEW:
-                            p.type = TargetType.CONSTRUCTOR_REFERENCE;
-                            break;
+                            return TypeAnnotationPosition
+                                .constructorRef(location.toList(),
+                                                currentLambda,
+                                                frame.pos);
                         default:
-                            Assert.error("Unknown method reference mode " + mrframe.mode +
-                                    " for tree " + tree + " within frame " + frame);
+                            throw new AssertionError("Unknown method reference mode " + mrframe.mode +
+                                                     " for tree " + tree + " within frame " + frame);
                         }
-                        p.pos = frame.pos;
                     } else if (mrframe.typeargs != null &&
                             mrframe.typeargs.contains(tree)) {
-                        int arg = mrframe.typeargs.indexOf(tree);
-                        p.type_index = arg;
+                        final int type_index = mrframe.typeargs.indexOf(tree);
                         switch (mrframe.mode) {
                         case INVOKE:
-                            p.type = TargetType.METHOD_REFERENCE_TYPE_ARGUMENT;
-                            break;
+                            return TypeAnnotationPosition
+                                .methodRefTypeArg(location.toList(),
+                                                  currentLambda,
+                                                  type_index, frame.pos);
                         case NEW:
-                            p.type = TargetType.CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT;
-                            break;
+                            return TypeAnnotationPosition
+                                .constructorRefTypeArg(location.toList(),
+                                                       currentLambda,
+                                                       type_index, frame.pos);
                         default:
-                            Assert.error("Unknown method reference mode " + mrframe.mode +
-                                    " for tree " + tree + " within frame " + frame);
+                            throw new AssertionError("Unknown method reference mode " + mrframe.mode +
+                                                   " for tree " + tree + " within frame " + frame);
                         }
-                        p.pos = frame.pos;
                     } else {
-                        Assert.error("Could not determine type argument position of tree " + tree +
-                                " within frame " + frame);
+                        throw new AssertionError("Could not determine type argument position of tree " + tree +
+                                               " within frame " + frame);
                     }
-                    return;
                 }
 
                 case ARRAY_TYPE: {
-                    ListBuffer<TypePathEntry> index = new ListBuffer<>();
-                    index = index.append(TypePathEntry.ARRAY);
+                    location = location.prepend(TypePathEntry.ARRAY);
                     List<JCTree> newPath = path.tail;
                     while (true) {
                         JCTree npHead = newPath.tail.head;
                         if (npHead.hasTag(JCTree.Tag.TYPEARRAY)) {
                             newPath = newPath.tail;
-                            index = index.append(TypePathEntry.ARRAY);
+                            location = location.prepend(TypePathEntry.ARRAY);
                         } else if (npHead.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
                             newPath = newPath.tail;
                         } else {
                             break;
                         }
                     }
-                    p.location = p.location.prependList(index.toList());
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index, location);
                 }
 
                 case TYPE_PARAMETER:
                     if (path.tail.tail.head.hasTag(JCTree.Tag.CLASSDEF)) {
-                        JCClassDecl clazz = (JCClassDecl)path.tail.tail.head;
-                        p.type = TargetType.CLASS_TYPE_PARAMETER_BOUND;
-                        p.parameter_index = clazz.typarams.indexOf(path.tail.head);
-                        p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
-                        if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
-                            // Account for an implicit Object as bound 0
-                            p.bound_index += 1;
-                        }
+                        final JCClassDecl clazz =
+                            (JCClassDecl)path.tail.tail.head;
+                        final int parameter_index =
+                            clazz.typarams.indexOf(path.tail.head);
+                        final int bound_index =
+                            ((JCTypeParameter)frame).bounds.get(0)
+                            .type.isInterface() ?
+                            ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
+                            ((JCTypeParameter)frame).bounds.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .typeParameterBound(location.toList(),
+                                                currentLambda,
+                                                parameter_index, bound_index,
+                                                frame.pos);
                     } else if (path.tail.tail.head.hasTag(JCTree.Tag.METHODDEF)) {
-                        JCMethodDecl method = (JCMethodDecl)path.tail.tail.head;
-                        p.type = TargetType.METHOD_TYPE_PARAMETER_BOUND;
-                        p.parameter_index = method.typarams.indexOf(path.tail.head);
-                        p.bound_index = ((JCTypeParameter)frame).bounds.indexOf(tree);
-                        if (((JCTypeParameter)frame).bounds.get(0).type.isInterface()) {
-                            // Account for an implicit Object as bound 0
-                            p.bound_index += 1;
-                        }
+                        final JCMethodDecl method =
+                            (JCMethodDecl)path.tail.tail.head;
+                        final int parameter_index =
+                            method.typarams.indexOf(path.tail.head);
+                        final int bound_index =
+                            ((JCTypeParameter)frame).bounds.get(0)
+                            .type.isInterface() ?
+                            ((JCTypeParameter)frame).bounds.indexOf(tree) + 1:
+                            ((JCTypeParameter)frame).bounds.indexOf(tree);
+                        return TypeAnnotationPosition
+                            .methodTypeParameterBound(location.toList(),
+                                                      currentLambda,
+                                                      parameter_index,
+                                                      bound_index,
+                                                      frame.pos);
                     } else {
-                        Assert.error("Could not determine position of tree " + tree +
-                                " within frame " + frame);
+                        throw new AssertionError("Could not determine position of tree " + tree +
+                                                 " within frame " + frame);
                     }
-                    p.pos = frame.pos;
-                    return;
 
                 case VARIABLE:
                     VarSymbol v = ((JCVariableDecl)frame).sym;
-                    p.pos = frame.pos;
-                    switch (v.getKind()) {
-                        case LOCAL_VARIABLE:
-                            p.type = TargetType.LOCAL_VARIABLE;
-                            break;
-                        case FIELD:
-                            p.type = TargetType.FIELD;
-                            break;
-                        case PARAMETER:
-                            if (v.getQualifiedName().equals(names._this)) {
-                                // TODO: Intro a separate ElementKind?
-                                p.type = TargetType.METHOD_RECEIVER;
-                            } else {
-                                p.type = TargetType.METHOD_FORMAL_PARAMETER;
-                                p.parameter_index = methodParamIndex(path, frame);
-                            }
-                            break;
-                        case EXCEPTION_PARAMETER:
-                            p.type = TargetType.EXCEPTION_PARAMETER;
-                            break;
-                        case RESOURCE_VARIABLE:
-                            p.type = TargetType.RESOURCE_VARIABLE;
-                            break;
-                        default:
-                            Assert.error("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
-                    }
                     if (v.getKind() != ElementKind.FIELD) {
                         v.owner.appendUniqueTypeAttributes(v.getRawTypeAttributes());
                     }
-                    return;
+                    switch (v.getKind()) {
+                        case LOCAL_VARIABLE:
+                            return TypeAnnotationPosition
+                                .localVariable(location.toList(), currentLambda,
+                                               frame.pos);
+                        case FIELD:
+                            return TypeAnnotationPosition.field(location.toList(),
+                                                                currentLambda,
+                                                                frame.pos);
+                        case PARAMETER:
+                            if (v.getQualifiedName().equals(names._this)) {
+                                return TypeAnnotationPosition
+                                    .methodReceiver(location.toList(),
+                                                    currentLambda,
+                                                    frame.pos);
+                            } else {
+                                final int parameter_index =
+                                    methodParamIndex(path, frame);
+                                return TypeAnnotationPosition
+                                    .methodParameter(location.toList(),
+                                                     currentLambda,
+                                                     parameter_index,
+                                                     frame.pos);
+                            }
+                        case EXCEPTION_PARAMETER:
+                            return TypeAnnotationPosition
+                                .exceptionParameter(location.toList(),
+                                                    currentLambda,
+                                                    frame.pos);
+                        case RESOURCE_VARIABLE:
+                            return TypeAnnotationPosition
+                                .resourceVariable(location.toList(),
+                                                  currentLambda,
+                                                  frame.pos);
+                        default:
+                            throw new AssertionError("Found unexpected type annotation for variable: " + v + " with kind: " + v.getKind());
+                    }
 
                 case ANNOTATED_TYPE: {
                     if (frame == tree) {
@@ -921,83 +970,89 @@
                             // class/method as enclosing elements.
                             // There is actually nothing to do for them.
                         } else {
-                            locateNestedTypes(utype, p);
+                            location = locateNestedTypes(utype, location);
                         }
                     }
                     List<JCTree> newPath = path.tail;
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index, location);
                 }
 
                 case UNION_TYPE: {
                     List<JCTree> newPath = path.tail;
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index, location);
                 }
 
                 case INTERSECTION_TYPE: {
                     JCTypeIntersection isect = (JCTypeIntersection)frame;
-                    p.type_index = isect.bounds.indexOf(tree);
-                    List<JCTree> newPath = path.tail;
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    final List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        isect.bounds.indexOf(tree), location);
                 }
 
                 case METHOD_INVOCATION: {
                     JCMethodInvocation invocation = (JCMethodInvocation)frame;
                     if (!invocation.typeargs.contains(tree)) {
-                        Assert.error("{" + tree + "} is not an argument in the invocation: " + invocation);
+                        throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation);
                     }
                     MethodSymbol exsym = (MethodSymbol) TreeInfo.symbol(invocation.getMethodSelect());
+                    final int type_index = invocation.typeargs.indexOf(tree);
                     if (exsym == null) {
-                        Assert.error("could not determine symbol for {" + invocation + "}");
+                        throw new AssertionError("could not determine symbol for {" + invocation + "}");
                     } else if (exsym.isConstructor()) {
-                        p.type = TargetType.CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT;
+                        return TypeAnnotationPosition
+                            .constructorInvocationTypeArg(location.toList(),
+                                                          currentLambda,
+                                                          type_index,
+                                                          invocation.pos);
                     } else {
-                        p.type = TargetType.METHOD_INVOCATION_TYPE_ARGUMENT;
+                        return TypeAnnotationPosition
+                            .methodInvocationTypeArg(location.toList(),
+                                                     currentLambda,
+                                                     type_index,
+                                                     invocation.pos);
                     }
-                    p.pos = invocation.pos;
-                    p.type_index = invocation.typeargs.indexOf(tree);
-                    return;
                 }
 
                 case EXTENDS_WILDCARD:
                 case SUPER_WILDCARD: {
                     // Annotations in wildcard bounds
-                    p.location = p.location.prepend(TypePathEntry.WILDCARD);
-                    List<JCTree> newPath = path.tail;
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    final List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index,
+                                        location.prepend(TypePathEntry.WILDCARD));
                 }
 
                 case MEMBER_SELECT: {
-                    List<JCTree> newPath = path.tail;
-                    resolveFrame(newPath.head, newPath.tail.head, newPath, p);
-                    return;
+                    final List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                                        newPath, currentLambda,
+                                        outer_type_index, location);
                 }
 
                 default:
-                    Assert.error("Unresolved frame: " + frame + " of kind: " + frame.getKind() +
-                            "\n    Looking for tree: " + tree);
-                    return;
+                    throw new AssertionError("Unresolved frame: " + frame +
+                                             " of kind: " + frame.getKind() +
+                                             "\n    Looking for tree: " + tree);
             }
         }
 
-        private void locateNestedTypes(Type type, TypeAnnotationPosition p) {
-            // The number of "steps" to get from the full type to the
-            // left-most outer type.
-            ListBuffer<TypePathEntry> depth = new ListBuffer<>();
-
+        private ListBuffer<TypePathEntry>
+            locateNestedTypes(Type type,
+                              ListBuffer<TypePathEntry> depth) {
             Type encl = type.getEnclosingType();
             while (encl != null &&
                     encl.getKind() != TypeKind.NONE &&
                     encl.getKind() != TypeKind.ERROR) {
-                depth = depth.append(TypePathEntry.INNER_TYPE);
+                depth = depth.prepend(TypePathEntry.INNER_TYPE);
                 encl = encl.getEnclosingType();
             }
-            if (depth.nonEmpty()) {
-                p.location = p.location.prependList(depth.toList());
-            }
+            return depth;
         }
 
         private int methodParamIndex(List<JCTree> path, JCTree param) {
@@ -1048,18 +1103,18 @@
             }
             if (sigOnly) {
                 if (!tree.mods.annotations.isEmpty()) {
-                    // Nothing to do for separateAnnotationsKinds if
-                    // there are no annotations of either kind.
-                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                    pos.type = TargetType.METHOD_RETURN;
                     if (tree.sym.isConstructor()) {
-                        pos.pos = tree.pos;
-                        // Use null to mark that the annotations go with the symbol.
+                        final TypeAnnotationPosition pos =
+                            TypeAnnotationPosition.methodReturn(tree.pos);
+                        // Use null to mark that the annotations go
+                        // with the symbol.
                         separateAnnotationsKinds(tree, null, tree.sym, pos);
                     } else {
-                        pos.pos = tree.restype.pos;
-                        separateAnnotationsKinds(tree.restype, tree.sym.type.getReturnType(),
-                                tree.sym, pos);
+                        final TypeAnnotationPosition pos =
+                            TypeAnnotationPosition.methodReturn(tree.restype.pos);
+                        separateAnnotationsKinds(tree.restype,
+                                                 tree.sym.type.getReturnType(),
+                                                 tree.sym, pos);
                     }
                 }
                 if (tree.recvparam != null && tree.recvparam.sym != null &&
@@ -1067,22 +1122,22 @@
                     // Nothing to do for separateAnnotationsKinds if
                     // there are no annotations of either kind.
                     // TODO: make sure there are no declaration annotations.
-                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                    pos.type = TargetType.METHOD_RECEIVER;
-                    pos.pos = tree.recvparam.vartype.pos;
-                    separateAnnotationsKinds(tree.recvparam.vartype, tree.recvparam.sym.type,
-                            tree.recvparam.sym, pos);
+                    final TypeAnnotationPosition pos =
+                        TypeAnnotationPosition.methodReceiver(tree.recvparam.vartype.pos);
+                    separateAnnotationsKinds(tree.recvparam.vartype,
+                                             tree.recvparam.sym.type,
+                                             tree.recvparam.sym, pos);
                 }
                 int i = 0;
                 for (JCVariableDecl param : tree.params) {
                     if (!param.mods.annotations.isEmpty()) {
                         // Nothing to do for separateAnnotationsKinds if
                         // there are no annotations of either kind.
-                        TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                        pos.type = TargetType.METHOD_FORMAL_PARAMETER;
-                        pos.parameter_index = i;
-                        pos.pos = param.vartype.pos;
-                        separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
+                        final TypeAnnotationPosition pos =
+                            TypeAnnotationPosition.methodParameter(i, param.vartype.pos);
+                        separateAnnotationsKinds(param.vartype,
+                                                 param.sym.type,
+                                                 param.sym, pos);
                     }
                     ++i;
                 }
@@ -1119,11 +1174,9 @@
                     if (!param.mods.annotations.isEmpty()) {
                         // Nothing to do for separateAnnotationsKinds if
                         // there are no annotations of either kind.
-                        TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                        pos.type = TargetType.METHOD_FORMAL_PARAMETER;
-                        pos.parameter_index = i;
-                        pos.pos = param.vartype.pos;
-                        pos.onLambda = tree;
+                        final TypeAnnotationPosition pos =
+                            TypeAnnotationPosition.methodParameter(tree, i,
+                                                                   param.vartype.pos);
                         separateAnnotationsKinds(param.vartype, param.sym.type, param.sym, pos);
                     }
                     ++i;
@@ -1153,28 +1206,24 @@
                 // Parameters are handled in visitMethodDef or visitLambda.
             } else if (tree.sym.getKind() == ElementKind.FIELD) {
                 if (sigOnly) {
-                    TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                    pos.type = TargetType.FIELD;
-                    pos.pos = tree.pos;
+                    TypeAnnotationPosition pos =
+                        TypeAnnotationPosition.field(tree.pos);
                     separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
                 }
             } else if (tree.sym.getKind() == ElementKind.LOCAL_VARIABLE) {
-                TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                pos.type = TargetType.LOCAL_VARIABLE;
-                pos.pos = tree.pos;
-                pos.onLambda = currentLambda;
+                final TypeAnnotationPosition pos =
+                    TypeAnnotationPosition.localVariable(currentLambda,
+                                                         tree.pos);
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.EXCEPTION_PARAMETER) {
-                TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                pos.type = TargetType.EXCEPTION_PARAMETER;
-                pos.pos = tree.pos;
-                pos.onLambda = currentLambda;
+                final TypeAnnotationPosition pos =
+                    TypeAnnotationPosition.exceptionParameter(currentLambda,
+                                                              tree.pos);
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.RESOURCE_VARIABLE) {
-                TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                pos.type = TargetType.RESOURCE_VARIABLE;
-                pos.pos = tree.pos;
-                pos.onLambda = currentLambda;
+                final TypeAnnotationPosition pos =
+                    TypeAnnotationPosition.resourceVariable(currentLambda,
+                                                            tree.pos);
                 separateAnnotationsKinds(tree.vartype, tree.sym.type, tree.sym, pos);
             } else if (tree.sym.getKind() == ElementKind.ENUM_CONSTANT) {
                 // No type annotations can occur here.
@@ -1218,7 +1267,8 @@
 
         private void copyNewClassAnnotationsToOwner(JCNewClass tree) {
             Symbol sym = tree.def.sym;
-            TypeAnnotationPosition pos = new TypeAnnotationPosition();
+            final TypeAnnotationPosition pos =
+                TypeAnnotationPosition.newObj(tree.pos);
             ListBuffer<Attribute.TypeCompound> newattrs = new ListBuffer<>();
 
             for (Attribute.TypeCompound old : sym.getRawTypeAttributes()) {
@@ -1226,8 +1276,6 @@
                                                            pos));
             }
 
-            pos.type = TargetType.NEW;
-            pos.pos = tree.pos;
             sym.owner.appendUniqueTypeAttributes(newattrs.toList());
         }
 
@@ -1236,16 +1284,16 @@
             if (tree.def != null &&
                     !tree.def.mods.annotations.isEmpty()) {
                 JCClassDecl classdecl = tree.def;
-                TypeAnnotationPosition pos = new TypeAnnotationPosition();
-                pos.type = TargetType.CLASS_EXTENDS;
-                pos.pos = tree.pos;
+                TypeAnnotationPosition pos;
+
                 if (classdecl.extending == tree.clazz) {
-                    pos.type_index = -1;
+                    pos = TypeAnnotationPosition.classExtends(tree.pos);
                 } else if (classdecl.implementing.contains(tree.clazz)) {
-                    pos.type_index = classdecl.implementing.indexOf(tree.clazz);
+                    final int index = classdecl.implementing.indexOf(tree.clazz);
+                    pos = TypeAnnotationPosition.classExtends(index, tree.pos);
                 } else {
                     // In contrast to CLASS elsewhere, typarams cannot occur here.
-                    Assert.error("Could not determine position of tree " + tree);
+                    throw new AssertionError("Could not determine position of tree " + tree);
                 }
                 Type before = classdecl.sym.type;
                 separateAnnotationsKinds(classdecl, tree.clazz.type, classdecl.sym, pos);
@@ -1273,14 +1321,16 @@
 
             // handle annotations associated with dimensions
             for (int i = 0; i < dimAnnosCount; ++i) {
-                TypeAnnotationPosition p = new TypeAnnotationPosition();
-                p.pos = tree.pos;
-                p.onLambda = currentLambda;
-                p.type = TargetType.NEW;
+                ListBuffer<TypePathEntry> location =
+                    new ListBuffer<TypePathEntry>();
                 if (i != 0) {
                     depth = depth.append(TypePathEntry.ARRAY);
-                    p.location = p.location.appendList(depth.toList());
+                    location = location.appendList(depth.toList());
                 }
+                final TypeAnnotationPosition p =
+                    TypeAnnotationPosition.newObj(location.toList(),
+                                                  currentLambda,
+                                                  tree.pos);
 
                 setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
             }
@@ -1293,12 +1343,14 @@
             while (elemType != null) {
                 if (elemType.hasTag(JCTree.Tag.ANNOTATED_TYPE)) {
                     JCAnnotatedType at = (JCAnnotatedType)elemType;
-                    TypeAnnotationPosition p = new TypeAnnotationPosition();
-                    p.type = TargetType.NEW;
-                    p.pos = tree.pos;
-                    p.onLambda = currentLambda;
-                    locateNestedTypes(elemType.type, p);
-                    p.location = p.location.prependList(depth.toList());
+                    final ListBuffer<TypePathEntry> locationbuf =
+                        locateNestedTypes(elemType.type,
+                                          new ListBuffer<TypePathEntry>());
+                    final List<TypePathEntry> location =
+                        locationbuf.toList().prependList(depth.toList());
+                    final TypeAnnotationPosition p =
+                        TypeAnnotationPosition.newObj(location, currentLambda,
+                                                      tree.pos);
                     setTypeAnnotationPos(at.annotations, p);
                     elemType = at.underlyingType;
                 } else if (elemType.hasTag(JCTree.Tag.TYPEARRAY)) {
@@ -1320,9 +1372,9 @@
                 System.err.println("    tree: " + tree + " kind: " + tree.getKind());
                 System.err.println("    frame: " + frame + " kind: " + frame.getKind());
                 */
-                TypeAnnotationPosition p = new TypeAnnotationPosition();
-                p.onLambda = currentLambda;
-                resolveFrame(tree, frame, frames.toList(), p);
+                final TypeAnnotationPosition p =
+                    resolveFrame(tree, frame, frames.toList(), currentLambda, 0,
+                                 new ListBuffer<TypePathEntry>());
                 setTypeAnnotationPos(annotations, p);
             }
         }
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Sun Feb 02 12:12:01 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Annotate.java	Mon Feb 03 17:19:15 2014 -0500
@@ -299,7 +299,13 @@
         if (typeAnnotation) {
             if (a.attribute == null || !(a.attribute instanceof Attribute.TypeCompound)) {
                 // Create a new TypeCompound
-                Attribute.TypeCompound tc = new Attribute.TypeCompound(a.type, buf.toList(), new TypeAnnotationPosition());
+
+                Attribute.TypeCompound tc =
+                    new Attribute.TypeCompound(a.type, buf.toList(),
+                // TODO: Eventually, we will get rid of this use of
+                // unknown, because we'll get a position from
+                // MemberEnter (task 8027262).
+                                               TypeAnnotationPosition.unknown);
                 a.attribute = tc;
                 return tc;
             } else {
--- a/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Sun Feb 02 12:12:01 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Mon Feb 03 17:19:15 2014 -0500
@@ -1469,26 +1469,63 @@
         if (!TargetType.isValidTargetTypeValue(tag))
             throw this.badClassFile("bad.type.annotation.value", String.format("0x%02X", tag));
 
-        TypeAnnotationPosition position = new TypeAnnotationPosition();
         TargetType type = TargetType.fromTargetTypeValue(tag);
 
-        position.type = type;
-
         switch (type) {
         // instanceof
-        case INSTANCEOF:
+        case INSTANCEOF: {
+            final int offset = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.instanceOf(readTypePath());
+            position.offset = offset;
+            return position;
+        }
         // new expression
-        case NEW:
+        case NEW: {
+            final int offset = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.newObj(readTypePath());
+            position.offset = offset;
+            return position;
+        }
         // constructor/method reference receiver
-        case CONSTRUCTOR_REFERENCE:
-        case METHOD_REFERENCE:
-            position.offset = nextChar();
-            break;
+        case CONSTRUCTOR_REFERENCE: {
+            final int offset = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.constructorRef(readTypePath());
+            position.offset = offset;
+            return position;
+        }
+        case METHOD_REFERENCE: {
+            final int offset = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.methodRef(readTypePath());
+            position.offset = offset;
+            return position;
+        }
         // local variable
-        case LOCAL_VARIABLE:
+        case LOCAL_VARIABLE: {
+            final int table_length = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.localVariable(readTypePath());
+
+            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();
+            }
+            return position;
+        }
         // resource variable
-        case RESOURCE_VARIABLE:
-            int table_length = nextChar();
+        case RESOURCE_VARIABLE: {
+            final int table_length = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.resourceVariable(readTypePath());
+
             position.lvarOffset = new int[table_length];
             position.lvarLength = new int[table_length];
             position.lvarIndex = new int[table_length];
@@ -1498,67 +1535,125 @@
                 position.lvarLength[i] = nextChar();
                 position.lvarIndex[i] = nextChar();
             }
-            break;
+            return position;
+        }
         // exception parameter
-        case EXCEPTION_PARAMETER:
-            position.exception_index = nextChar();
-            break;
+        case EXCEPTION_PARAMETER: {
+            final int exception_index = nextChar();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.exceptionParameter(readTypePath());
+            position.exception_index = exception_index;
+            return position;
+        }
         // method receiver
         case METHOD_RECEIVER:
-            // Do nothing
-            break;
+            return TypeAnnotationPosition.methodReceiver(readTypePath());
         // type parameter
-        case CLASS_TYPE_PARAMETER:
-        case METHOD_TYPE_PARAMETER:
-            position.parameter_index = nextByte();
-            break;
+        case CLASS_TYPE_PARAMETER: {
+            final int parameter_index = nextByte();
+            return TypeAnnotationPosition
+                .typeParameter(readTypePath(), parameter_index);
+        }
+        case METHOD_TYPE_PARAMETER: {
+            final int parameter_index = nextByte();
+            return TypeAnnotationPosition
+                .methodTypeParameter(readTypePath(), parameter_index);
+        }
         // type parameter bound
-        case CLASS_TYPE_PARAMETER_BOUND:
-        case METHOD_TYPE_PARAMETER_BOUND:
-            position.parameter_index = nextByte();
-            position.bound_index = nextByte();
-            break;
+        case CLASS_TYPE_PARAMETER_BOUND: {
+            final int parameter_index = nextByte();
+            final int bound_index = nextByte();
+            return TypeAnnotationPosition
+                .typeParameterBound(readTypePath(), parameter_index,
+                                    bound_index);
+        }
+        case METHOD_TYPE_PARAMETER_BOUND: {
+            final int parameter_index = nextByte();
+            final int bound_index = nextByte();
+            return TypeAnnotationPosition
+                .methodTypeParameterBound(readTypePath(), parameter_index,
+                                          bound_index);
+        }
         // class extends or implements clause
-        case CLASS_EXTENDS:
-            position.type_index = nextChar();
-            break;
+        case CLASS_EXTENDS: {
+            final int type_index = nextChar();
+            return TypeAnnotationPosition.classExtends(readTypePath(),
+                                                       type_index);
+        }
         // throws
-        case THROWS:
-            position.type_index = nextChar();
-            break;
+        case THROWS: {
+            final int type_index = nextChar();
+            return TypeAnnotationPosition.methodThrows(readTypePath(),
+                                                       type_index);
+        }
         // method parameter
-        case METHOD_FORMAL_PARAMETER:
-            position.parameter_index = nextByte();
-            break;
+        case METHOD_FORMAL_PARAMETER: {
+            final int parameter_index = nextByte();
+            return TypeAnnotationPosition.methodParameter(readTypePath(),
+                                                          parameter_index);
+        }
         // type cast
-        case CAST:
+        case CAST: {
+            final int offset = nextChar();
+            final int type_index = nextByte();
+            final TypeAnnotationPosition position =
+                TypeAnnotationPosition.typeCast(readTypePath(), type_index);
+            position.offset = offset;
+            return position;
+        }
         // method/constructor/reference type argument
-        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT:
-        case METHOD_INVOCATION_TYPE_ARGUMENT:
-        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT:
-        case METHOD_REFERENCE_TYPE_ARGUMENT:
-            position.offset = nextChar();
-            position.type_index = nextByte();
-            break;
+        case CONSTRUCTOR_INVOCATION_TYPE_ARGUMENT: {
+            final int offset = nextChar();
+            final int type_index = nextByte();
+            final TypeAnnotationPosition position = TypeAnnotationPosition
+                .constructorInvocationTypeArg(readTypePath(), type_index);
+            position.offset = offset;
+            return position;
+        }
+        case METHOD_INVOCATION_TYPE_ARGUMENT: {
+            final int offset = nextChar();
+            final int type_index = nextByte();
+            final TypeAnnotationPosition position = TypeAnnotationPosition
+                .methodInvocationTypeArg(readTypePath(), type_index);
+            position.offset = offset;
+            return position;
+        }
+        case CONSTRUCTOR_REFERENCE_TYPE_ARGUMENT: {
+            final int offset = nextChar();
+            final int type_index = nextByte();
+            final TypeAnnotationPosition position = TypeAnnotationPosition
+                .constructorRefTypeArg(readTypePath(), type_index);
+            position.offset = offset;
+            return position;
+        }
+        case METHOD_REFERENCE_TYPE_ARGUMENT: {
+            final int offset = nextChar();
+            final int type_index = nextByte();
+            final TypeAnnotationPosition position = TypeAnnotationPosition
+                .methodRefTypeArg(readTypePath(), type_index);
+            position.offset = offset;
+            return position;
+        }
         // We don't need to worry about these
         case METHOD_RETURN:
+            return TypeAnnotationPosition.methodReturn(readTypePath());
         case FIELD:
-            break;
+            return TypeAnnotationPosition.field(readTypePath());
         case UNKNOWN:
             throw new AssertionError("jvm.ClassReader: UNKNOWN target type should never occur!");
         default:
-            throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + position);
+            throw new AssertionError("jvm.ClassReader: Unknown target type for position: " + type);
         }
+    }
 
-        { // See whether there is location info and read it
-            int len = nextByte();
-            ListBuffer<Integer> loc = new ListBuffer<>();
-            for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i)
-                loc = loc.append(nextByte());
-            position.location = TypeAnnotationPosition.getTypePathFromBinary(loc.toList());
-        }
+    List<TypeAnnotationPosition.TypePathEntry> readTypePath() {
+        int len = nextByte();
+        ListBuffer<Integer> loc = new ListBuffer<>();
+        for (int i = 0; i < len * TypeAnnotationPosition.TypePathEntry.bytesPerEntry; ++i)
+            loc = loc.append(nextByte());
 
-        return position;
+        return TypeAnnotationPosition.getTypePathFromBinary(loc.toList());
+
     }
 
     Attribute readAttributeValue() {
--- a/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Sun Feb 02 12:12:01 2014 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Mon Feb 03 17:19:15 2014 -0500
@@ -2299,6 +2299,9 @@
 
         // Attribute.Compound if tag is ANNOTATION
         // Attribute.TypeCompound if tag is TYPE_ANNOTATION
+        //
+        // NOTE: This field is slated for removal in the future.  Do
+        // not use it for anything new.
         public Attribute.Compound attribute;
 
         protected JCAnnotation(Tag tag, JCTree annotationType, List<JCExpression> args) {