changeset 307:03944ee4fac4

6843077: JSR 308: Annotations on types Reviewed-by: jjg, mcimadamore, darcy Contributed-by: mernst@cs.washington.edu, mali@csail.mit.edu, mpapi@csail.mit.edu
author jjg
date Fri, 26 Jun 2009 18:51:39 -0700
parents ca063536e4a6
children 664edca41e34
files src/share/bin/launcher.sh-template src/share/classes/com/sun/source/tree/MethodTree.java src/share/classes/com/sun/source/tree/Tree.java src/share/classes/com/sun/source/tree/TreeVisitor.java src/share/classes/com/sun/source/tree/TypeParameterTree.java src/share/classes/com/sun/source/util/SimpleTreeVisitor.java src/share/classes/com/sun/source/util/TreePath.java src/share/classes/com/sun/source/util/TreeScanner.java src/share/classes/com/sun/source/util/Trees.java src/share/classes/com/sun/tools/classfile/Attribute.java src/share/classes/com/sun/tools/classfile/ClassWriter.java src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java src/share/classes/com/sun/tools/javac/api/JavacTrees.java src/share/classes/com/sun/tools/javac/code/Attribute.java src/share/classes/com/sun/tools/javac/code/Source.java src/share/classes/com/sun/tools/javac/code/Symbol.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Check.java src/share/classes/com/sun/tools/javac/comp/Flow.java src/share/classes/com/sun/tools/javac/comp/Lower.java src/share/classes/com/sun/tools/javac/comp/MemberEnter.java src/share/classes/com/sun/tools/javac/comp/TransTypes.java src/share/classes/com/sun/tools/javac/jvm/ClassReader.java src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java src/share/classes/com/sun/tools/javac/jvm/Code.java src/share/classes/com/sun/tools/javac/jvm/Gen.java src/share/classes/com/sun/tools/javac/parser/JavacParser.java src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java src/share/classes/com/sun/tools/javac/resources/compiler.properties src/share/classes/com/sun/tools/javac/tree/JCTree.java src/share/classes/com/sun/tools/javac/tree/Pretty.java src/share/classes/com/sun/tools/javac/tree/TreeCopier.java src/share/classes/com/sun/tools/javac/tree/TreeInfo.java src/share/classes/com/sun/tools/javac/tree/TreeMaker.java src/share/classes/com/sun/tools/javac/tree/TreeScanner.java src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java src/share/classes/com/sun/tools/javac/util/Names.java src/share/classes/com/sun/tools/javap/AnnotationWriter.java src/share/classes/com/sun/tools/javap/AttributeWriter.java test/tools/javac/6341866/T6341866.java test/tools/javac/processing/6348499/T6348499.java test/tools/javac/processing/6414633/T6414633.java test/tools/javac/processing/6430209/T6430209.java test/tools/javac/processing/T6439826.java
diffstat 45 files changed, 1856 insertions(+), 98 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/bin/launcher.sh-template	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/bin/launcher.sh-template	Fri Jun 26 18:51:39 2009 -0700
@@ -1,7 +1,7 @@
 #!/bin/sh
 
 #
-# Copyright 2006-2007 Sun Microsystems, Inc.  All Rights Reserved.
+# Copyright 2006-2009 Sun Microsystems, Inc.  All Rights Reserved.
 # DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 #
 # This code is free software; you can redistribute it and/or modify it
@@ -44,7 +44,27 @@
    bcp="$mylib/#PROGRAM#.jar":$cp 
 fi
 
-# javac currently assumes that assertions are enabled in the launcher
+# tools currently assumes that assertions are enabled in the launcher
 ea=-ea:com.sun.tools
 
-"#TARGET_JAVA#" ${bcp:+-Xbootclasspath/p:"$bcp"} ${ea} -jar "${mydir}"/../lib/#PROGRAM#.jar "$@"
+# Any parameters starting with -J are passed to the JVM.
+# All other parameters become parameters of #PROGRAM#.
+
+# Separate out -J* options for the JVM
+# Note jdk as possible default to run jtreg
+# Unset IFS and use newline as arg separator to preserve spaces in args
+DUALCASE=1  # for MKS: make case statement case-sensitive (6709498)
+saveIFS="$IFS"
+nl='
+'
+for i in "$@" ; do
+   IFS=
+   case $i in
+   -J* )       javaOpts=$javaOpts$nl`echo $i | sed -e 's/^-J//'` ;;
+   *   )       toolOpts=$toolOpts$nl$i ;;
+   esac
+   IFS="$saveIFS"
+done
+unset DUALCASE
+
+eval "#TARGET_JAVA#" "${bcp:+-Xbootclasspath/p:"$bcp"}" ${ea} ${javaOpts} -jar "${mydir}"/../lib/#PROGRAM#.jar ${toolOpts}
--- a/src/share/classes/com/sun/source/tree/MethodTree.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/tree/MethodTree.java	Fri Jun 26 18:51:39 2009 -0700
@@ -53,6 +53,7 @@
     Tree getReturnType();
     List<? extends TypeParameterTree> getTypeParameters();
     List<? extends VariableTree> getParameters();
+    List<? extends AnnotationTree> getReceiverAnnotations();
     List<? extends ExpressionTree> getThrows();
     BlockTree getBody();
     Tree getDefaultValue(); // for annotation types
--- a/src/share/classes/com/sun/source/tree/Tree.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/tree/Tree.java	Fri Jun 26 18:51:39 2009 -0700
@@ -45,6 +45,9 @@
      * Enumerates all kinds of trees.
      */
     public enum Kind {
+
+        ANNOTATED_TYPE(AnnotatedTypeTree.class),
+
         /**
          * Used for instances of {@link AnnotationTree}.
          */
--- a/src/share/classes/com/sun/source/tree/TreeVisitor.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/tree/TreeVisitor.java	Fri Jun 26 18:51:39 2009 -0700
@@ -57,6 +57,7 @@
  * @since 1.6
  */
 public interface TreeVisitor<R,P> {
+    R visitAnnotatedType(AnnotatedTypeTree node, P p);
     R visitAnnotation(AnnotationTree node, P p);
     R visitMethodInvocation(MethodInvocationTree node, P p);
     R visitAssert(AssertTree node, P p);
--- a/src/share/classes/com/sun/source/tree/TypeParameterTree.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/tree/TypeParameterTree.java	Fri Jun 26 18:51:39 2009 -0700
@@ -47,4 +47,5 @@
 public interface TypeParameterTree extends Tree {
     Name getName();
     List<? extends Tree> getBounds();
+    List<? extends AnnotationTree> getAnnotations();
 }
--- a/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/util/SimpleTreeVisitor.java	Fri Jun 26 18:51:39 2009 -0700
@@ -244,6 +244,10 @@
         return defaultAction(node, p);
     }
 
+    public R visitAnnotatedType(AnnotatedTypeTree node, P p) {
+        return defaultAction(node, p);
+    }
+
     public R visitErroneous(ErroneousTree node, P p) {
         return defaultAction(node, p);
     }
--- a/src/share/classes/com/sun/source/util/TreePath.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/util/TreePath.java	Fri Jun 26 18:51:39 2009 -0700
@@ -120,19 +120,20 @@
     public Iterator<Tree> iterator() {
         return new Iterator<Tree>() {
             public boolean hasNext() {
-                return curr.parent != null;
+                return next != null;
             }
 
             public Tree next() {
-                curr = curr.parent;
-                return curr.leaf;
+                Tree t = next.leaf;
+                next = next.parent;
+                return t;
             }
 
             public void remove() {
                 throw new UnsupportedOperationException();
             }
 
-            private TreePath curr;
+            private TreePath next = TreePath.this;
         };
     }
 
--- a/src/share/classes/com/sun/source/util/TreeScanner.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/util/TreeScanner.java	Fri Jun 26 18:51:39 2009 -0700
@@ -138,6 +138,7 @@
         r = scanAndReduce(node.getReturnType(), p, r);
         r = scanAndReduce(node.getTypeParameters(), p, r);
         r = scanAndReduce(node.getParameters(), p, r);
+        r = scanAndReduce(node.getReceiverAnnotations(), p, r);
         r = scanAndReduce(node.getThrows(), p, r);
         r = scanAndReduce(node.getBody(), p, r);
         return r;
@@ -354,7 +355,9 @@
     }
 
     public R visitTypeParameter(TypeParameterTree node, P p) {
-        return scan(node.getBounds(), p);
+        R r = scan(node.getAnnotations(), p);
+        r = scanAndReduce(node.getBounds(), p, r);
+        return r;
     }
 
     public R visitWildcard(WildcardTree node, P p) {
@@ -371,6 +374,12 @@
         return r;
     }
 
+   public R visitAnnotatedType(AnnotatedTypeTree node, P p) {
+       R r = scan(node.getAnnotations(), p);
+       r = scanAndReduce(node.getUnderlyingType(), p, r);
+       return r;
+   }
+
     public R visitOther(Tree node, P p) {
         return null;
     }
--- a/src/share/classes/com/sun/source/util/Trees.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/source/util/Trees.java	Fri Jun 26 18:51:39 2009 -0700
@@ -35,6 +35,7 @@
 import javax.lang.model.type.DeclaredType;
 import javax.lang.model.type.ErrorType;
 import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic;
 import javax.tools.JavaCompiler.CompilationTask;
 
 import com.sun.source.tree.ClassTree;
@@ -182,7 +183,20 @@
     /**
       * Gets the original type from the ErrorType object.
       * @param errorType The errorType for which we want to get the original type.
-      * @returns javax.lang.model.type.TypeMirror corresponding to the original type, replaced by the ErrorType.
+      * @return javax.lang.model.type.TypeMirror corresponding to the original type, replaced by the ErrorType.
       */
     public abstract TypeMirror getOriginalType(ErrorType errorType);
+
+    /**
+     * Prints a message of the specified kind at the location of the
+     * tree within the provided compilation unit
+     *
+     * @param kind the kind of message
+     * @param msg  the message, or an empty string if none
+     * @param t    the tree to use as a position hint
+     * @param root the compilation unit that contains tree
+     */
+    public abstract void printMessage(Diagnostic.Kind kind, CharSequence msg,
+            com.sun.source.tree.Tree t,
+            com.sun.source.tree.CompilationUnitTree root);
 }
--- a/src/share/classes/com/sun/tools/classfile/Attribute.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/Attribute.java	Fri Jun 26 18:51:39 2009 -0700
@@ -54,6 +54,8 @@
     public static final String RuntimeInvisibleAnnotations = "RuntimeInvisibleAnnotations";
     public static final String RuntimeVisibleParameterAnnotations = "RuntimeVisibleParameterAnnotations";
     public static final String RuntimeInvisibleParameterAnnotations = "RuntimeInvisibleParameterAnnotations";
+    public static final String RuntimeVisibleTypeAnnotations = "RuntimeVisibleTypeAnnotations";
+    public static final String RuntimeInvisibleTypeAnnotations = "RuntimeInvisibleTypeAnnotations";
     public static final String Signature                = "Signature";
     public static final String SourceDebugExtension     = "SourceDebugExtension";
     public static final String SourceFile               = "SourceFile";
@@ -131,6 +133,8 @@
                 standardAttributes.put(RuntimeInvisibleParameterAnnotations, RuntimeInvisibleParameterAnnotations_attribute.class);
                 standardAttributes.put(RuntimeVisibleAnnotations, RuntimeVisibleAnnotations_attribute.class);
                 standardAttributes.put(RuntimeVisibleParameterAnnotations, RuntimeVisibleParameterAnnotations_attribute.class);
+                standardAttributes.put(RuntimeVisibleTypeAnnotations, RuntimeVisibleTypeAnnotations_attribute.class);
+                standardAttributes.put(RuntimeInvisibleTypeAnnotations, RuntimeInvisibleTypeAnnotations_attribute.class);
                 standardAttributes.put(Signature,     Signature_attribute.class);
                 standardAttributes.put(SourceID, SourceID_attribute.class);
             }
@@ -184,6 +188,8 @@
         R visitRuntimeInvisibleAnnotations(RuntimeInvisibleAnnotations_attribute attr, P p);
         R visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, P p);
         R visitRuntimeInvisibleParameterAnnotations(RuntimeInvisibleParameterAnnotations_attribute attr, P p);
+        R visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, P p);
+        R visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, P p);
         R visitSignature(Signature_attribute attr, P p);
         R visitSourceDebugExtension(SourceDebugExtension_attribute attr, P p);
         R visitSourceFile(SourceFile_attribute attr, P p);
--- a/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/classfile/ClassWriter.java	Fri Jun 26 18:51:39 2009 -0700
@@ -1,3 +1,4 @@
+
 /*
  * Copyright 2008 Sun Microsystems, Inc.  All Rights Reserved.
  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
@@ -477,6 +478,16 @@
             return null;
         }
 
+        public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
+            annotationWriter.write(attr.annotations, out);
+            return null;
+        }
+
+        public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, ClassOutputStream out) {
+            annotationWriter.write(attr.annotations, out);
+            return null;
+        }
+
         public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, ClassOutputStream out) {
             out.writeByte(attr.parameter_annotations.length);
             for (Annotation[] annos: attr.parameter_annotations)
@@ -636,6 +647,12 @@
                 write(anno, out);
         }
 
+        public void write(ExtendedAnnotation[] annos, ClassOutputStream out) {
+            out.writeShort(annos.length);
+            for (ExtendedAnnotation anno: annos)
+                write(anno, out);
+        }
+
         public void write(Annotation anno, ClassOutputStream out) {
             out.writeShort(anno.type_index);
             out.writeShort(anno.element_value_pairs.length);
@@ -643,6 +660,11 @@
                 write(p, out);
         }
 
+        public void write(ExtendedAnnotation anno, ClassOutputStream out) {
+            write(anno.annotation, out);
+            write(anno.position, out);
+        }
+
         public void write(element_value_pair pair, ClassOutputStream out) {
             out.writeShort(pair.element_name_index);
             write(pair.value, out);
@@ -680,5 +702,95 @@
                 write(v, out);
             return null;
         }
+
+        private void write(ExtendedAnnotation.Position p, ClassOutputStream out) {
+            out.writeByte(p.type.targetTypeValue());
+            switch (p.type) {
+            // type case
+            case TYPECAST:
+            case TYPECAST_GENERIC_OR_ARRAY:
+            // object creation
+            case INSTANCEOF:
+            case INSTANCEOF_GENERIC_OR_ARRAY:
+            // new expression
+            case NEW:
+            case NEW_GENERIC_OR_ARRAY:
+            case NEW_TYPE_ARGUMENT:
+            case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+                out.writeShort(p.offset);
+                break;
+             // local variable
+            case LOCAL_VARIABLE:
+            case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
+                int table_length = p.lvarOffset.length;
+                out.writeShort(table_length);
+                for (int i = 0; i < table_length; ++i) {
+                    out.writeShort(1);  // for table length
+                    out.writeShort(p.lvarOffset[i]);
+                    out.writeShort(p.lvarLength[i]);
+                    out.writeShort(p.lvarIndex[i]);
+                }
+                break;
+             // method receiver
+            case METHOD_RECEIVER:
+                // Do nothing
+                break;
+            // type parameters
+            case CLASS_TYPE_PARAMETER:
+            case METHOD_TYPE_PARAMETER:
+                out.writeByte(p.parameter_index);
+                break;
+            // type parameters bounds
+            case CLASS_TYPE_PARAMETER_BOUND:
+            case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+            case METHOD_TYPE_PARAMETER_BOUND:
+            case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+                out.writeByte(p.parameter_index);
+                out.writeByte(p.bound_index);
+                break;
+             // wildcards
+            case WILDCARD_BOUND:
+            case WILDCARD_BOUND_GENERIC_OR_ARRAY:
+                write(p.wildcard_position, out);
+                break;
+            // Class extends and implements clauses
+            case CLASS_EXTENDS:
+            case CLASS_EXTENDS_GENERIC_OR_ARRAY:
+                out.writeByte(p.type_index);
+                break;
+            // throws
+            case THROWS:
+                out.writeByte(p.type_index);
+                break;
+            case CLASS_LITERAL:
+                out.writeShort(p.offset);
+                break;
+            // method parameter: not specified
+            case METHOD_PARAMETER_GENERIC_OR_ARRAY:
+                out.writeByte(p.parameter_index);
+                break;
+            // method type argument: wasn't specified
+            case METHOD_TYPE_ARGUMENT:
+            case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+                out.writeShort(p.offset);
+                out.writeByte(p.type_index);
+                break;
+            // We don't need to worry abut these
+            case METHOD_RETURN_GENERIC_OR_ARRAY:
+            case FIELD_GENERIC_OR_ARRAY:
+                break;
+            case UNKNOWN:
+                break;
+            default:
+                throw new AssertionError("unknown type: " + p);
+            }
+
+            // Append location data for generics/arrays.
+            if (p.type.hasLocation()) {
+                out.writeShort(p.location.size());
+                for (int i : p.location)
+                    out.writeByte((byte)i);
+            }
+        }
     }
 }
--- a/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTaskImpl.java	Fri Jun 26 18:51:39 2009 -0700
@@ -133,6 +133,7 @@
     public Boolean call() {
         if (!used.getAndSet(true)) {
             beginContext();
+            notYetEntered = new HashMap<JavaFileObject, JCCompilationUnit>();
             try {
                 compilerMain.setFatalErrors(true);
                 result = compilerMain.compile(args, context, fileObjects, processors);
@@ -143,6 +144,7 @@
             args = null;
             context = null;
             fileObjects = null;
+            notYetEntered = null;
             return result == 0;
         } else {
             throw new IllegalStateException("multiple calls to method 'call'");
--- a/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/api/JavacTrees.java	Fri Jun 26 18:51:39 2009 -0700
@@ -35,6 +35,7 @@
 import javax.lang.model.element.TypeElement;
 import javax.lang.model.type.DeclaredType;
 import javax.lang.model.type.TypeMirror;
+import javax.tools.Diagnostic;
 import javax.tools.JavaCompiler;
 import javax.tools.JavaFileObject;
 
@@ -54,6 +55,7 @@
 import com.sun.tools.javac.comp.MemberEnter;
 import com.sun.tools.javac.comp.Resolve;
 import com.sun.tools.javac.model.JavacElements;
+import com.sun.tools.javac.processing.JavacMessager;
 import com.sun.tools.javac.processing.JavacProcessingEnvironment;
 import com.sun.tools.javac.tree.JCTree.*;
 import com.sun.tools.javac.tree.JCTree;
@@ -61,6 +63,7 @@
 import com.sun.tools.javac.tree.TreeInfo;
 import com.sun.tools.javac.tree.TreeMaker;
 import com.sun.tools.javac.util.Context;
+import com.sun.tools.javac.util.JCDiagnostic;
 import com.sun.tools.javac.util.List;
 import com.sun.tools.javac.util.Log;
 import com.sun.tools.javac.util.Pair;
@@ -336,4 +339,54 @@
 
         return com.sun.tools.javac.code.Type.noType;
     }
+
+    /**
+     * Prints a message of the specified kind at the location of the
+     * tree within the provided compilation unit
+     *
+     * @param kind the kind of message
+     * @param msg  the message, or an empty string if none
+     * @param t    the tree to use as a position hint
+     * @param root the compilation unit that contains tree
+     */
+    public void printMessage(Diagnostic.Kind kind, CharSequence msg,
+            com.sun.source.tree.Tree t,
+            com.sun.source.tree.CompilationUnitTree root) {
+        JavaFileObject oldSource = null;
+        JavaFileObject newSource = null;
+        JCDiagnostic.DiagnosticPosition pos = null;
+
+        newSource = root.getSourceFile();
+        if (newSource != null) {
+            oldSource = log.useSource(newSource);
+            pos = ((JCTree) t).pos();
+        }
+
+        try {
+            switch (kind) {
+            case ERROR:
+                boolean prev = log.multipleErrors;
+                try {
+                    log.error(pos, "proc.messager", msg.toString());
+                } finally {
+                    log.multipleErrors = prev;
+                }
+                break;
+
+            case WARNING:
+                log.warning(pos, "proc.messager", msg.toString());
+                break;
+
+            case MANDATORY_WARNING:
+                log.mandatoryWarning(pos, "proc.messager", msg.toString());
+                break;
+
+            default:
+                log.note(pos, "proc.messager", msg.toString());
+            }
+        } finally {
+            if (oldSource != null)
+                log.useSource(oldSource);
+        }
+    }
 }
--- a/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Attribute.java	Fri Jun 26 18:51:39 2009 -0700
@@ -204,6 +204,21 @@
         }
     }
 
+    public static class TypeCompound extends Compound {
+        public TypeAnnotationPosition position;
+        public TypeCompound(Compound compound,
+                TypeAnnotationPosition position) {
+            this(compound.type, compound.values, position);
+        }
+        public TypeCompound(Type type,
+                List<Pair<MethodSymbol, Attribute>> values,
+                TypeAnnotationPosition position) {
+            super(type, values);
+            this.position = position;
+        }
+
+    }
+
     /** The value for an annotation element of an array type.
      */
     public static class Array extends Attribute {
--- a/src/share/classes/com/sun/tools/javac/code/Source.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Source.java	Fri Jun 26 18:51:39 2009 -0700
@@ -153,6 +153,9 @@
     public boolean enforceMandatoryWarnings() {
         return compareTo(JDK1_5) >= 0;
     }
+    public boolean allowTypeAnnotations() {
+        return compareTo(JDK1_7) >= 0;
+    }
     public static SourceVersion toSourceVersion(Source source) {
         switch(source) {
         case JDK1_2:
--- a/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/code/Symbol.java	Fri Jun 26 18:51:39 2009 -0700
@@ -100,6 +100,17 @@
      */
     public Type type;
 
+    /** The type annotations targeted to a tree directly owned by this symbol
+     */
+    // type annotations are stored here for two purposes:
+    //  - convenient location to store annotations for generation after erasure
+    //  - a private interface for accessing type annotations parsed from
+    //    classfiles
+    //  the field is populated for the following declaration only
+    //  class, field, variable and type parameters
+    //
+    public List<Attribute.TypeCompound> typeAnnotations;
+
     /** The owner of this symbol.
      */
     public Symbol owner;
@@ -122,6 +133,7 @@
         this.completer = null;
         this.erasure_field = null;
         this.attributes_field = List.nil();
+        this.typeAnnotations = List.nil();
         this.name = name;
     }
 
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Jun 26 18:51:39 2009 -0700
@@ -700,7 +700,6 @@
             localEnv.info.scope.leave();
             result = tree.type = m.type;
             chk.validateAnnotations(tree.mods.annotations, m);
-
         }
         finally {
             chk.setLint(prevLint);
@@ -2516,10 +2515,11 @@
                 Type clazzOuter = clazztype.getEnclosingType();
                 if (clazzOuter.tag == CLASS) {
                     Type site;
-                    if (tree.clazz.getTag() == JCTree.IDENT) {
+                    JCExpression clazz = TreeInfo.typeIn(tree.clazz);
+                    if (clazz.getTag() == JCTree.IDENT) {
                         site = env.enclClass.sym.type;
-                    } else if (tree.clazz.getTag() == JCTree.SELECT) {
-                        site = ((JCFieldAccess) tree.clazz).selected.type;
+                    } else if (clazz.getTag() == JCTree.SELECT) {
+                        site = ((JCFieldAccess) clazz).selected.type;
                     } else throw new AssertionError(""+tree);
                     if (clazzOuter.tag == CLASS && site != clazzOuter) {
                         if (site.tag == CLASS)
@@ -2628,6 +2628,10 @@
         result = tree.type = syms.errType;
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        result = tree.type = attribType(tree.getUnderlyingType(), env);
+    }
+
     public void visitErroneous(JCErroneous tree) {
         if (tree.errs != null)
             for (JCTree err : tree.errs)
@@ -2816,6 +2820,9 @@
             (c.flags() & ABSTRACT) == 0) {
             checkSerialVersionUID(tree, c);
         }
+
+        // Check type annotations applicability rules
+        validateTypeAnnotations(tree);
     }
         // where
         /** check if a class is a subtype of Serializable, if that is available. */
@@ -2858,4 +2865,33 @@
     private Type capture(Type type) {
         return types.capture(type);
     }
+
+    private void validateTypeAnnotations(JCTree tree) {
+        tree.accept(typeAnnotationsValidator);
+    }
+    //where
+    private final JCTree.Visitor typeAnnotationsValidator =
+        new TreeScanner() {
+        public void visitAnnotation(JCAnnotation tree) {
+            if (tree instanceof JCTypeAnnotation) {
+                chk.validateTypeAnnotation((JCTypeAnnotation)tree, false);
+            }
+            super.visitAnnotation(tree);
+        }
+        public void visitTypeParameter(JCTypeParameter tree) {
+            chk.validateTypeAnnotations(tree.annotations, true);
+            // don't call super. skip type annotations
+            scan(tree.bounds);
+        }
+        public void visitMethodDef(JCMethodDecl tree) {
+            // need to check static methods
+            if ((tree.sym.flags() & Flags.STATIC) != 0) {
+                for (JCTypeAnnotation a : tree.receiverAnnotations) {
+                    if (chk.isTypeAnnotation(a, false))
+                        log.error(a.pos(), "annotation.type.not.applicable");
+                }
+            }
+            super.visitMethodDef(tree);
+        }
+    };
 }
--- a/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Check.java	Fri Jun 26 18:51:39 2009 -0700
@@ -916,6 +916,10 @@
             }
         }
 
+        public void visitAnnotatedType(JCAnnotatedType tree) {
+            tree.underlyingType.accept(this);
+        }
+
         /** Default visitor method: do nothing.
          */
         public void visitTree(JCTree tree) {
@@ -1806,6 +1810,14 @@
             validateAnnotation(a, s);
     }
 
+    /** Check the type annotations
+     */
+    public void validateTypeAnnotations(List<JCTypeAnnotation> annotations, boolean isTypeParameter) {
+        if (skipAnnotations) return;
+        for (JCTypeAnnotation a : annotations)
+            validateTypeAnnotation(a, isTypeParameter);
+    }
+
     /** Check an annotation of a symbol.
      */
     public void validateAnnotation(JCAnnotation a, Symbol s) {
@@ -1820,6 +1832,15 @@
         }
     }
 
+    public void validateTypeAnnotation(JCTypeAnnotation a, boolean isTypeParameter) {
+        if (a.type == null)
+            throw new AssertionError("annotation tree hasn't been attributed yet: " + a);
+        validateAnnotation(a);
+
+        if (!isTypeAnnotation(a, isTypeParameter))
+            log.error(a.pos(), "annotation.type.not.applicable");
+    }
+
     /** Is s a method symbol that overrides a method in a superclass? */
     boolean isOverrider(Symbol s) {
         if (s.kind != MTH || s.isStatic())
@@ -1838,6 +1859,25 @@
         return false;
     }
 
+    /** Is the annotation applicable to type annotations */
+    boolean isTypeAnnotation(JCTypeAnnotation a, boolean isTypeParameter) {
+        Attribute.Compound atTarget =
+            a.annotationType.type.tsym.attribute(syms.annotationTargetType.tsym);
+        if (atTarget == null) return true;
+        Attribute atValue = atTarget.member(names.value);
+        if (!(atValue instanceof Attribute.Array)) return true; // error recovery
+        Attribute.Array arr = (Attribute.Array) atValue;
+        for (Attribute app : arr.values) {
+            if (!(app instanceof Attribute.Enum)) return true; // recovery
+            Attribute.Enum e = (Attribute.Enum) app;
+            if (!isTypeParameter && e.value.name == names.TYPE_USE)
+                return true;
+            else if (isTypeParameter && e.value.name == names.TYPE_PARAMETER)
+                return true;
+        }
+        return false;
+    }
+
     /** Is the annotation applicable to the symbol? */
     boolean annotationApplicable(JCAnnotation a, Symbol s) {
         Attribute.Compound atTarget =
@@ -1874,6 +1914,13 @@
                 }
             else if (e.value.name == names.PACKAGE)
                 { if (s.kind == PCK) return true; }
+            else if (e.value.name == names.TYPE_USE)
+                { if (s.kind == TYP ||
+                      s.kind == VAR ||
+                      (s.kind == MTH && !s.isConstructor() &&
+                       s.type.getReturnType().tag != VOID))
+                    return true;
+                }
             else
                 return true; // recovery
         }
--- a/src/share/classes/com/sun/tools/javac/comp/Flow.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Flow.java	Fri Jun 26 18:51:39 2009 -0700
@@ -1245,6 +1245,11 @@
         }
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        // annotations don't get scanned
+        tree.underlyingType.accept(this);
+    }
+
     public void visitIdent(JCIdent tree) {
         if (tree.sym.kind == VAR)
             checkInit(tree.pos(), (VarSymbol)tree.sym);
@@ -1254,7 +1259,8 @@
         super.visitTypeCast(tree);
         if (!tree.type.isErroneous()
             && lint.isEnabled(Lint.LintCategory.CAST)
-            && types.isSameType(tree.expr.type, tree.clazz.type)) {
+            && types.isSameType(tree.expr.type, tree.clazz.type)
+            && !(ignoreAnnotatedCasts && containsTypeAnnotation(tree.clazz))) {
             log.warning(tree.pos(), "redundant.cast", tree.expr.type);
         }
     }
@@ -1264,6 +1270,23 @@
     }
 
 /**************************************************************************
+ * utility methods for ignoring type-annotated casts lint checking
+ *************************************************************************/
+    private static final boolean ignoreAnnotatedCasts = true;
+    private static class AnnotationFinder extends TreeScanner {
+        public boolean foundTypeAnno = false;
+        public void visitAnnotation(JCAnnotation tree) {
+            foundTypeAnno = foundTypeAnno || (tree instanceof JCTypeAnnotation);
+        }
+    }
+
+    private boolean containsTypeAnnotation(JCTree e) {
+        AnnotationFinder finder = new AnnotationFinder();
+        finder.scan(e);
+        return finder.foundTypeAnno;
+    }
+
+/**************************************************************************
  * main method
  *************************************************************************/
 
--- a/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/Lower.java	Fri Jun 26 18:51:39 2009 -0700
@@ -2369,6 +2369,11 @@
         result = tree;
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        tree.underlyingType = translate(tree.underlyingType);
+        result = tree.underlyingType;
+    }
+
     public void visitTypeCast(JCTypeCast tree) {
         tree.clazz = translate(tree.clazz);
         if (tree.type.isPrimitive() != tree.expr.type.isPrimitive())
--- a/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/MemberEnter.java	Fri Jun 26 18:51:39 2009 -0700
@@ -99,8 +99,8 @@
         types = Types.instance(context);
         diags = JCDiagnostic.Factory.instance(context);
         target = Target.instance(context);
-        skipAnnotations =
-            Options.instance(context).get("skipAnnotations") != null;
+        Options options = Options.instance(context);
+        skipAnnotations = options.get("skipAnnotations") != null;
     }
 
     /** A queue for classes whose members still need to be entered into the
@@ -906,6 +906,10 @@
             if (hasDeprecatedAnnotation(tree.mods.annotations))
                 c.flags_field |= DEPRECATED;
             annotateLater(tree.mods.annotations, baseEnv, c);
+            // class type parameters use baseEnv but everything uses env
+            for (JCTypeParameter tp : tree.typarams)
+                tp.accept(new TypeAnnotate(baseEnv));
+            tree.accept(new TypeAnnotate(env));
 
             chk.checkNonCyclic(tree.pos(), c.type);
 
@@ -988,6 +992,100 @@
         }
     }
 
+    // A sub-phase that "compiles" annotations in annotated types.
+    private class TypeAnnotate extends TreeScanner {
+        private Env<AttrContext> env;
+        public TypeAnnotate(Env<AttrContext> env) { this.env = env; }
+
+        private void enterTypeAnnotations(List<JCTypeAnnotation> annotations) {
+            Set<TypeSymbol> annotated = new HashSet<TypeSymbol>();
+            if (!skipAnnotations)
+                for (List<JCTypeAnnotation> al = annotations; al.nonEmpty(); al = al.tail) {
+                    JCTypeAnnotation a = al.head;
+                    Attribute.Compound c = annotate.enterAnnotation(a,
+                            syms.annotationType,
+                            env);
+                    if (c == null) continue;
+                    Attribute.TypeCompound tc = new Attribute.TypeCompound(c.type, c.values, a.annotation_position);
+                    a.attribute_field = tc;
+                    // Note: @Deprecated has no effect on local variables and parameters
+                    if (!annotated.add(a.type.tsym))
+                        log.error(a.pos, "duplicate.annotation");
+                }
+        }
+
+        // each class (including enclosed inner classes) should be visited
+        // separately through MemberEnter.complete(Symbol)
+        // this flag is used to prevent from visiting inner classes.
+        private boolean isEnclosingClass = false;
+        @Override
+        public void visitClassDef(final JCClassDecl tree) {
+            if (isEnclosingClass)
+                return;
+            isEnclosingClass = true;
+            scan(tree.mods);
+            // type parameter need to be visited with a separate env
+            // scan(tree.typarams);
+            scan(tree.extending);
+            scan(tree.implementing);
+            scan(tree.defs);
+        }
+
+        private void annotate(final JCTree tree, final List<JCTypeAnnotation> annotations) {
+            annotate.later(new Annotate.Annotator() {
+                public String toString() {
+                    return "annotate " + annotations + " onto " + tree;
+                }
+                public void enterAnnotation() {
+                    JavaFileObject prev = log.useSource(env.toplevel.sourcefile);
+                    try {
+                        enterTypeAnnotations(annotations);
+
+                        // enrich type parameter symbols... easier for annotation processors
+                        if (tree instanceof JCTypeParameter) {
+                            JCTypeParameter typeparam = (JCTypeParameter)tree;
+                            ListBuffer<Attribute.Compound> buf = ListBuffer.lb();
+                            for (JCTypeAnnotation anno : annotations)
+                                buf.add(anno.attribute_field);
+                            typeparam.type.tsym.attributes_field = buf.toList();
+                        }
+                    } finally {
+                        log.useSource(prev);
+                    }
+                }
+            });
+        }
+
+        @Override
+        public void visitAnnotatedType(final JCAnnotatedType tree) {
+            annotate(tree, tree.annotations);
+            super.visitAnnotatedType(tree);
+        }
+        @Override
+        public void visitTypeParameter(final JCTypeParameter tree) {
+            annotate(tree, tree.annotations);
+            super.visitTypeParameter(tree);
+        }
+        @Override
+        public void visitNewArray(final JCNewArray tree) {
+            annotate(tree, tree.annotations);
+            for (List<JCTypeAnnotation> dimAnnos : tree.dimAnnotations)
+                annotate(tree, dimAnnos);
+            super.visitNewArray(tree);
+        }
+        @Override
+        public void visitApply(JCMethodInvocation tree) {
+            super.visitApply(tree);
+            scan(tree.typeargs);
+        }
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            annotate(tree, tree.receiverAnnotations);
+            super.visitMethodDef(tree);
+        }
+    }
+
+
     private Env<AttrContext> baseEnv(JCClassDecl tree, Env<AttrContext> env) {
         Scope typaramScope = new Scope(tree.sym);
         if (tree.typarams != null)
--- a/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/comp/TransTypes.java	Fri Jun 26 18:51:39 2009 -0700
@@ -27,6 +27,8 @@
 
 import java.util.*;
 
+import javax.lang.model.element.ElementKind;
+
 import com.sun.tools.javac.code.*;
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.tree.*;
@@ -59,6 +61,8 @@
         return instance;
     }
 
+    private boolean debugJSR308;
+
     private Names names;
     private Log log;
     private Symtab syms;
@@ -88,6 +92,7 @@
         types = Types.instance(context);
         make = TreeMaker.instance(context);
         resolve = Resolve.instance(context);
+        debugJSR308 = Options.instance(context).get("TA:trans") != null;
     }
 
     /** A hashtable mapping bridge methods to the methods they override after
@@ -435,12 +440,15 @@
     }
 
     public void visitClassDef(JCClassDecl tree) {
+        new TypeAnnotationPositions().scan(tree);
+        new TypeAnnotationLift().scan(tree);
         translateClass(tree.sym);
         result = tree;
     }
 
     JCMethodDecl currentMethod = null;
     public void visitMethodDef(JCMethodDecl tree) {
+        tree.sym.typeAnnotations = tree.sym.typeAnnotations;
         JCMethodDecl previousMethod = currentMethod;
         try {
             currentMethod = tree;
@@ -726,8 +734,8 @@
     /** Visitor method for parameterized types.
      */
     public void visitTypeApply(JCTypeApply tree) {
-        // Delete all type parameters.
-        result = translate(tree.clazz, null);
+        JCTree clazz = translate(tree.clazz, null);
+        result = clazz;
     }
 
 /**************************************************************************
@@ -793,4 +801,342 @@
         pt = null;
         return translate(cdef, null);
     }
+
+    private class TypeAnnotationPositions extends TreeScanner {
+
+        private ListBuffer<JCTree> frames = ListBuffer.lb();
+        private void push(JCTree t) { frames = frames.prepend(t); }
+        private JCTree pop() { return frames.next(); }
+        private JCTree peek() { return frames.first(); }
+        private JCTree peek2() { return frames.toList().tail.head; }
+
+        @Override
+        public void scan(JCTree tree) {
+            push(tree);
+            super.scan(tree);
+            pop();
+        }
+
+        private TypeAnnotationPosition resolveFrame(JCTree tree, JCTree frame,
+                List<JCTree> path, TypeAnnotationPosition p) {
+            switch (frame.getKind()) {
+                case TYPE_CAST:
+                    p.type = TargetType.TYPECAST;
+                    p.pos = frame.pos;
+                    return p;
+
+                case INSTANCE_OF:
+                    p.type = TargetType.INSTANCEOF;
+                    p.pos = frame.pos;
+                    return p;
+
+                case NEW_CLASS:
+                    p.type = TargetType.NEW;
+                    p.pos = frame.pos;
+                    return p;
+
+                case NEW_ARRAY:
+                    p.type = TargetType.NEW;
+                    p.pos = frame.pos;
+                    return p;
+
+                case CLASS:
+                    p.pos = frame.pos;
+                    if (((JCClassDecl)frame).extending == tree) {
+                        p.type = TargetType.CLASS_EXTENDS;
+                        p.type_index = -1;
+                    } else if (((JCClassDecl)frame).implementing.contains(tree)) {
+                        p.type = TargetType.CLASS_EXTENDS;
+                        p.type_index = ((JCClassDecl)frame).implementing.indexOf(tree);
+                    } else if (((JCClassDecl)frame).typarams.contains(tree)) {
+                        p.type = TargetType.CLASS_TYPE_PARAMETER;
+                        p.parameter_index = ((JCClassDecl)frame).typarams.indexOf(tree);
+                    } else
+                        throw new AssertionError();
+                    return p;
+
+                case METHOD: {
+                    JCMethodDecl frameMethod = (JCMethodDecl)frame;
+                    p.pos = frame.pos;
+                    if (frameMethod.receiverAnnotations.contains(tree))
+                        p.type = TargetType.METHOD_RECEIVER;
+                    else if (frameMethod.thrown.contains(tree)) {
+                        p.type = TargetType.THROWS;
+                        p.type_index = frameMethod.thrown.indexOf(tree);
+                    } else if (((JCMethodDecl)frame).restype == tree) {
+                        p.type = TargetType.METHOD_RETURN_GENERIC_OR_ARRAY;
+                    } else if (frameMethod.typarams.contains(tree)) {
+                        p.type = TargetType.METHOD_TYPE_PARAMETER;
+                        p.parameter_index = frameMethod.typarams.indexOf(tree);
+                    } else
+                        throw new AssertionError();
+                    return p;
+                }
+                case MEMBER_SELECT: {
+                    JCFieldAccess fieldFrame = (JCFieldAccess)frame;
+                    if (fieldFrame.name == names._class) {
+                        p.type = TargetType.CLASS_LITERAL;
+                        if (fieldFrame.selected instanceof JCAnnotatedType) {
+                            p.pos = TreeInfo.typeIn(fieldFrame).pos;
+                        } else if (fieldFrame.selected instanceof JCArrayTypeTree) {
+                            p.pos = fieldFrame.selected.pos;
+                        }
+                    } else
+                        throw new AssertionError();
+                    return p;
+                }
+                case PARAMETERIZED_TYPE: {
+                    TypeAnnotationPosition nextP;
+                    if (((JCTypeApply)frame).clazz == tree)
+                        nextP = p; // generic: RAW; noop
+                    else if (((JCTypeApply)frame).arguments.contains(tree))
+                        p.location = p.location.prepend(
+                                ((JCTypeApply)frame).arguments.indexOf(tree));
+                    else
+                        throw new AssertionError();
+
+                    List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                }
+
+                case ARRAY_TYPE: {
+                    p.location = p.location.prepend(0);
+                    List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head, newPath, p);
+                }
+
+                case TYPE_PARAMETER:
+                    if (path.tail.tail.head.getTag() == JCTree.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);
+                    } else if (path.tail.tail.head.getTag() == JCTree.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);
+                    } else
+                        throw new AssertionError();
+                    p.pos = frame.pos;
+                    return p;
+
+                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_GENERIC_OR_ARRAY; break;
+                        case PARAMETER:
+                            p.type = TargetType.METHOD_PARAMETER_GENERIC_OR_ARRAY;
+                            p.parameter_index = methodParamIndex(path, frame);
+                            break;
+                        default: throw new AssertionError();
+                    }
+                    return p;
+
+                case ANNOTATED_TYPE: {
+                    List<JCTree> newPath = path.tail;
+                    return resolveFrame(newPath.head, newPath.tail.head,
+                            newPath, p);
+                }
+
+                case METHOD_INVOCATION: {
+                    JCMethodInvocation invocation = (JCMethodInvocation)frame;
+                    if (!invocation.typeargs.contains(tree))
+                        throw new AssertionError("{" + tree + "} is not an argument in the invocation: " + invocation);
+                    p.type = TargetType.METHOD_TYPE_ARGUMENT;
+                    p.pos = invocation.pos;
+                    p.type_index = invocation.typeargs.indexOf(tree);
+                    return p;
+                }
+
+                case EXTENDS_WILDCARD:
+                case SUPER_WILDCARD: {
+                    p.type = TargetType.WILDCARD_BOUND;
+                    List<JCTree> newPath = path.tail;
+
+                    TypeAnnotationPosition wildcard =
+                        resolveFrame(newPath.head, newPath.tail.head, newPath,
+                                new TypeAnnotationPosition());
+                    if (!wildcard.location.isEmpty())
+                        wildcard.type = wildcard.type.getGenericComplement();
+                    p.wildcard_position = wildcard;
+                    p.pos = frame.pos;
+                    return p;
+                }
+            }
+            return p;
+        }
+
+        @Override
+        public void visitApply(JCMethodInvocation tree) {
+            scan(tree.meth);
+            scan(tree.typeargs);
+            scan(tree.args);
+        }
+
+        private void setTypeAnnotationPos(List<JCTypeAnnotation> annotations, TypeAnnotationPosition position) {
+            for (JCTypeAnnotation anno : annotations) {
+                anno.annotation_position = position;
+                anno.attribute_field.position = position;
+            }
+        }
+
+        @Override
+        public void visitNewArray(JCNewArray tree) {
+            findPosition(tree, tree, tree.annotations);
+            int dimAnnosCount = tree.dimAnnotations.size();
+
+            // handle annotations associated with dimentions
+            for (int i = 0; i < dimAnnosCount; ++i) {
+                TypeAnnotationPosition p = new TypeAnnotationPosition();
+                p.type = TargetType.NEW_GENERIC_OR_ARRAY;
+                p.pos = tree.pos;
+                p.location = p.location.append(i);
+                setTypeAnnotationPos(tree.dimAnnotations.get(i), p);
+            }
+
+            // handle "free" annotations
+            int i = dimAnnosCount == 0 ? 0 : dimAnnosCount - 1;
+            JCExpression elemType = tree.elemtype;
+            while (elemType != null) {
+                if (elemType.getTag() == JCTree.ANNOTATED_TYPE) {
+                    JCAnnotatedType at = (JCAnnotatedType)elemType;
+                    TypeAnnotationPosition p = new TypeAnnotationPosition();
+                    p.type = TargetType.NEW_GENERIC_OR_ARRAY;
+                    p.pos = tree.pos;
+                    p.location = p.location.append(i);
+                    setTypeAnnotationPos(at.annotations, p);
+                    elemType = at.underlyingType;
+                } else if (elemType.getTag() == JCTree.TYPEARRAY) {
+                    ++i;
+                    elemType = ((JCArrayTypeTree)elemType).elemtype;
+                } else
+                    break;
+            }
+
+            // find annotations locations of initializer elements
+            scan(tree.elems);
+        }
+
+        @Override
+        public void visitAnnotatedType(JCAnnotatedType tree) {
+            findPosition(tree, peek2(), tree.annotations);
+            super.visitAnnotatedType(tree);
+        }
+
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            TypeAnnotationPosition p = new TypeAnnotationPosition();
+            p.type = TargetType.METHOD_RECEIVER;
+            setTypeAnnotationPos(tree.receiverAnnotations, p);
+            super.visitMethodDef(tree);
+        }
+        @Override
+        public void visitTypeParameter(JCTypeParameter tree) {
+            findPosition(tree, peek2(), tree.annotations);
+            super.visitTypeParameter(tree);
+        }
+
+        void findPosition(JCTree tree, JCTree frame, List<JCTypeAnnotation> annotations) {
+            if (!annotations.isEmpty()) {
+                TypeAnnotationPosition p =
+                        resolveFrame(tree, frame, frames.toList(),
+                                new TypeAnnotationPosition());
+                if (!p.location.isEmpty())
+                    p.type = p.type.getGenericComplement();
+                setTypeAnnotationPos(annotations, p);
+                if (debugJSR308) {
+                    System.out.println("trans: " + tree);
+                    System.out.println("  target: " + p);
+                }
+            }
+        }
+
+        private int methodParamIndex(List<JCTree> path, JCTree param) {
+            List<JCTree> curr = path;
+            if (curr.head != param)
+                curr = path.tail;
+            JCMethodDecl method = (JCMethodDecl)curr.tail.head;
+            return method.params.indexOf(param);
+        }
+    }
+
+    private class TypeAnnotationLift extends TreeScanner {
+        List<Attribute.TypeCompound> recordedTypeAnnotations = List.nil();
+
+        boolean isInner = false;
+        @Override
+        public void visitClassDef(JCClassDecl tree) {
+            if (isInner) {
+                // tree is an inner class tree.  stop now.
+                // TransTypes.visitClassDef makes an invocation for each class
+                // seperately.
+                return;
+            }
+            isInner = true;
+            List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
+            recordedTypeAnnotations = List.nil();
+            try {
+                super.visitClassDef(tree);
+            } finally {
+                tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
+                recordedTypeAnnotations = prevTAs;
+            }
+        }
+
+        @Override
+        public void visitMethodDef(JCMethodDecl tree) {
+            List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
+            recordedTypeAnnotations = List.nil();
+            try {
+                super.visitMethodDef(tree);
+            } finally {
+                tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
+                recordedTypeAnnotations = prevTAs;
+            }
+        }
+
+        @Override
+        public void visitVarDef(JCVariableDecl tree) {
+            List<Attribute.TypeCompound> prevTAs = recordedTypeAnnotations;
+            recordedTypeAnnotations = List.nil();
+            ElementKind kind = tree.sym.getKind();
+            if (kind == ElementKind.LOCAL_VARIABLE && tree.mods.annotations.nonEmpty()) {
+                // need to lift the annotations
+                TypeAnnotationPosition position = new TypeAnnotationPosition();
+                position.pos = tree.pos;
+                position.type = TargetType.LOCAL_VARIABLE;
+                for (Attribute.Compound attribute : tree.sym.attributes_field) {
+                    Attribute.TypeCompound tc =
+                        new Attribute.TypeCompound(attribute.type, attribute.values, position);
+                    recordedTypeAnnotations = recordedTypeAnnotations.append(tc);
+                }
+            }
+            try {
+                super.visitVarDef(tree);
+            } finally {
+                if (kind.isField() || kind == ElementKind.LOCAL_VARIABLE)
+                    tree.sym.typeAnnotations = tree.sym.typeAnnotations.appendList(recordedTypeAnnotations);
+                recordedTypeAnnotations = kind.isField() ? prevTAs : prevTAs.appendList(recordedTypeAnnotations);
+            }
+        }
+
+        @Override
+        public void visitApply(JCMethodInvocation tree) {
+            scan(tree.meth);
+            scan(tree.typeargs);
+            scan(tree.args);
+        }
+
+        public void visitAnnotation(JCAnnotation tree) {
+            if (tree instanceof JCTypeAnnotation)
+                recordedTypeAnnotations = recordedTypeAnnotations.append(((JCTypeAnnotation)tree).attribute_field);
+            super.visitAnnotation(tree);
+        }
+    }
+
 }
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassReader.java	Fri Jun 26 18:51:39 2009 -0700
@@ -47,7 +47,6 @@
 import com.sun.tools.javac.code.Symtab;
 import com.sun.tools.javac.file.BaseFileObject;
 import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.Flags.*;
 import static com.sun.tools.javac.code.Kinds.*;
@@ -187,6 +186,10 @@
     /** The minor version number of the class file being read. */
     int minorVersion;
 
+    /** Switch: debug output for JSR 308-related operations.
+     */
+    boolean debugJSR308;
+
     /** Get the ClassReader instance for this invocation. */
     public static ClassReader instance(Context context) {
         ClassReader instance = context.get(classReaderKey);
@@ -256,6 +259,7 @@
             : null;
 
         typevars = new Scope(syms.noSymbol);
+        debugJSR308 = options.get("TA:reader") != null;
 
         initAttributeReaders();
     }
@@ -303,6 +307,12 @@
         return (char)(((buf[bp++] & 0xFF) << 8) + (buf[bp++] & 0xFF));
     }
 
+    /** Read a byte.
+     */
+    byte nextByte() {
+        return buf[bp++];
+    }
+
     /** Read an integer.
      */
     int nextInt() {
@@ -1060,7 +1070,21 @@
                     if (allowVarargs)
                         sym.flags_field |= VARARGS;
                 }
-            }
+            },
+
+            // v51 attributes
+            new AttributeReader(names.RuntimeVisibleTypeAnnotations, V51, CLASS_OR_MEMBER_ATTRIBUTE) {
+                void read(Symbol sym, int attrLen) {
+                    attachTypeAnnotations(sym);
+                }
+            },
+
+            new AttributeReader(names.RuntimeInvisibleTypeAnnotations, V51, CLASS_OR_MEMBER_ATTRIBUTE) {
+                void read(Symbol sym, int attrLen) {
+                    attachTypeAnnotations(sym);
+                }
+            },
+
 
             // The following attributes for a Code attribute are not currently handled
             // StackMapTable
@@ -1268,6 +1292,17 @@
         }
     }
 
+    void attachTypeAnnotations(final Symbol sym) {
+        int numAttributes = nextChar();
+        if (numAttributes != 0) {
+            ListBuffer<TypeAnnotationProxy> proxies =
+                ListBuffer.lb();
+            for (int i = 0; i < numAttributes; i++)
+                proxies.append(readTypeAnnotation());
+            annotate.later(new TypeAnnotationCompleter(sym, proxies.toList()));
+        }
+    }
+
     /** Attach the default value for an annotation element.
      */
     void attachAnnotationDefault(final Symbol sym) {
@@ -1304,6 +1339,121 @@
         return new CompoundAnnotationProxy(t, pairs.toList());
     }
 
+    TypeAnnotationProxy readTypeAnnotation() {
+        CompoundAnnotationProxy proxy = readCompoundAnnotation();
+        TypeAnnotationPosition position = readPosition();
+
+        if (debugJSR308)
+            System.out.println("TA: reading: " + proxy + " @ " + position
+                    + " in " + log.currentSourceFile());
+
+        return new TypeAnnotationProxy(proxy, position);
+    }
+
+    TypeAnnotationPosition readPosition() {
+        byte tag = nextByte();
+
+        if (!TargetType.isValidTargetTypeValue(tag))
+            throw this.badClassFile("bad.type.annotation.value", tag);
+
+        TypeAnnotationPosition position = new TypeAnnotationPosition();
+        TargetType type = TargetType.fromTargetTypeValue(tag);
+
+        position.type = type;
+
+        switch (type) {
+        // type case
+        case TYPECAST:
+        case TYPECAST_GENERIC_OR_ARRAY:
+        // object creation
+        case INSTANCEOF:
+        case INSTANCEOF_GENERIC_OR_ARRAY:
+        // new expression
+        case NEW:
+        case NEW_GENERIC_OR_ARRAY:
+            position.offset = nextChar();
+            break;
+         // local variable
+        case LOCAL_VARIABLE:
+        case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
+            int table_length = nextChar();
+            position.lvarOffset = new int[table_length];
+            position.lvarLength = new int[table_length];
+            position.lvarIndex = new int[table_length];
+
+            for (int i = 0; i < table_length; ++i) {
+                position.lvarOffset[i] = nextChar();
+                position.lvarLength[i] = nextChar();
+                position.lvarIndex[i] = nextChar();
+            }
+            break;
+         // method receiver
+        case METHOD_RECEIVER:
+            // Do nothing
+            break;
+        // type parameters
+        case CLASS_TYPE_PARAMETER:
+        case METHOD_TYPE_PARAMETER:
+            position.parameter_index = nextByte();
+            break;
+        // type parameter bounds
+        case CLASS_TYPE_PARAMETER_BOUND:
+        case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+        case METHOD_TYPE_PARAMETER_BOUND:
+        case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+            position.parameter_index = nextByte();
+            position.bound_index = nextByte();
+            break;
+         // wildcard
+        case WILDCARD_BOUND:
+        case WILDCARD_BOUND_GENERIC_OR_ARRAY:
+            position.wildcard_position = readPosition();
+            break;
+         // Class extends and implements clauses
+        case CLASS_EXTENDS:
+        case CLASS_EXTENDS_GENERIC_OR_ARRAY:
+            position.type_index = nextByte();
+            break;
+        // throws
+        case THROWS:
+            position.type_index = nextByte();
+            break;
+        case CLASS_LITERAL:
+        case CLASS_LITERAL_GENERIC_OR_ARRAY:
+            position.offset = nextChar();
+            break;
+        // method parameter: not specified
+        case METHOD_PARAMETER_GENERIC_OR_ARRAY:
+            position.parameter_index = nextByte();
+            break;
+        // method type argument: wasn't specified
+        case NEW_TYPE_ARGUMENT:
+        case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+        case METHOD_TYPE_ARGUMENT:
+        case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+            position.offset = nextChar();
+            position.type_index = nextByte();
+            break;
+        // We don't need to worry abut these
+        case METHOD_RETURN_GENERIC_OR_ARRAY:
+        case FIELD_GENERIC_OR_ARRAY:
+            break;
+        case UNKNOWN:
+            break;
+        default:
+            throw new AssertionError("unknown type: " + position);
+        }
+
+        if (type.hasLocation()) {
+            int len = nextChar();
+            ListBuffer<Integer> loc = ListBuffer.lb();
+            for (int i = 0; i < len; i++)
+                loc = loc.append((int)nextByte());
+            position.location = loc.toList();
+        }
+
+        return position;
+    }
     Attribute readAttributeValue() {
         char c = (char) buf[bp++];
         switch (c) {
@@ -1408,6 +1558,18 @@
         }
     }
 
+    /** A temporary proxy representing a type annotation.
+     */
+    static class TypeAnnotationProxy {
+        final CompoundAnnotationProxy compound;
+        final TypeAnnotationPosition position;
+        public TypeAnnotationProxy(CompoundAnnotationProxy compound,
+                TypeAnnotationPosition position) {
+            this.compound = compound;
+            this.position = position;
+        }
+    }
+
     class AnnotationDeproxy implements ProxyVisitor {
         private ClassSymbol requestingOwner = currentOwner.kind == MTH
             ? currentOwner.enclClass() : (ClassSymbol)currentOwner;
@@ -1604,6 +1766,45 @@
         }
     }
 
+    class TypeAnnotationCompleter extends AnnotationCompleter {
+
+        List<TypeAnnotationProxy> proxies;
+
+        TypeAnnotationCompleter(Symbol sym,
+                List<TypeAnnotationProxy> proxies) {
+            super(sym, List.<CompoundAnnotationProxy>nil());
+            this.proxies = proxies;
+        }
+
+        List<Attribute.TypeCompound> deproxyTypeCompoundList(List<TypeAnnotationProxy> proxies) {
+            ListBuffer<Attribute.TypeCompound> buf = ListBuffer.lb();
+            for (TypeAnnotationProxy proxy: proxies) {
+                Attribute.Compound compound = deproxyCompound(proxy.compound);
+                Attribute.TypeCompound typeCompound = new Attribute.TypeCompound(compound, proxy.position);
+                buf.add(typeCompound);
+            }
+            return buf.toList();
+        }
+
+        @Override
+        public void enterAnnotation() {
+            JavaFileObject previousClassFile = currentClassFile;
+            try {
+                currentClassFile = classFile;
+                List<Attribute.TypeCompound> newList = deproxyTypeCompoundList(proxies);
+              if (debugJSR308)
+              System.out.println("TA: reading: adding " + newList
+                      + " to symbol " + sym + " in " + log.currentSourceFile());
+                sym.typeAnnotations = ((sym.typeAnnotations == null)
+                                        ? newList
+                                        : newList.prependList(sym.typeAnnotations));
+
+            } finally {
+                currentClassFile = previousClassFile;
+            }
+        }
+    }
+
 
 /************************************************************************
  * Reading Symbols
--- a/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/ClassWriter.java	Fri Jun 26 18:51:39 2009 -0700
@@ -37,7 +37,6 @@
 import com.sun.tools.javac.code.Symbol.*;
 import com.sun.tools.javac.code.Type.*;
 import com.sun.tools.javac.util.*;
-import com.sun.tools.javac.util.List;
 
 import static com.sun.tools.javac.code.BoundKind.*;
 import static com.sun.tools.javac.code.Flags.*;
@@ -62,6 +61,10 @@
 
     private final Options options;
 
+    /** Switch: debugging output for JSR 308-related operations.
+     */
+    private boolean debugJSR308;
+
     /** Switch: verbose output.
      */
     private boolean verbose;
@@ -173,6 +176,7 @@
         types = Types.instance(context);
         fileManager = context.get(JavaFileManager.class);
 
+        debugJSR308    = options.get("TA:writer") != null;
         verbose        = options.get("-verbose")     != null;
         scramble       = options.get("-scramble")    != null;
         scrambleAll    = options.get("-scrambleAll") != null;
@@ -668,6 +672,7 @@
             acount++;
         }
         acount += writeJavaAnnotations(sym.getAnnotationMirrors());
+        acount += writeTypeAnnotations(sym.typeAnnotations);
         return acount;
     }
 
@@ -762,6 +767,43 @@
         return attrCount;
     }
 
+    int writeTypeAnnotations(List<Attribute.TypeCompound> typeAnnos) {
+        if (typeAnnos.isEmpty()) return 0;
+
+        ListBuffer<Attribute.TypeCompound> visibles = ListBuffer.lb();
+        ListBuffer<Attribute.TypeCompound> invisibles = ListBuffer.lb();
+
+        for (Attribute.TypeCompound tc : typeAnnos) {
+                switch (getRetention(tc.type.tsym)) {
+                case SOURCE: break;
+                case CLASS: invisibles.append(tc); break;
+                case RUNTIME: visibles.append(tc); break;
+                default: ;// /* fail soft */ throw new AssertionError(vis);
+            }
+        }
+
+        int attrCount = 0;
+        if (visibles.length() != 0) {
+            int attrIndex = writeAttr(names.RuntimeVisibleTypeAnnotations);
+            databuf.appendChar(visibles.length());
+            for (Attribute.TypeCompound p : visibles)
+                writeTypeAnnotation(p);
+            endAttr(attrIndex);
+            attrCount++;
+        }
+
+        if (invisibles.length() != 0) {
+            int attrIndex = writeAttr(names.RuntimeInvisibleTypeAnnotations);
+            databuf.appendChar(invisibles.length());
+            for (Attribute.TypeCompound p : invisibles)
+                writeTypeAnnotation(p);
+            endAttr(attrIndex);
+            attrCount++;
+        }
+
+        return attrCount;
+    }
+
     /** A mirror of java.lang.annotation.RetentionPolicy. */
     enum RetentionPolicy {
         SOURCE,
@@ -862,6 +904,104 @@
         }
     }
 
+    void writeTypeAnnotation(Attribute.TypeCompound c) {
+        // ignore UNKNOWN attributes - improve testing
+      if (debugJSR308)
+        System.out.println("TA: writing " + c + " at " + c.position
+                + " in " + log.currentSourceFile());
+      writeCompoundAttribute(c);
+      writePosition(c.position);
+    }
+
+    void writePosition(TypeAnnotationPosition p) {
+        databuf.appendByte(p.type.targetTypeValue());
+        switch (p.type) {
+        // type case
+        case TYPECAST:
+        case TYPECAST_GENERIC_OR_ARRAY:
+        // object creation
+        case INSTANCEOF:
+        case INSTANCEOF_GENERIC_OR_ARRAY:
+        // new expression
+        case NEW:
+        case NEW_GENERIC_OR_ARRAY:
+            databuf.appendChar(p.offset);
+            break;
+         // local variable
+        case LOCAL_VARIABLE:
+        case LOCAL_VARIABLE_GENERIC_OR_ARRAY:
+            databuf.appendChar(p.lvarOffset.length);  // for table length
+            for (int i = 0; i < p.lvarOffset.length; ++i) {
+                databuf.appendChar(p.lvarOffset[i]);
+                databuf.appendChar(p.lvarLength[i]);
+                databuf.appendChar(p.lvarIndex[i]);
+            }
+            break;
+         // method receiver
+        case METHOD_RECEIVER:
+            // Do nothing
+            break;
+        // type parameters
+        case CLASS_TYPE_PARAMETER:
+        case METHOD_TYPE_PARAMETER:
+            databuf.appendByte(p.parameter_index);
+            break;
+        // type parameters bounds
+        case CLASS_TYPE_PARAMETER_BOUND:
+        case CLASS_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+        case METHOD_TYPE_PARAMETER_BOUND:
+        case METHOD_TYPE_PARAMETER_BOUND_GENERIC_OR_ARRAY:
+            databuf.appendByte(p.parameter_index);
+            databuf.appendByte(p.bound_index);
+            break;
+         // wildcards
+        case WILDCARD_BOUND:
+        case WILDCARD_BOUND_GENERIC_OR_ARRAY:
+            writePosition(p.wildcard_position);
+            break;
+         // Class extends and implements clauses
+        case CLASS_EXTENDS:
+        case CLASS_EXTENDS_GENERIC_OR_ARRAY:
+            databuf.appendByte(p.type_index);
+            break;
+        // throws
+        case THROWS:
+            databuf.appendByte(p.type_index);
+            break;
+        case CLASS_LITERAL:
+        case CLASS_LITERAL_GENERIC_OR_ARRAY:
+            databuf.appendChar(p.offset);
+            break;
+        // method parameter: not specified
+        case METHOD_PARAMETER_GENERIC_OR_ARRAY:
+            databuf.appendByte(p.parameter_index);
+            break;
+        // method type argument: wasn't specified
+        case NEW_TYPE_ARGUMENT:
+        case NEW_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+        case METHOD_TYPE_ARGUMENT:
+        case METHOD_TYPE_ARGUMENT_GENERIC_OR_ARRAY:
+            databuf.appendChar(p.offset);
+            databuf.appendByte(p.type_index);
+            break;
+        // We don't need to worry abut these
+        case METHOD_RETURN_GENERIC_OR_ARRAY:
+        case FIELD_GENERIC_OR_ARRAY:
+            break;
+        case UNKNOWN:
+            break;
+        default:
+            throw new AssertionError("unknown position: " + p);
+        }
+
+        // Append location data for generics/arrays.
+        if (p.type.hasLocation()) {
+            databuf.appendChar(p.location.size());
+            for (int i : p.location)
+                databuf.appendByte((byte)i);
+        }
+    }
+
 /**********************************************************************
  * Writing Objects
  **********************************************************************/
@@ -1569,6 +1709,7 @@
 
         acount += writeFlagAttrs(c.flags());
         acount += writeJavaAnnotations(c.getAnnotationMirrors());
+        acount += writeTypeAnnotations(c.typeAnnotations);
         acount += writeEnclosingMethodAttribute(c);
 
         poolbuf.appendInt(JAVA_MAGIC);
--- a/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Code.java	Fri Jun 26 18:51:39 2009 -0700
@@ -1913,11 +1913,27 @@
                     v.length = length;
                     putVar(v);
                 }
+                fillLocalVarPosition(v);
             }
         }
         state.defined.excl(adr);
     }
 
+    private void fillLocalVarPosition(LocalVar lv) {
+        if (lv == null || lv.sym == null
+                || lv.sym.typeAnnotations == null)
+            return;
+        for (Attribute.TypeCompound ta : lv.sym.typeAnnotations) {
+            TypeAnnotationPosition p = ta.position;
+            while (p != null) {
+                p.lvarOffset[0] = (int)lv.start_pc;
+                p.lvarLength[0] = (int)lv.length;
+                p.lvarIndex[0] = (int)lv.reg;
+                p = p.wildcard_position;
+            }
+        }
+    }
+
     /** Put a live variable range into the buffer to be output to the
      *  class file.
      */
--- a/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/jvm/Gen.java	Fri Jun 26 18:51:39 2009 -0700
@@ -26,6 +26,8 @@
 package com.sun.tools.javac.jvm;
 import java.util.*;
 
+import javax.lang.model.element.ElementKind;
+
 import com.sun.tools.javac.util.*;
 import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
 import com.sun.tools.javac.util.List;
@@ -939,7 +941,6 @@
                                  startpcCrt,
                                  code.curPc());
 
-                // End the scope of all local variables in variable info.
                 code.endScopes(0);
 
                 // If we exceeded limits, panic
@@ -1439,7 +1440,6 @@
             // Resolve all breaks.
             code.resolve(exitChain);
 
-            // End the scopes of all try-local variables in variable info.
             code.endScopes(limit);
         }
 
@@ -1672,6 +1672,7 @@
  *************************************************************************/
 
     public void visitApply(JCMethodInvocation tree) {
+        setTypeAnnotationPositions(tree.pos);
         // Generate code for method.
         Item m = genExpr(tree.meth, methodType);
         // Generate code for all arguments, where the expected types are
@@ -1707,10 +1708,45 @@
         result = items.makeStackItem(pt);
     }
 
+    private void setTypeAnnotationPositions(int treePos) {
+        MethodSymbol meth = code.meth;
+
+        for (Attribute.TypeCompound ta : meth.typeAnnotations) {
+            if (ta.position.pos == treePos) {
+                ta.position.offset = code.cp;
+                ta.position.lvarOffset[0] = code.cp;
+            }
+        }
+
+        if (code.meth.getKind() != ElementKind.CONSTRUCTOR
+                && code.meth.getKind() != ElementKind.STATIC_INIT)
+            return;
+
+        for (Attribute.TypeCompound ta : meth.owner.typeAnnotations) {
+            if (ta.position.pos == treePos) {
+                ta.position.offset = code.cp;
+                ta.position.lvarOffset[0] = code.cp;
+            }
+        }
+
+        ClassSymbol clazz = meth.enclClass();
+        for (Symbol s : new com.sun.tools.javac.model.FilteredMemberList(clazz.members())) {
+            if (!s.getKind().isField())
+                continue;
+            for (Attribute.TypeCompound ta : s.typeAnnotations) {
+                if (ta.position.pos == treePos) {
+                    ta.position.offset = code.cp;
+                    ta.position.lvarOffset[0] = code.cp;
+                }
+            }
+        }
+    }
+
     public void visitNewClass(JCNewClass tree) {
         // Enclosing instances or anonymous classes should have been eliminated
         // by now.
         assert tree.encl == null && tree.def == null;
+        setTypeAnnotationPositions(tree.pos);
 
         code.emitop2(new_, makeRef(tree.pos(), tree.type));
         code.emitop0(dup);
@@ -1725,6 +1761,8 @@
     }
 
     public void visitNewArray(JCNewArray tree) {
+        setTypeAnnotationPositions(tree.pos);
+
         if (tree.elems != null) {
             Type elemtype = types.elemtype(tree.type);
             loadIntConst(tree.elems.length());
@@ -2053,6 +2091,7 @@
         }
 
     public void visitTypeCast(JCTypeCast tree) {
+        setTypeAnnotationPositions(tree.pos);
         result = genExpr(tree.expr, tree.clazz.type).load();
         // Additional code is only needed if we cast to a reference type
         // which is not statically a supertype of the expression's type.
@@ -2069,6 +2108,8 @@
     }
 
     public void visitTypeTest(JCInstanceOf tree) {
+        setTypeAnnotationPositions(tree.pos);
+
         genExpr(tree.expr, tree.expr.type).load();
         code.emitop2(instanceof_, makeRef(tree.pos(), tree.clazz.type));
         result = items.makeStackItem(syms.booleanType);
@@ -2110,6 +2151,7 @@
 
         if (tree.name == names._class) {
             assert target.hasClassLiterals();
+            setTypeAnnotationPositions(tree.pos);
             code.emitop2(ldc2, makeRef(tree.pos(), tree.selected.type));
             result = items.makeStackItem(pt);
             return;
--- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jun 26 18:51:39 2009 -0700
@@ -75,6 +75,42 @@
     /** The name table. */
     private Names names;
 
+    // Because of javac's limited lookahead, some contexts are ambiguous in
+    // the presence of type annotations even though they are not ambiguous
+    // in the absence of type annotations.  Consider this code:
+    //   void m(String [] m) { }
+    //   void m(String ... m) { }
+    // After parsing "String", javac calls bracketsOpt which immediately
+    // returns if the next character is not '['.  Similarly, javac can see
+    // if the next token is ... and in that case parse an ellipsis.  But in
+    // the presence of type annotations:
+    //   void m(String @A [] m) { }
+    //   void m(String @A ... m) { }
+    // no finite lookahead is enough to determine whether to read array
+    // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
+    // bracketsOpt first reads all the leading annotations and only then
+    // discovers that it needs to fail.  bracketsOpt needs a way to push
+    // back the extra annotations that it read.  (But, bracketsOpt should
+    // not *always* be allowed to push back extra annotations that it finds
+    // -- in most contexts, any such extra annotation is an error.
+    // Another similar case occurs with arrays and receiver annotations:
+    //   String b() @Array [] @Receiver { }
+    //   String b() @Receiver { }
+    //
+    // The following two variables permit type annotations that have
+    // already been read to be stored for later use.  Alternate
+    // implementations are possible but would cause much larger changes to
+    // the parser.
+    /** Type annotations that have already been read but have not yet been used. **/
+    private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
+    /**
+     * If the parser notices extra annotations, then it either immediately
+     * issues an error (if this variable is false) or places the extra
+     * annotations in variable typeAnnotationsPushedBack (if this variable
+     * is true).
+     */
+    private boolean permitTypeAnnotationsPushBack = false;
+
     /** Construct a parser from a given scanner, tree factory and log.
      */
     protected JavacParser(ParserFactory fac,
@@ -95,13 +131,19 @@
         this.allowForeach = source.allowForeach();
         this.allowStaticImport = source.allowStaticImport();
         this.allowAnnotations = source.allowAnnotations();
+        this.allowTypeAnnotations = source.allowTypeAnnotations();
         this.keepDocComments = keepDocComments;
         if (keepDocComments)
             docComments = new HashMap<JCTree,String>();
         this.keepLineMap = keepLineMap;
         this.errorTree = F.Erroneous();
+        this.debugJSR308 = fac.options.get("TA:parser") != null;
     }
 
+    /** Switch: debug output for type-annotations operations
+     */
+    boolean debugJSR308;
+
     /** Switch: Should generics be recognized?
      */
     boolean allowGenerics;
@@ -130,6 +172,10 @@
      */
     boolean allowAnnotations;
 
+    /** Switch: should we recognize type annotations?
+     */
+    boolean allowTypeAnnotations;
+
     /** Switch: should we keep docComments?
      */
     boolean keepDocComments;
@@ -558,7 +604,33 @@
         return term(EXPR);
     }
 
+    /**
+     * parses (optional) type annotations followed by a type. If the
+     * annotations are present before the type and are not consumed during array
+     * parsing, this method returns a {@link JCAnnotatedType} consisting of
+     * these annotations and the underlying type. Otherwise, it returns the
+     * underlying type.
+     *
+     * <p>
+     *
+     * Note that this method sets {@code mode} to {@code TYPE} first, before
+     * parsing annotations.
+     */
     public JCExpression parseType() {
+        List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
+        return parseType(annotations);
+    }
+
+    public JCExpression parseType(List<JCTypeAnnotation> annotations) {
+        JCExpression result = unannotatedType();
+
+        if (!annotations.isEmpty())
+            result = F.AnnotatedType(annotations, result);
+
+        return result;
+    }
+
+    public JCExpression unannotatedType() {
         return term(TYPE);
     }
 
@@ -792,8 +864,8 @@
      *                 | [TypeArguments] THIS [Arguments]
      *                 | [TypeArguments] SUPER SuperSuffix
      *                 | NEW [TypeArguments] Creator
-     *                 | Ident { "." Ident }
-     *                   [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
+     *                 | [Annotations] Ident { "." Ident }
+     *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
      *                   | Arguments
      *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
      *                   ]
@@ -942,23 +1014,62 @@
                 typeArgs = null;
             } else return illegal();
             break;
+        case MONKEYS_AT:
+
+            // only annotated targetting class literals or cast types are valid
+            List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
+            if (typeAnnos.isEmpty()) {
+                // else there would be no '@'
+                throw new AssertionError("type annos is empty");
+            }
+
+            JCExpression expr = term3();
+
+            // Type annotations: If term3 just parsed a non-type, expect a
+            // class literal (and issue a syntax error if there is no class
+            // literal). Otherwise, create a JCAnnotatedType.
+            if ((mode & TYPE) == 0) {
+                if (expr.getTag() != JCTree.SELECT)
+                    return illegal(typeAnnos.head.pos);
+                JCFieldAccess sel = (JCFieldAccess)expr;
+                if (sel.name != names._class)
+                    return illegal();
+                else {
+                    sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
+                    t = expr;
+                }
+            } else {
+                // type annotation targeting a cast
+                t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
+            }
+            break;
         case IDENTIFIER: case ASSERT: case ENUM:
             if (typeArgs != null) return illegal();
             t = toP(F.at(S.pos()).Ident(ident()));
             loop: while (true) {
                 pos = S.pos();
+                final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
+
+                // need to report an error later if LBRACKET is for array
+                // index access rather than array creation level
+                if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
+                    return illegal(annos.head.pos);
                 switch (S.token()) {
                 case LBRACKET:
                     S.nextToken();
+
                     if (S.token() == RBRACKET) {
+
                         S.nextToken();
-                        t = bracketsOpt(t);
+
+                        t = bracketsOpt(t, annos);
                         t = toP(F.at(pos).TypeArray(t));
                         t = bracketsSuffix(t);
                     } else {
                         if ((mode & EXPR) != 0) {
                             mode = EXPR;
                             JCExpression t1 = term();
+                            if (!annos.isEmpty()) t = illegal(annos.head.pos);
                             t = to(F.at(pos).Indexed(t, t1));
                         }
                         accept(RBRACKET);
@@ -1011,6 +1122,10 @@
                     // typeArgs saved for next loop iteration.
                     t = toP(F.at(pos).Select(t, ident()));
                     break;
+                case ELLIPSIS:
+                    assert this.permitTypeAnnotationsPushBack;
+                    typeAnnotationsPushedBack = annos;
+                    break loop;
                 default:
                     break loop;
                 }
@@ -1049,14 +1164,18 @@
         if (typeArgs != null) illegal();
         while (true) {
             int pos1 = S.pos();
+
+            final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
+
             if (S.token() == LBRACKET) {
                 S.nextToken();
+
                 if ((mode & TYPE) != 0) {
                     int oldmode = mode;
                     mode = TYPE;
                     if (S.token() == RBRACKET) {
                         S.nextToken();
-                        t = bracketsOpt(t);
+                        t = bracketsOpt(t, annos);
                         t = toP(F.at(pos1).TypeArray(t));
                         return t;
                     }
@@ -1091,6 +1210,13 @@
                     typeArgs = null;
                 }
             } else {
+                if (!annos.isEmpty()) {
+                    illegal(0);
+                    if (permitTypeAnnotationsPushBack)
+                        typeAnnotationsPushedBack = annos;
+                    else
+                        return illegal(annos.head.pos);
+                }
                 break;
             }
         }
@@ -1100,6 +1226,7 @@
                   S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
             S.nextToken();
         }
+
         return toP(t);
     }
 
@@ -1232,22 +1359,24 @@
     }
 
     /** TypeArgument = Type
-     *               | "?"
-     *               | "?" EXTENDS Type {"&" Type}
-     *               | "?" SUPER Type
+     *               | [Annotations] "?"
+     *               | [Annotations] "?" EXTENDS Type {"&" Type}
+     *               | [Annotations] "?" SUPER Type
      */
     JCExpression typeArgument() {
-        if (S.token() != QUES) return parseType();
+        List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
+        if (S.token() != QUES) return parseType(annotations);
         int pos = S.pos();
         S.nextToken();
+        JCExpression result;
         if (S.token() == EXTENDS) {
             TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
             S.nextToken();
-            return F.at(pos).Wildcard(t, parseType());
+            result = F.at(pos).Wildcard(t, parseType());
         } else if (S.token() == SUPER) {
             TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
             S.nextToken();
-            return F.at(pos).Wildcard(t, parseType());
+            result = F.at(pos).Wildcard(t, parseType());
         } else if (S.token() == IDENTIFIER) {
             //error recovery
             reportSyntaxError(S.prevEndPos(), "expected3",
@@ -1255,11 +1384,14 @@
             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
             JCExpression wc = toP(F.at(pos).Wildcard(t, null));
             JCIdent id = toP(F.at(S.pos()).Ident(ident()));
-            return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
+            result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
         } else {
             TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
-            return toP(F.at(pos).Wildcard(t, null));
+            result = toP(F.at(pos).Wildcard(t, null));
         }
+        if (!annotations.isEmpty())
+            result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
+        return result;
     }
 
     JCTypeApply typeArguments(JCExpression t) {
@@ -1268,21 +1400,47 @@
         return toP(F.at(pos).TypeApply(t, args));
     }
 
-    /** BracketsOpt = {"[" "]"}
+    /**
+     * BracketsOpt = { [Annotations] "[" "]" }
+     *
+     * <p>
+     *
+     * <code>annotations</code> is the list of annotations targeting
+     * the expression <code>t</code>.
      */
-    private JCExpression bracketsOpt(JCExpression t) {
+    private JCExpression bracketsOpt(JCExpression t,
+            List<JCTypeAnnotation> annotations) {
+        List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
+
         if (S.token() == LBRACKET) {
             int pos = S.pos();
             S.nextToken();
-            t = bracketsOptCont(t, pos);
-            F.at(pos);
+
+            JCExpression orig = t;
+            t = bracketsOptCont(t, pos, nextLevelAnnotations);
+        } else if (!nextLevelAnnotations.isEmpty()) {
+            if (permitTypeAnnotationsPushBack) {
+                this.typeAnnotationsPushedBack = nextLevelAnnotations;
+            } else
+                return illegal(nextLevelAnnotations.head.pos);
         }
+
+        int apos = S.pos();
+        if (!annotations.isEmpty())
+            t = F.at(apos).AnnotatedType(annotations, t);
         return t;
     }
 
-    private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) {
+    /** BracketsOpt = {"[" TypeAnnotations "]"}
+     */
+    private JCExpression bracketsOpt(JCExpression t) {
+        return bracketsOpt(t, List.<JCTypeAnnotation>nil());
+    }
+
+    private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
+            List<JCTypeAnnotation> annotations) {
         accept(RBRACKET);
-        t = bracketsOpt(t);
+        t = bracketsOpt(t, annotations);
         return toP(F.at(pos).TypeArray(t));
     }
 
@@ -1316,18 +1474,29 @@
         return t;
     }
 
-    /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
+    /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
      */
     JCExpression creator(int newpos, List<JCExpression> typeArgs) {
+
+        List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
+
         switch (S.token()) {
         case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
         case DOUBLE: case BOOLEAN:
-            if (typeArgs == null)
-                return arrayCreatorRest(newpos, basicType());
+            if (typeArgs == null) {
+                if (newAnnotations.isEmpty())
+                    return arrayCreatorRest(newpos, basicType());
+                else
+                    return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
+            }
             break;
         default:
         }
         JCExpression t = qualident();
+        // handle type annotations for non primitive arrays
+        if (!newAnnotations.isEmpty())
+            t = F.AnnotatedType(newAnnotations, t);
+
         int oldmode = mode;
         mode = TYPE;
         if (S.token() == LT) {
@@ -1344,7 +1513,7 @@
             }
         }
         mode = oldmode;
-        if (S.token() == LBRACKET) {
+        if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
             JCExpression e = arrayCreatorRest(newpos, t);
             if (typeArgs != null) {
                 int pos = newpos;
@@ -1360,7 +1529,12 @@
             }
             return e;
         } else if (S.token() == LPAREN) {
-            return classCreatorRest(newpos, null, typeArgs, t);
+            JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
+            if (newClass.def != null) {
+                assert newClass.def.mods.annotations.isEmpty();
+                newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
+            }
+            return newClass;
         } else {
             reportSyntaxError(S.pos(), "expected2",
                                LPAREN, LBRACKET);
@@ -1380,40 +1554,73 @@
         return classCreatorRest(newpos, encl, typeArgs, t);
     }
 
-    /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer
-     *                         | Expression "]" {"[" Expression "]"} BracketsOpt )
+    /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
+     *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
      */
     JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
+
+        List<JCTypeAnnotation> topAnnos = List.nil();
+        if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
+            JCAnnotatedType atype = (JCAnnotatedType) elemtype;
+            topAnnos = atype.annotations;
+            elemtype = atype.underlyingType;
+        }
+
+        List<JCTypeAnnotation> annos = typeAnnotationsOpt();
+
         accept(LBRACKET);
+
         if (S.token() == RBRACKET) {
             accept(RBRACKET);
-            elemtype = bracketsOpt(elemtype);
+
+            elemtype = bracketsOpt(elemtype, annos);
+
             if (S.token() == LBRACE) {
-                return arrayInitializer(newpos, elemtype);
+                JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
+
+                na.annotations = topAnnos;
+
+                return na;
             } else {
                 return syntaxError(S.pos(), "array.dimension.missing");
             }
         } else {
             ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
+
+            // maintain array dimension type annotations
+            ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
+            dimAnnotations.append(annos);
+
             dims.append(parseExpression());
             accept(RBRACKET);
-            while (S.token() == LBRACKET) {
+            while (S.token() == LBRACKET
+                    || (S.token() == MONKEYS_AT)) {
+                List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
                 int pos = S.pos();
                 S.nextToken();
                 if (S.token() == RBRACKET) {
-                    elemtype = bracketsOptCont(elemtype, pos);
+                    elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
                 } else {
-                    dims.append(parseExpression());
-                    accept(RBRACKET);
+                    if (S.token() == RBRACKET) { // no dimension
+                        elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
+                    } else {
+                        dimAnnotations.append(maybeDimAnnos);
+                        dims.append(parseExpression());
+                        accept(RBRACKET);
+                    }
                 }
             }
-            return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
+
+            JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
+            na.annotations = topAnnos;
+            na.dimAnnotations = dimAnnotations.toList();
+            return na;
         }
     }
 
     /** ClassCreatorRest = Arguments [ClassBody]
      */
-    JCExpression classCreatorRest(int newpos,
+    JCNewClass classCreatorRest(int newpos,
                                   JCExpression encl,
                                   List<JCExpression> typeArgs,
                                   JCExpression t)
@@ -1860,17 +2067,32 @@
                                         new ListBuffer<JCExpressionStatement>()).toList();
     }
 
+    enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
+
     /** AnnotationsOpt = { '@' Annotation }
      */
-    List<JCAnnotation> annotationsOpt() {
+    List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
         if (S.token() != MONKEYS_AT) return List.nil(); // optimization
         ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
+        int prevmode = mode;
         while (S.token() == MONKEYS_AT) {
             int pos = S.pos();
             S.nextToken();
-            buf.append(annotation(pos));
+            buf.append(annotation(pos, kind));
         }
-        return buf.toList();
+        lastmode = mode;
+        mode = prevmode;
+        List<JCAnnotation> annotations = buf.toList();
+
+        if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
+            System.out.println("TA: parsing " + annotations
+                    + " in " + log.currentSourceFile());
+        return annotations;
+    }
+
+    List<JCTypeAnnotation> typeAnnotationsOpt() {
+        List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
+        return List.convert(JCTypeAnnotation.class, annotations);
     }
 
     /** ModifiersOpt = { Modifier }
@@ -1915,7 +2137,7 @@
             if (flag == Flags.ANNOTATION) {
                 checkAnnotations();
                 if (S.token() != INTERFACE) {
-                JCAnnotation ann = annotation(lastPos);
+                JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
                 // if first modifier is an annotation, set pos to annotation's.
                 if (flags == 0 && annotations.isEmpty())
                     pos = ann.pos;
@@ -1946,12 +2168,18 @@
     /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
      * @param pos position of "@" token
      */
-    JCAnnotation annotation(int pos) {
+    JCAnnotation annotation(int pos, AnnotationKind kind) {
         // accept(AT); // AT consumed by caller
         checkAnnotations();
+        if (kind == AnnotationKind.TYPE_ANNO)
+            checkTypeAnnotations();
         JCTree ident = qualident();
         List<JCExpression> fieldValues = annotationFieldValuesOpt();
-        JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
+        JCAnnotation ann;
+        if (kind == AnnotationKind.DEFAULT_ANNO)
+            ann = F.at(pos).Annotation(ident, fieldValues);
+        else
+            ann = F.at(pos).TypeAnnotation(ident, fieldValues);
         storeEnd(ann, S.prevEndPos());
         return ann;
     }
@@ -2003,7 +2231,7 @@
         case MONKEYS_AT:
             pos = S.pos();
             S.nextToken();
-            return annotation(pos);
+            return annotation(pos, AnnotationKind.DEFAULT_ANNO);
         case LBRACE:
             pos = S.pos();
             accept(LBRACE);
@@ -2357,7 +2585,7 @@
             S.resetDeprecatedFlag();
         }
         int pos = S.pos();
-        List<JCAnnotation> annotations = annotationsOpt();
+        List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
         JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
         List<JCExpression> typeArgs = typeArgumentsOpt();
         int identPos = S.pos();
@@ -2460,16 +2688,23 @@
                 if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
                     mods.pos = pos;
                 }
+
+                List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
+
                 Token token = S.token();
                 Name name = S.name();
                 pos = S.pos();
                 JCExpression type;
                 boolean isVoid = S.token() == VOID;
                 if (isVoid) {
+                    if (annosAfterParams.nonEmpty())
+                        illegal(annosAfterParams.head.pos);
                     type = to(F.at(pos).TypeIdent(TypeTags.VOID));
                     S.nextToken();
                 } else {
-                    type = parseType();
+                    mods.annotations = mods.annotations.appendList(annosAfterParams);
+                    // method returns types are un-annotated types
+                    type = unannotatedType();
                 }
                 if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
                     if (isInterface || name != className)
@@ -2505,15 +2740,15 @@
     }
 
     /** MethodDeclaratorRest =
-     *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
+     *      FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
      *  VoidMethodDeclaratorRest =
-     *      FormalParameters [Throws TypeList] ( MethodBody | ";")
+     *      FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
      *  InterfaceMethodDeclaratorRest =
-     *      FormalParameters BracketsOpt [THROWS TypeList] ";"
+     *      FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
      *  VoidInterfaceMethodDeclaratorRest =
-     *      FormalParameters [THROWS TypeList] ";"
+     *      FormalParameters [Annotations] [THROWS TypeList] ";"
      *  ConstructorDeclaratorRest =
-     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
+     *      "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
      */
     JCTree methodDeclaratorRest(int pos,
                               JCModifiers mods,
@@ -2523,7 +2758,22 @@
                               boolean isInterface, boolean isVoid,
                               String dc) {
         List<JCVariableDecl> params = formalParameters();
-        if (!isVoid) type = bracketsOpt(type);
+
+        List<JCTypeAnnotation> receiverAnnotations;
+        if (!isVoid) {
+            // need to distinguish between receiver anno and array anno
+            // look at typeAnnotationsPushedBack comment
+            this.permitTypeAnnotationsPushBack = true;
+            type = methodReturnArrayRest(type);
+            this.permitTypeAnnotationsPushBack = false;
+            if (typeAnnotationsPushedBack == null)
+                receiverAnnotations = List.nil();
+            else
+                receiverAnnotations = typeAnnotationsPushedBack;
+            typeAnnotationsPushedBack = null;
+        } else
+            receiverAnnotations = typeAnnotationsOpt();
+
         List<JCExpression> thrown = List.nil();
         if (S.token() == THROWS) {
             S.nextToken();
@@ -2552,20 +2802,51 @@
         }
         JCMethodDecl result =
             toP(F.at(pos).MethodDef(mods, name, type, typarams,
-                                    params, thrown,
+                                    params, receiverAnnotations, thrown,
                                     body, defaultValue));
         attach(result, dc);
         return result;
     }
 
-    /** QualidentList = Qualident {"," Qualident}
+    /** Parses the array levels after the format parameters list, and append
+     * them to the return type, while preseving the order of type annotations
+     */
+    private JCExpression methodReturnArrayRest(JCExpression type) {
+        if (type.getTag() != JCTree.TYPEARRAY)
+            return bracketsOpt(type);
+
+        JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
+        while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
+            baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
+
+        if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
+            JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
+            at.underlyingType = bracketsOpt(at.underlyingType);
+        } else {
+            baseArray.elemtype = bracketsOpt(baseArray.elemtype);
+        }
+
+        return type;
+    }
+
+    /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
      */
     List<JCExpression> qualidentList() {
         ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
-        ts.append(qualident());
+
+        List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
+        if (!typeAnnos.isEmpty())
+            ts.append(F.AnnotatedType(typeAnnos, qualident()));
+        else
+            ts.append(qualident());
         while (S.token() == COMMA) {
             S.nextToken();
-            ts.append(qualident());
+
+            typeAnnos = typeAnnotationsOpt();
+            if (!typeAnnos.isEmpty())
+                ts.append(F.AnnotatedType(typeAnnos, qualident()));
+            else
+                ts.append(qualident());
         }
         return ts.toList();
     }
@@ -2589,12 +2870,13 @@
         }
     }
 
-    /** TypeParameter = TypeVariable [TypeParameterBound]
+    /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
      *  TypeParameterBound = EXTENDS Type {"&" Type}
      *  TypeVariable = Ident
      */
     JCTypeParameter typeParameter() {
         int pos = S.pos();
+        List<JCTypeAnnotation> annos = typeAnnotationsOpt();
         Name name = ident();
         ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
         if (S.token() == EXTENDS) {
@@ -2605,7 +2887,7 @@
                 bounds.append(parseType());
             }
         }
-        return toP(F.at(pos).TypeParameter(name, bounds.toList()));
+        return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
     }
 
     /** FormalParameters = "(" [ FormalParameterList ] ")"
@@ -2639,12 +2921,31 @@
      */
     JCVariableDecl formalParameter() {
         JCModifiers mods = optFinal(Flags.PARAMETER);
+        // need to distinguish between vararg annos and array annos
+        // look at typeAnnotaitonsPushedBack comment
+        this.permitTypeAnnotationsPushBack = true;
         JCExpression type = parseType();
+        this.permitTypeAnnotationsPushBack = false;
+
         if (S.token() == ELLIPSIS) {
+            List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
+            typeAnnotationsPushedBack = null;
             checkVarargs();
             mods.flags |= Flags.VARARGS;
+            // insert var arg type annotations
+            if (varargsAnnos != null && varargsAnnos.nonEmpty())
+                type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
             type = to(F.at(S.pos()).TypeArray(type));
+
             S.nextToken();
+        } else {
+            // if not a var arg, then typeAnnotationsPushedBack should be null
+            if (typeAnnotationsPushedBack != null
+                    && !typeAnnotationsPushedBack.isEmpty()) {
+                reportSyntaxError(typeAnnotationsPushedBack.head.pos,
+                        "illegal.start.of.type");
+            }
+            typeAnnotationsPushedBack = null;
         }
         return variableDeclaratorId(mods, type);
     }
@@ -2829,4 +3130,10 @@
             allowAnnotations = true;
         }
     }
+    void checkTypeAnnotations() {
+        if (!allowTypeAnnotations) {
+            log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
+            allowTypeAnnotations = true;
+        }
+    }
 }
--- a/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/processing/JavacProcessingEnvironment.java	Fri Jun 26 18:51:39 2009 -0700
@@ -921,6 +921,8 @@
         } else { // Final compilation
             compiler.close(false);
             currentContext = contextForNextRound(currentContext, true);
+            this.context = currentContext;
+            updateProcessingState(currentContext, true);
             compiler = JavaCompiler.instance(currentContext);
 
             if (true) {
@@ -1213,6 +1215,10 @@
                 node.sym = null;
                 super.visitIdent(node);
             }
+            public void visitApply(JCMethodInvocation node) {
+                scan(node.typeargs);
+                super.visitApply(node);
+            }
         };
 
 
--- a/src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/processing/JavacRoundEnvironment.java	Fri Jun 26 18:51:39 2009 -0700
@@ -105,6 +105,9 @@
      * elements are {@linkplain #getSpecifiedTypeElements specified
      * types} and any types nested within them.
      *
+     * <p>This method will not return type annotations, which annotate
+     * types, not elements.
+     *
      * @param a  annotation type being requested
      * @return the elements annotated with the given annotation type,
      * or an empty set if there are none
--- a/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/resources/compiler.properties	Fri Jun 26 18:51:39 2009 -0700
@@ -882,6 +882,8 @@
     bad constant pool tag: {0} at {1}
 compiler.misc.bad.signature=\
     bad signature: {0}
+compiler.misc.bad.type.annotation.value=\
+    bad type annotation target type value: {0}
 compiler.misc.class.file.wrong.class=\
     class file contains wrong class: {0}
 compiler.misc.class.file.not.found=\
@@ -1162,6 +1164,10 @@
     annotations are not supported in -source {0}\n\
 (use -source 5 or higher to enable annotations)
 
+compiler.err.type.annotations.not.supported.in.source=\
+    type annotations are not supported in -source {0}\n\
+(use -source 7 or higher to enable type annotations)
+
 compiler.err.foreach.not.supported.in.source=\
     for-each loops are not supported in -source {0}\n\
 (use -source 5 or higher to enable for-each loops)
--- a/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/JCTree.java	Fri Jun 26 18:51:39 2009 -0700
@@ -256,9 +256,11 @@
      */
     public static final int MODIFIERS = ANNOTATION + 1;
 
+    public static final int ANNOTATED_TYPE = MODIFIERS + 1;
+
     /** Error trees, of type Erroneous.
      */
-    public static final int ERRONEOUS = MODIFIERS + 1;
+    public static final int ERRONEOUS = ANNOTATED_TYPE + 1;
 
     /** Unary operators, of type Unary.
      */
@@ -622,6 +624,7 @@
         public JCExpression restype;
         public List<JCTypeParameter> typarams;
         public List<JCVariableDecl> params;
+        public List<JCTypeAnnotation> receiverAnnotations;
         public List<JCExpression> thrown;
         public JCBlock body;
         public JCExpression defaultValue; // for annotation types
@@ -631,6 +634,7 @@
                             JCExpression restype,
                             List<JCTypeParameter> typarams,
                             List<JCVariableDecl> params,
+                            List<JCTypeAnnotation> receiver,
                             List<JCExpression> thrown,
                             JCBlock body,
                             JCExpression defaultValue,
@@ -641,6 +645,7 @@
             this.restype = restype;
             this.typarams = typarams;
             this.params = params;
+            this.receiverAnnotations = (receiver != null ? receiver : List.<JCTypeAnnotation>nil());
             this.thrown = thrown;
             this.body = body;
             this.defaultValue = defaultValue;
@@ -659,6 +664,7 @@
         public List<JCVariableDecl> getParameters() {
             return params;
         }
+        public List<JCTypeAnnotation> getReceiverAnnotations() { return receiverAnnotations; }
         public List<JCExpression> getThrows() {
             return thrown;
         }
@@ -1371,6 +1377,8 @@
     public static class JCNewArray extends JCExpression implements NewArrayTree {
         public JCExpression elemtype;
         public List<JCExpression> dims;
+        public List<JCTypeAnnotation> annotations;
+        public List<List<JCTypeAnnotation>> dimAnnotations;
         public List<JCExpression> elems;
         protected JCNewArray(JCExpression elemtype,
                            List<JCExpression> dims,
@@ -1378,6 +1386,8 @@
         {
             this.elemtype = elemtype;
             this.dims = dims;
+            this.annotations = List.nil();
+            this.dimAnnotations = List.nil();
             this.elems = elems;
         }
         @Override
@@ -1860,9 +1870,11 @@
     public static class JCTypeParameter extends JCTree implements TypeParameterTree {
         public Name name;
         public List<JCExpression> bounds;
-        protected JCTypeParameter(Name name, List<JCExpression> bounds) {
+        public List<JCTypeAnnotation> annotations;
+        protected JCTypeParameter(Name name, List<JCExpression> bounds, List<JCTypeAnnotation> annotations) {
             this.name = name;
             this.bounds = bounds;
+            this.annotations = annotations;
         }
         @Override
         public void accept(Visitor v) { v.visitTypeParameter(this); }
@@ -1872,6 +1884,9 @@
         public List<JCExpression> getBounds() {
             return bounds;
         }
+        public List<JCTypeAnnotation> getAnnotations() {
+            return annotations;
+        }
         @Override
         public <R,D> R accept(TreeVisitor<R,D> v, D d) {
             return v.visitTypeParameter(this, d);
@@ -1962,6 +1977,16 @@
         }
     }
 
+    public static class JCTypeAnnotation extends JCAnnotation {
+        public TypeAnnotationPosition annotation_position;
+        public Attribute.TypeCompound attribute_field;
+
+        protected JCTypeAnnotation(JCTree annotationType, List<JCExpression> args) {
+            super(annotationType, args);
+            this.annotation_position = new TypeAnnotationPosition();
+        }
+    }
+
     public static class JCModifiers extends JCTree implements com.sun.source.tree.ModifiersTree {
         public long flags;
         public List<JCAnnotation> annotations;
@@ -1989,6 +2014,33 @@
         }
     }
 
+    public static class JCAnnotatedType extends JCExpression implements com.sun.source.tree.AnnotatedTypeTree {
+        public List<JCTypeAnnotation> annotations;
+        public JCExpression underlyingType;
+        protected JCAnnotatedType(List<JCTypeAnnotation> annotations, JCExpression underlyingType) {
+            this.annotations = annotations;
+            this.underlyingType = underlyingType;
+        }
+        @Override
+        public void accept(Visitor v) { v.visitAnnotatedType(this); }
+
+        public Kind getKind() { return Kind.ANNOTATED_TYPE; }
+        public List<JCTypeAnnotation> getAnnotations() {
+            return annotations;
+        }
+        public JCExpression getUnderlyingType() {
+            return underlyingType;
+        }
+        @Override
+        public <R,D> R accept(TreeVisitor<R,D> v, D d) {
+            return v.visitAnnotatedType(this, d);
+        }
+        @Override
+        public int getTag() {
+            return ANNOTATED_TYPE;
+        }
+    }
+
     public static class JCErroneous extends JCExpression
             implements com.sun.source.tree.ErroneousTree {
         public List<? extends JCTree> errs;
@@ -2056,6 +2108,7 @@
                             JCExpression restype,
                             List<JCTypeParameter> typarams,
                             List<JCVariableDecl> params,
+                            List<JCTypeAnnotation> receiver,
                             List<JCExpression> thrown,
                             JCBlock body,
                             JCExpression defaultValue);
@@ -2172,6 +2225,7 @@
         public void visitTypeBoundKind(TypeBoundKind that)   { visitTree(that); }
         public void visitAnnotation(JCAnnotation that)       { visitTree(that); }
         public void visitModifiers(JCModifiers that)         { visitTree(that); }
+        public void visitAnnotatedType(JCAnnotatedType that) { visitTree(that); }
         public void visitErroneous(JCErroneous that)         { visitTree(that); }
         public void visitLetExpr(LetExpr that)               { visitTree(that); }
 
--- a/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/Pretty.java	Fri Jun 26 18:51:39 2009 -0700
@@ -224,6 +224,15 @@
         }
     }
 
+    public void printTypeAnnotations(List<JCTypeAnnotation> trees) throws IOException {
+        if (trees.nonEmpty())
+            print(" ");
+        for (List<JCTypeAnnotation> l = trees; l.nonEmpty(); l = l.tail) {
+            printExpr(l.head);
+            print(" ");
+        }
+    }
+
     /** Print documentation comment, if it exists
      *  @param tree    The tree for which a documentation comment should be printed.
      */
@@ -850,21 +859,33 @@
         try {
             if (tree.elemtype != null) {
                 print("new ");
+                printTypeAnnotations(tree.annotations);
                 JCTree elem = tree.elemtype;
-                if (elem instanceof JCArrayTypeTree)
-                    printBaseElementType((JCArrayTypeTree) elem);
-                else
-                    printExpr(elem);
+                printBaseElementType(elem);
+                boolean isElemAnnoType = elem instanceof JCAnnotatedType;
+                int i = 0;
+                List<List<JCTypeAnnotation>> da = tree.dimAnnotations;
                 for (List<JCExpression> l = tree.dims; l.nonEmpty(); l = l.tail) {
+                    if (da.size() > i) {
+                        printTypeAnnotations(da.get(i));
+                    }
                     print("[");
+                    i++;
                     printExpr(l.head);
                     print("]");
                 }
+                if (tree.elems != null) {
+                    if (isElemAnnoType) {
+                        printTypeAnnotations(((JCAnnotatedType)tree.elemtype).annotations);
+                    }
+                    print("[]");
+                }
+                if (isElemAnnoType)
+                    elem = ((JCAnnotatedType)elem).underlyingType;
                 if (elem instanceof JCArrayTypeTree)
                     printBrackets((JCArrayTypeTree) elem);
             }
             if (tree.elems != null) {
-                if (tree.elemtype != null) print("[]");
                 print("{");
                 printExprs(tree.elems);
                 print("}");
@@ -1112,14 +1133,21 @@
     }
 
     // Prints the inner element type of a nested array
-    private void printBaseElementType(JCArrayTypeTree tree) throws IOException {
-        JCTree elem = tree.elemtype;
-        while (elem instanceof JCWildcard)
-            elem = ((JCWildcard) elem).inner;
-        if (elem instanceof JCArrayTypeTree)
-            printBaseElementType((JCArrayTypeTree) elem);
-        else
-            printExpr(elem);
+    private void printBaseElementType(JCTree tree) throws IOException {
+        switch (tree.getTag()) {
+        case JCTree.TYPEARRAY:
+            printBaseElementType(((JCArrayTypeTree)tree).elemtype);
+            return;
+        case JCTree.WILDCARD:
+            printBaseElementType(((JCWildcard)tree).inner);
+            return;
+        case JCTree.ANNOTATED_TYPE:
+            printBaseElementType(((JCAnnotatedType)tree).underlyingType);
+            return;
+        default:
+            printExpr(tree);
+            return;
+        }
     }
 
     // prints the brackets of a nested array in reverse order
@@ -1127,8 +1155,13 @@
         JCTree elem;
         while (true) {
             elem = tree.elemtype;
+            if (elem.getTag() == JCTree.ANNOTATED_TYPE) {
+                JCAnnotatedType atype = (JCAnnotatedType) elem;
+                printTypeAnnotations(atype.annotations);
+                elem = atype.underlyingType;
+            }
             print("[]");
-            if (!(elem instanceof JCArrayTypeTree)) break;
+            if (elem.getTag() != JCTree.TYPEARRAY) break;
             tree = (JCArrayTypeTree) elem;
         }
     }
@@ -1213,6 +1246,15 @@
         }
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        try {
+            printTypeAnnotations(tree.annotations);
+            printExpr(tree.underlyingType);
+        } catch (IOException e) {
+            throw new UncheckedIOException(e);
+        }
+    }
+
     public void visitTree(JCTree tree) {
         try {
             print("(UNKNOWN: " + tree + ")");
@@ -1221,4 +1263,5 @@
             throw new UncheckedIOException(e);
         }
     }
+
 }
--- a/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeCopier.java	Fri Jun 26 18:51:39 2009 -0700
@@ -71,6 +71,13 @@
         return lb.toList();
     }
 
+    public JCTree visitAnnotatedType(AnnotatedTypeTree node, P p) {
+        JCAnnotatedType t = (JCAnnotatedType) node;
+        List<JCTypeAnnotation> annotations = copy(t.annotations, p);
+        JCExpression underlyingType = copy(t.underlyingType, p);
+        return M.at(t.pos).AnnotatedType(annotations, underlyingType);
+    }
+
     public JCTree visitAnnotation(AnnotationTree node, P p) {
         JCAnnotation t = (JCAnnotation) node;
         JCTree annotationType = copy(t.annotationType, p);
@@ -233,10 +240,11 @@
         JCExpression restype = copy(t.restype, p);
         List<JCTypeParameter> typarams = copy(t.typarams, p);
         List<JCVariableDecl> params = copy(t.params, p);
+        List<JCTypeAnnotation> receiver = copy(t.receiverAnnotations, p);
         List<JCExpression> thrown = copy(t.thrown, p);
         JCBlock body = copy(t.body, p);
         JCExpression defaultValue = copy(t.defaultValue, p);
-        return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, thrown, body, defaultValue);
+        return M.at(t.pos).MethodDef(mods, t.name, restype, typarams, params, receiver, thrown, body, defaultValue);
     }
 
     public JCTree visitMethodInvocation(MethodInvocationTree node, P p) {
@@ -357,8 +365,9 @@
 
     public JCTree visitTypeParameter(TypeParameterTree node, P p) {
         JCTypeParameter t = (JCTypeParameter) node;
+        List<JCTypeAnnotation> annos = copy(t.annotations, p);
         List<JCExpression> bounds = copy(t.bounds, p);
-        return M.at(t.pos).TypeParameter(t.name, t.bounds);
+        return M.at(t.pos).TypeParameter(t.name, bounds, annos);
     }
 
     public JCTree visitInstanceOf(InstanceOfTree node, P p) {
--- a/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeInfo.java	Fri Jun 26 18:51:39 2009 -0700
@@ -298,6 +298,8 @@
         case(JCTree.POSTINC):
         case(JCTree.POSTDEC):
             return getStartPos(((JCUnary) tree).arg);
+        case(JCTree.ANNOTATED_TYPE):
+            return getStartPos(((JCAnnotatedType) tree).underlyingType);
         case(JCTree.VARDEF): {
             JCVariableDecl node = (JCVariableDecl)tree;
             if (node.mods.pos != Position.NOPOS) {
@@ -859,4 +861,25 @@
             return null;
         }
     }
+
+    /**
+     * Returns the underlying type of the tree if it is annotated type,
+     * or the tree itself otherwise
+     */
+    public static JCExpression typeIn(JCExpression tree) {
+        switch (tree.getTag()) {
+        case JCTree.ANNOTATED_TYPE:
+            return ((JCAnnotatedType)tree).underlyingType;
+        case JCTree.IDENT: /* simple names */
+        case JCTree.TYPEIDENT: /* primitive name */
+        case JCTree.SELECT: /* qualified name */
+        case JCTree.TYPEARRAY: /* array types */
+        case JCTree.WILDCARD: /* wild cards */
+        case JCTree.TYPEPARAMETER: /* type parameters */
+        case JCTree.TYPEAPPLY: /* parameterized types */
+            return tree;
+        default:
+            throw new AssertionError("Unexpected type tree: " + tree);
+        }
+    }
 }
--- a/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeMaker.java	Fri Jun 26 18:51:39 2009 -0700
@@ -168,6 +168,20 @@
                                List<JCVariableDecl> params,
                                List<JCExpression> thrown,
                                JCBlock body,
+                               JCExpression defaultValue) {
+        return MethodDef(
+                mods, name, restype, typarams, params,
+                null, thrown, body, defaultValue);
+    }
+
+    public JCMethodDecl MethodDef(JCModifiers mods,
+                               Name name,
+                               JCExpression restype,
+                               List<JCTypeParameter> typarams,
+                               List<JCVariableDecl> params,
+                               List<JCTypeAnnotation> receiver,
+                               List<JCExpression> thrown,
+                               JCBlock body,
                                JCExpression defaultValue)
     {
         JCMethodDecl tree = new JCMethodDecl(mods,
@@ -175,6 +189,7 @@
                                        restype,
                                        typarams,
                                        params,
+                                       receiver,
                                        thrown,
                                        body,
                                        defaultValue,
@@ -430,7 +445,11 @@
     }
 
     public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds) {
-        JCTypeParameter tree = new JCTypeParameter(name, bounds);
+        return TypeParameter(name, bounds, List.<JCTypeAnnotation>nil());
+    }
+
+    public JCTypeParameter TypeParameter(Name name, List<JCExpression> bounds, List<JCTypeAnnotation> annos) {
+        JCTypeParameter tree = new JCTypeParameter(name, bounds, annos);
         tree.pos = pos;
         return tree;
     }
@@ -453,6 +472,12 @@
         return tree;
     }
 
+    public JCTypeAnnotation TypeAnnotation(JCTree annotationType, List<JCExpression> args) {
+        JCTypeAnnotation tree = new JCTypeAnnotation(annotationType, args);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCModifiers Modifiers(long flags, List<JCAnnotation> annotations) {
         JCModifiers tree = new JCModifiers(flags, annotations);
         boolean noFlags = (flags & Flags.StandardFlags) == 0;
@@ -464,6 +489,12 @@
         return Modifiers(flags, List.<JCAnnotation>nil());
     }
 
+    public JCAnnotatedType AnnotatedType(List<JCTypeAnnotation> annotations, JCExpression underlyingType) {
+        JCAnnotatedType tree = new JCAnnotatedType(annotations, underlyingType);
+        tree.pos = pos;
+        return tree;
+    }
+
     public JCErroneous Erroneous() {
         return Erroneous(List.<JCTree>nil());
     }
@@ -772,6 +803,7 @@
                 Type(mtype.getReturnType()),
                 TypeParams(mtype.getTypeArguments()),
                 Params(mtype.getParameterTypes(), m),
+                null,
                 Types(mtype.getThrownTypes()),
                 body,
                 null,
--- a/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeScanner.java	Fri Jun 26 18:51:39 2009 -0700
@@ -85,6 +85,7 @@
         scan(tree.restype);
         scan(tree.typarams);
         scan(tree.params);
+        scan(tree.receiverAnnotations);
         scan(tree.thrown);
         scan(tree.defaultValue);
         scan(tree.body);
@@ -204,8 +205,11 @@
     }
 
     public void visitNewArray(JCNewArray tree) {
+        scan(tree.annotations);
         scan(tree.elemtype);
         scan(tree.dims);
+        for (List<JCTypeAnnotation> annos : tree.dimAnnotations)
+            scan(annos);
         scan(tree.elems);
     }
 
@@ -270,6 +274,7 @@
     }
 
     public void visitTypeParameter(JCTypeParameter tree) {
+        scan(tree.annotations);
         scan(tree.bounds);
     }
 
@@ -293,6 +298,11 @@
         scan(tree.args);
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        scan(tree.annotations);
+        scan(tree.underlyingType);
+    }
+
     public void visitErroneous(JCErroneous tree) {
     }
 
--- a/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/tree/TreeTranslator.java	Fri Jun 26 18:51:39 2009 -0700
@@ -282,6 +282,11 @@
     }
 
     public void visitNewArray(JCNewArray tree) {
+        tree.annotations = translate(tree.annotations);
+        List<List<JCTypeAnnotation>> dimAnnos = List.nil();
+        for (List<JCTypeAnnotation> origDimAnnos : tree.dimAnnotations)
+            dimAnnos = dimAnnos.append(translate(origDimAnnos));
+        tree.dimAnnotations = dimAnnos;
         tree.elemtype = translate(tree.elemtype);
         tree.dims = translate(tree.dims);
         tree.elems = translate(tree.elems);
@@ -363,6 +368,7 @@
     }
 
     public void visitTypeParameter(JCTypeParameter tree) {
+        tree.annotations = translate(tree.annotations);
         tree.bounds = translate(tree.bounds);
         result = tree;
     }
@@ -400,6 +406,12 @@
         result = tree;
     }
 
+    public void visitAnnotatedType(JCAnnotatedType tree) {
+        tree.annotations = translate(tree.annotations);
+        tree.underlyingType = translate(tree.underlyingType);
+        result = tree;
+    }
+
     public void visitTree(JCTree tree) {
         throw new AssertionError(tree);
     }
--- a/src/share/classes/com/sun/tools/javac/util/Names.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javac/util/Names.java	Fri Jun 26 18:51:39 2009 -0700
@@ -99,6 +99,8 @@
     public final Name Annotation;
     public final Name RuntimeVisibleAnnotations;
     public final Name RuntimeInvisibleAnnotations;
+    public final Name RuntimeVisibleTypeAnnotations;
+    public final Name RuntimeInvisibleTypeAnnotations;
     public final Name RuntimeVisibleParameterAnnotations;
     public final Name RuntimeInvisibleParameterAnnotations;
     public final Name Value;
@@ -115,6 +117,8 @@
     public final Name getClass;
     public final Name invoke;
     public final Name TYPE;
+    public final Name TYPE_USE;
+    public final Name TYPE_PARAMETER;
     public final Name FIELD;
     public final Name METHOD;
     public final Name PARAMETER;
@@ -205,6 +209,8 @@
         Annotation = fromString("Annotation");
         RuntimeVisibleAnnotations = fromString("RuntimeVisibleAnnotations");
         RuntimeInvisibleAnnotations = fromString("RuntimeInvisibleAnnotations");
+        RuntimeVisibleTypeAnnotations = fromString("RuntimeVisibleTypeAnnotations");
+        RuntimeInvisibleTypeAnnotations = fromString("RuntimeInvisibleTypeAnnotations");
         RuntimeVisibleParameterAnnotations = fromString("RuntimeVisibleParameterAnnotations");
         RuntimeInvisibleParameterAnnotations = fromString("RuntimeInvisibleParameterAnnotations");
         Value = fromString("Value");
@@ -224,6 +230,8 @@
         invoke = fromString("invoke");
 
         TYPE = fromString("TYPE");
+        TYPE_USE = fromString("TYPE_USE");
+        TYPE_PARAMETER = fromString("TYPE_PARAMETER");
         FIELD = fromString("FIELD");
         METHOD = fromString("METHOD");
         PARAMETER = fromString("PARAMETER");
--- a/src/share/classes/com/sun/tools/javap/AnnotationWriter.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/AnnotationWriter.java	Fri Jun 26 18:51:39 2009 -0700
@@ -26,6 +26,7 @@
 package com.sun.tools.javap;
 
 import com.sun.tools.classfile.Annotation;
+import com.sun.tools.classfile.ExtendedAnnotation;
 import com.sun.tools.classfile.Annotation.Annotation_element_value;
 import com.sun.tools.classfile.Annotation.Array_element_value;
 import com.sun.tools.classfile.Annotation.Class_element_value;
@@ -62,6 +63,12 @@
         print(")");
     }
 
+    public void write(ExtendedAnnotation annot) {
+        write(annot.annotation);
+        print('@');
+        print(annot.position.toString());
+    }
+
     public void write(Annotation.element_value_pair pair) {
         print("#" + pair.element_name_index + ":");
         write(pair.value);
--- a/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/src/share/classes/com/sun/tools/javap/AttributeWriter.java	Fri Jun 26 18:51:39 2009 -0700
@@ -51,8 +51,10 @@
 import com.sun.tools.classfile.Module_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeInvisibleParameterAnnotations_attribute;
+import com.sun.tools.classfile.RuntimeInvisibleTypeAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeVisibleAnnotations_attribute;
 import com.sun.tools.classfile.RuntimeVisibleParameterAnnotations_attribute;
+import com.sun.tools.classfile.RuntimeVisibleTypeAnnotations_attribute;
 import com.sun.tools.classfile.Signature_attribute;
 import com.sun.tools.classfile.SourceDebugExtension_attribute;
 import com.sun.tools.classfile.SourceFile_attribute;
@@ -434,6 +436,26 @@
         return null;
     }
 
+    public Void visitRuntimeVisibleTypeAnnotations(RuntimeVisibleTypeAnnotations_attribute attr, Void ignore) {
+        println("  RuntimeVisibleTypeAnnotations: ");
+        for (int i = 0; i < attr.annotations.length; i++) {
+            print("    " + i + ": ");
+            annotationWriter.write(attr.annotations[i]);
+            println();
+        }
+        return null;
+    }
+
+    public Void visitRuntimeInvisibleTypeAnnotations(RuntimeInvisibleTypeAnnotations_attribute attr, Void ignore) {
+        println("  RuntimeInvisibleTypeAnnotations: ");
+        for (int i = 0; i < attr.annotations.length; i++) {
+            print("    " + i + ": ");
+            annotationWriter.write(attr.annotations[i]);
+            println();
+        }
+        return null;
+    }
+
     public Void visitRuntimeVisibleParameterAnnotations(RuntimeVisibleParameterAnnotations_attribute attr, Void ignore) {
         println("  RuntimeVisibleParameterAnnotations: ");
         for (int param = 0; param < attr.parameter_annotations.length; param++) {
--- a/test/tools/javac/6341866/T6341866.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/test/tools/javac/6341866/T6341866.java	Fri Jun 26 18:51:39 2009 -0700
@@ -97,7 +97,7 @@
         processorServices.delete();
 
         List<String> opts = new ArrayList<String>();
-        opts.addAll(Arrays.asList("-d", ".", "-sourcepath", testSrc, "-classpath", testClasses));
+        opts.addAll(Arrays.asList("-d", ".", "-sourcepath", testSrc, "-classpath", testClasses, "-source", "1.6"));
         if (implicitType.opt != null)
             opts.add(implicitType.opt);
 
--- a/test/tools/javac/processing/6348499/T6348499.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/test/tools/javac/processing/6348499/T6348499.java	Fri Jun 26 18:51:39 2009 -0700
@@ -54,6 +54,7 @@
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, "A.java")));
         Iterable<String> opts = Arrays.asList("-proc:only",
                                               "-processor", "A",
+                                              "-source", "1.6",
                                               "-processorpath", testClasses);
         StringWriter out = new StringWriter();
         JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
--- a/test/tools/javac/processing/6414633/T6414633.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/test/tools/javac/processing/6414633/T6414633.java	Fri Jun 26 18:51:39 2009 -0700
@@ -55,6 +55,7 @@
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, A.class.getName()+".java")));
         String[] opts = { "-proc:only",
                           "-processor", A.class.getName(),
+                          "-source", "1.6",
                           "-classpath", testClasses };
         JavacTask task = tool.getTask(null, fm, dl, Arrays.asList(opts), null, files);
         task.call();
--- a/test/tools/javac/processing/6430209/T6430209.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/test/tools/javac/processing/6430209/T6430209.java	Fri Jun 26 18:51:39 2009 -0700
@@ -63,6 +63,7 @@
             new File(testSrc, "test0.java"), new File(testSrc, "test1.java")));
         Iterable<String> opts = Arrays.asList("-proc:only",
                                               "-processor", "b6341534",
+                                              "-source", "1.6",
                                               "-processorpath", testClasses);
         StringWriter out = new StringWriter();
         JavacTask task = tool.getTask(out, fm, dl, opts, null, files);
--- a/test/tools/javac/processing/T6439826.java	Fri Jun 26 12:22:40 2009 -0700
+++ b/test/tools/javac/processing/T6439826.java	Fri Jun 26 18:51:39 2009 -0700
@@ -49,7 +49,8 @@
         StandardJavaFileManager fm = tool.getStandardFileManager(dl, null, null);
         Iterable<? extends JavaFileObject> files =
             fm.getJavaFileObjectsFromFiles(Arrays.asList(new File(testSrc, T6439826.class.getName()+".java")));
-        Iterable<String> opts = Arrays.asList("-proc:only",
+        Iterable<String> opts = Arrays.asList("-source","1.6",
+                                              "-proc:only",
                                               "-processor", "T6439826",
                                               "-processorpath", testClasses);
         StringWriter out = new StringWriter();