src/share/classes/com/sun/tools/javac/parser/JavacParser.java

changeset 308
03944ee4fac4
parent 267
e2722bd43f3a
child 310
7c154fdc3547
     1.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jun 26 12:22:40 2009 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Fri Jun 26 18:51:39 2009 -0700
     1.3 @@ -75,6 +75,42 @@
     1.4      /** The name table. */
     1.5      private Names names;
     1.6  
     1.7 +    // Because of javac's limited lookahead, some contexts are ambiguous in
     1.8 +    // the presence of type annotations even though they are not ambiguous
     1.9 +    // in the absence of type annotations.  Consider this code:
    1.10 +    //   void m(String [] m) { }
    1.11 +    //   void m(String ... m) { }
    1.12 +    // After parsing "String", javac calls bracketsOpt which immediately
    1.13 +    // returns if the next character is not '['.  Similarly, javac can see
    1.14 +    // if the next token is ... and in that case parse an ellipsis.  But in
    1.15 +    // the presence of type annotations:
    1.16 +    //   void m(String @A [] m) { }
    1.17 +    //   void m(String @A ... m) { }
    1.18 +    // no finite lookahead is enough to determine whether to read array
    1.19 +    // levels or an ellipsis.  Furthermore, if you call bracketsOpt, then
    1.20 +    // bracketsOpt first reads all the leading annotations and only then
    1.21 +    // discovers that it needs to fail.  bracketsOpt needs a way to push
    1.22 +    // back the extra annotations that it read.  (But, bracketsOpt should
    1.23 +    // not *always* be allowed to push back extra annotations that it finds
    1.24 +    // -- in most contexts, any such extra annotation is an error.
    1.25 +    // Another similar case occurs with arrays and receiver annotations:
    1.26 +    //   String b() @Array [] @Receiver { }
    1.27 +    //   String b() @Receiver { }
    1.28 +    //
    1.29 +    // The following two variables permit type annotations that have
    1.30 +    // already been read to be stored for later use.  Alternate
    1.31 +    // implementations are possible but would cause much larger changes to
    1.32 +    // the parser.
    1.33 +    /** Type annotations that have already been read but have not yet been used. **/
    1.34 +    private List<JCTypeAnnotation> typeAnnotationsPushedBack = null;
    1.35 +    /**
    1.36 +     * If the parser notices extra annotations, then it either immediately
    1.37 +     * issues an error (if this variable is false) or places the extra
    1.38 +     * annotations in variable typeAnnotationsPushedBack (if this variable
    1.39 +     * is true).
    1.40 +     */
    1.41 +    private boolean permitTypeAnnotationsPushBack = false;
    1.42 +
    1.43      /** Construct a parser from a given scanner, tree factory and log.
    1.44       */
    1.45      protected JavacParser(ParserFactory fac,
    1.46 @@ -95,13 +131,19 @@
    1.47          this.allowForeach = source.allowForeach();
    1.48          this.allowStaticImport = source.allowStaticImport();
    1.49          this.allowAnnotations = source.allowAnnotations();
    1.50 +        this.allowTypeAnnotations = source.allowTypeAnnotations();
    1.51          this.keepDocComments = keepDocComments;
    1.52          if (keepDocComments)
    1.53              docComments = new HashMap<JCTree,String>();
    1.54          this.keepLineMap = keepLineMap;
    1.55          this.errorTree = F.Erroneous();
    1.56 +        this.debugJSR308 = fac.options.get("TA:parser") != null;
    1.57      }
    1.58  
    1.59 +    /** Switch: debug output for type-annotations operations
    1.60 +     */
    1.61 +    boolean debugJSR308;
    1.62 +
    1.63      /** Switch: Should generics be recognized?
    1.64       */
    1.65      boolean allowGenerics;
    1.66 @@ -130,6 +172,10 @@
    1.67       */
    1.68      boolean allowAnnotations;
    1.69  
    1.70 +    /** Switch: should we recognize type annotations?
    1.71 +     */
    1.72 +    boolean allowTypeAnnotations;
    1.73 +
    1.74      /** Switch: should we keep docComments?
    1.75       */
    1.76      boolean keepDocComments;
    1.77 @@ -558,7 +604,33 @@
    1.78          return term(EXPR);
    1.79      }
    1.80  
    1.81 +    /**
    1.82 +     * parses (optional) type annotations followed by a type. If the
    1.83 +     * annotations are present before the type and are not consumed during array
    1.84 +     * parsing, this method returns a {@link JCAnnotatedType} consisting of
    1.85 +     * these annotations and the underlying type. Otherwise, it returns the
    1.86 +     * underlying type.
    1.87 +     *
    1.88 +     * <p>
    1.89 +     *
    1.90 +     * Note that this method sets {@code mode} to {@code TYPE} first, before
    1.91 +     * parsing annotations.
    1.92 +     */
    1.93      public JCExpression parseType() {
    1.94 +        List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
    1.95 +        return parseType(annotations);
    1.96 +    }
    1.97 +
    1.98 +    public JCExpression parseType(List<JCTypeAnnotation> annotations) {
    1.99 +        JCExpression result = unannotatedType();
   1.100 +
   1.101 +        if (!annotations.isEmpty())
   1.102 +            result = F.AnnotatedType(annotations, result);
   1.103 +
   1.104 +        return result;
   1.105 +    }
   1.106 +
   1.107 +    public JCExpression unannotatedType() {
   1.108          return term(TYPE);
   1.109      }
   1.110  
   1.111 @@ -792,8 +864,8 @@
   1.112       *                 | [TypeArguments] THIS [Arguments]
   1.113       *                 | [TypeArguments] SUPER SuperSuffix
   1.114       *                 | NEW [TypeArguments] Creator
   1.115 -     *                 | Ident { "." Ident }
   1.116 -     *                   [ "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
   1.117 +     *                 | [Annotations] Ident { "." Ident }
   1.118 +     *                   [ [Annotations] "[" ( "]" BracketsOpt "." CLASS | Expression "]" )
   1.119       *                   | Arguments
   1.120       *                   | "." ( CLASS | THIS | [TypeArguments] SUPER Arguments | NEW [TypeArguments] InnerCreator )
   1.121       *                   ]
   1.122 @@ -942,23 +1014,62 @@
   1.123                  typeArgs = null;
   1.124              } else return illegal();
   1.125              break;
   1.126 +        case MONKEYS_AT:
   1.127 +
   1.128 +            // only annotated targetting class literals or cast types are valid
   1.129 +            List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
   1.130 +            if (typeAnnos.isEmpty()) {
   1.131 +                // else there would be no '@'
   1.132 +                throw new AssertionError("type annos is empty");
   1.133 +            }
   1.134 +
   1.135 +            JCExpression expr = term3();
   1.136 +
   1.137 +            // Type annotations: If term3 just parsed a non-type, expect a
   1.138 +            // class literal (and issue a syntax error if there is no class
   1.139 +            // literal). Otherwise, create a JCAnnotatedType.
   1.140 +            if ((mode & TYPE) == 0) {
   1.141 +                if (expr.getTag() != JCTree.SELECT)
   1.142 +                    return illegal(typeAnnos.head.pos);
   1.143 +                JCFieldAccess sel = (JCFieldAccess)expr;
   1.144 +                if (sel.name != names._class)
   1.145 +                    return illegal();
   1.146 +                else {
   1.147 +                    sel.selected = F.AnnotatedType(typeAnnos, sel.selected);
   1.148 +                    t = expr;
   1.149 +                }
   1.150 +            } else {
   1.151 +                // type annotation targeting a cast
   1.152 +                t = toP(F.at(S.pos()).AnnotatedType(typeAnnos, expr));
   1.153 +            }
   1.154 +            break;
   1.155          case IDENTIFIER: case ASSERT: case ENUM:
   1.156              if (typeArgs != null) return illegal();
   1.157              t = toP(F.at(S.pos()).Ident(ident()));
   1.158              loop: while (true) {
   1.159                  pos = S.pos();
   1.160 +                final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
   1.161 +
   1.162 +                // need to report an error later if LBRACKET is for array
   1.163 +                // index access rather than array creation level
   1.164 +                if (!annos.isEmpty() && S.token() != LBRACKET && S.token() != ELLIPSIS)
   1.165 +                    return illegal(annos.head.pos);
   1.166                  switch (S.token()) {
   1.167                  case LBRACKET:
   1.168                      S.nextToken();
   1.169 +
   1.170                      if (S.token() == RBRACKET) {
   1.171 +
   1.172                          S.nextToken();
   1.173 -                        t = bracketsOpt(t);
   1.174 +
   1.175 +                        t = bracketsOpt(t, annos);
   1.176                          t = toP(F.at(pos).TypeArray(t));
   1.177                          t = bracketsSuffix(t);
   1.178                      } else {
   1.179                          if ((mode & EXPR) != 0) {
   1.180                              mode = EXPR;
   1.181                              JCExpression t1 = term();
   1.182 +                            if (!annos.isEmpty()) t = illegal(annos.head.pos);
   1.183                              t = to(F.at(pos).Indexed(t, t1));
   1.184                          }
   1.185                          accept(RBRACKET);
   1.186 @@ -1011,6 +1122,10 @@
   1.187                      // typeArgs saved for next loop iteration.
   1.188                      t = toP(F.at(pos).Select(t, ident()));
   1.189                      break;
   1.190 +                case ELLIPSIS:
   1.191 +                    assert this.permitTypeAnnotationsPushBack;
   1.192 +                    typeAnnotationsPushedBack = annos;
   1.193 +                    break loop;
   1.194                  default:
   1.195                      break loop;
   1.196                  }
   1.197 @@ -1049,14 +1164,18 @@
   1.198          if (typeArgs != null) illegal();
   1.199          while (true) {
   1.200              int pos1 = S.pos();
   1.201 +
   1.202 +            final List<JCTypeAnnotation> annos = typeAnnotationsOpt();
   1.203 +
   1.204              if (S.token() == LBRACKET) {
   1.205                  S.nextToken();
   1.206 +
   1.207                  if ((mode & TYPE) != 0) {
   1.208                      int oldmode = mode;
   1.209                      mode = TYPE;
   1.210                      if (S.token() == RBRACKET) {
   1.211                          S.nextToken();
   1.212 -                        t = bracketsOpt(t);
   1.213 +                        t = bracketsOpt(t, annos);
   1.214                          t = toP(F.at(pos1).TypeArray(t));
   1.215                          return t;
   1.216                      }
   1.217 @@ -1091,6 +1210,13 @@
   1.218                      typeArgs = null;
   1.219                  }
   1.220              } else {
   1.221 +                if (!annos.isEmpty()) {
   1.222 +                    illegal(0);
   1.223 +                    if (permitTypeAnnotationsPushBack)
   1.224 +                        typeAnnotationsPushedBack = annos;
   1.225 +                    else
   1.226 +                        return illegal(annos.head.pos);
   1.227 +                }
   1.228                  break;
   1.229              }
   1.230          }
   1.231 @@ -1100,6 +1226,7 @@
   1.232                    S.token() == PLUSPLUS ? JCTree.POSTINC : JCTree.POSTDEC, t));
   1.233              S.nextToken();
   1.234          }
   1.235 +
   1.236          return toP(t);
   1.237      }
   1.238  
   1.239 @@ -1232,22 +1359,24 @@
   1.240      }
   1.241  
   1.242      /** TypeArgument = Type
   1.243 -     *               | "?"
   1.244 -     *               | "?" EXTENDS Type {"&" Type}
   1.245 -     *               | "?" SUPER Type
   1.246 +     *               | [Annotations] "?"
   1.247 +     *               | [Annotations] "?" EXTENDS Type {"&" Type}
   1.248 +     *               | [Annotations] "?" SUPER Type
   1.249       */
   1.250      JCExpression typeArgument() {
   1.251 -        if (S.token() != QUES) return parseType();
   1.252 +        List<JCTypeAnnotation> annotations = typeAnnotationsOpt();
   1.253 +        if (S.token() != QUES) return parseType(annotations);
   1.254          int pos = S.pos();
   1.255          S.nextToken();
   1.256 +        JCExpression result;
   1.257          if (S.token() == EXTENDS) {
   1.258              TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.EXTENDS));
   1.259              S.nextToken();
   1.260 -            return F.at(pos).Wildcard(t, parseType());
   1.261 +            result = F.at(pos).Wildcard(t, parseType());
   1.262          } else if (S.token() == SUPER) {
   1.263              TypeBoundKind t = to(F.at(S.pos()).TypeBoundKind(BoundKind.SUPER));
   1.264              S.nextToken();
   1.265 -            return F.at(pos).Wildcard(t, parseType());
   1.266 +            result = F.at(pos).Wildcard(t, parseType());
   1.267          } else if (S.token() == IDENTIFIER) {
   1.268              //error recovery
   1.269              reportSyntaxError(S.prevEndPos(), "expected3",
   1.270 @@ -1255,11 +1384,14 @@
   1.271              TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
   1.272              JCExpression wc = toP(F.at(pos).Wildcard(t, null));
   1.273              JCIdent id = toP(F.at(S.pos()).Ident(ident()));
   1.274 -            return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
   1.275 +            result = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
   1.276          } else {
   1.277              TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
   1.278 -            return toP(F.at(pos).Wildcard(t, null));
   1.279 +            result = toP(F.at(pos).Wildcard(t, null));
   1.280          }
   1.281 +        if (!annotations.isEmpty())
   1.282 +            result = toP(F.at(annotations.head.pos).AnnotatedType(annotations,result));
   1.283 +        return result;
   1.284      }
   1.285  
   1.286      JCTypeApply typeArguments(JCExpression t) {
   1.287 @@ -1268,21 +1400,47 @@
   1.288          return toP(F.at(pos).TypeApply(t, args));
   1.289      }
   1.290  
   1.291 -    /** BracketsOpt = {"[" "]"}
   1.292 +    /**
   1.293 +     * BracketsOpt = { [Annotations] "[" "]" }
   1.294 +     *
   1.295 +     * <p>
   1.296 +     *
   1.297 +     * <code>annotations</code> is the list of annotations targeting
   1.298 +     * the expression <code>t</code>.
   1.299       */
   1.300 -    private JCExpression bracketsOpt(JCExpression t) {
   1.301 +    private JCExpression bracketsOpt(JCExpression t,
   1.302 +            List<JCTypeAnnotation> annotations) {
   1.303 +        List<JCTypeAnnotation> nextLevelAnnotations = typeAnnotationsOpt();
   1.304 +
   1.305          if (S.token() == LBRACKET) {
   1.306              int pos = S.pos();
   1.307              S.nextToken();
   1.308 -            t = bracketsOptCont(t, pos);
   1.309 -            F.at(pos);
   1.310 +
   1.311 +            JCExpression orig = t;
   1.312 +            t = bracketsOptCont(t, pos, nextLevelAnnotations);
   1.313 +        } else if (!nextLevelAnnotations.isEmpty()) {
   1.314 +            if (permitTypeAnnotationsPushBack) {
   1.315 +                this.typeAnnotationsPushedBack = nextLevelAnnotations;
   1.316 +            } else
   1.317 +                return illegal(nextLevelAnnotations.head.pos);
   1.318          }
   1.319 +
   1.320 +        int apos = S.pos();
   1.321 +        if (!annotations.isEmpty())
   1.322 +            t = F.at(apos).AnnotatedType(annotations, t);
   1.323          return t;
   1.324      }
   1.325  
   1.326 -    private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos) {
   1.327 +    /** BracketsOpt = {"[" TypeAnnotations "]"}
   1.328 +     */
   1.329 +    private JCExpression bracketsOpt(JCExpression t) {
   1.330 +        return bracketsOpt(t, List.<JCTypeAnnotation>nil());
   1.331 +    }
   1.332 +
   1.333 +    private JCArrayTypeTree bracketsOptCont(JCExpression t, int pos,
   1.334 +            List<JCTypeAnnotation> annotations) {
   1.335          accept(RBRACKET);
   1.336 -        t = bracketsOpt(t);
   1.337 +        t = bracketsOpt(t, annotations);
   1.338          return toP(F.at(pos).TypeArray(t));
   1.339      }
   1.340  
   1.341 @@ -1316,18 +1474,29 @@
   1.342          return t;
   1.343      }
   1.344  
   1.345 -    /** Creator = Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
   1.346 +    /** Creator = [Annotations] Qualident [TypeArguments] ( ArrayCreatorRest | ClassCreatorRest )
   1.347       */
   1.348      JCExpression creator(int newpos, List<JCExpression> typeArgs) {
   1.349 +
   1.350 +        List<JCTypeAnnotation> newAnnotations = typeAnnotationsOpt();
   1.351 +
   1.352          switch (S.token()) {
   1.353          case BYTE: case SHORT: case CHAR: case INT: case LONG: case FLOAT:
   1.354          case DOUBLE: case BOOLEAN:
   1.355 -            if (typeArgs == null)
   1.356 -                return arrayCreatorRest(newpos, basicType());
   1.357 +            if (typeArgs == null) {
   1.358 +                if (newAnnotations.isEmpty())
   1.359 +                    return arrayCreatorRest(newpos, basicType());
   1.360 +                else
   1.361 +                    return arrayCreatorRest(newpos, F.AnnotatedType(newAnnotations, basicType()));
   1.362 +            }
   1.363              break;
   1.364          default:
   1.365          }
   1.366          JCExpression t = qualident();
   1.367 +        // handle type annotations for non primitive arrays
   1.368 +        if (!newAnnotations.isEmpty())
   1.369 +            t = F.AnnotatedType(newAnnotations, t);
   1.370 +
   1.371          int oldmode = mode;
   1.372          mode = TYPE;
   1.373          if (S.token() == LT) {
   1.374 @@ -1344,7 +1513,7 @@
   1.375              }
   1.376          }
   1.377          mode = oldmode;
   1.378 -        if (S.token() == LBRACKET) {
   1.379 +        if (S.token() == LBRACKET || S.token() == MONKEYS_AT) {
   1.380              JCExpression e = arrayCreatorRest(newpos, t);
   1.381              if (typeArgs != null) {
   1.382                  int pos = newpos;
   1.383 @@ -1360,7 +1529,12 @@
   1.384              }
   1.385              return e;
   1.386          } else if (S.token() == LPAREN) {
   1.387 -            return classCreatorRest(newpos, null, typeArgs, t);
   1.388 +            JCNewClass newClass = classCreatorRest(newpos, null, typeArgs, t);
   1.389 +            if (newClass.def != null) {
   1.390 +                assert newClass.def.mods.annotations.isEmpty();
   1.391 +                newClass.def.mods.annotations = List.convert(JCAnnotation.class, newAnnotations);
   1.392 +            }
   1.393 +            return newClass;
   1.394          } else {
   1.395              reportSyntaxError(S.pos(), "expected2",
   1.396                                 LPAREN, LBRACKET);
   1.397 @@ -1380,40 +1554,73 @@
   1.398          return classCreatorRest(newpos, encl, typeArgs, t);
   1.399      }
   1.400  
   1.401 -    /** ArrayCreatorRest = "[" ( "]" BracketsOpt ArrayInitializer
   1.402 -     *                         | Expression "]" {"[" Expression "]"} BracketsOpt )
   1.403 +    /** ArrayCreatorRest = [Annotations] "[" ( "]" BracketsOpt ArrayInitializer
   1.404 +     *                         | Expression "]" {[Annotations]  "[" Expression "]"} BracketsOpt )
   1.405       */
   1.406      JCExpression arrayCreatorRest(int newpos, JCExpression elemtype) {
   1.407 +
   1.408 +        List<JCTypeAnnotation> topAnnos = List.nil();
   1.409 +        if (elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
   1.410 +            JCAnnotatedType atype = (JCAnnotatedType) elemtype;
   1.411 +            topAnnos = atype.annotations;
   1.412 +            elemtype = atype.underlyingType;
   1.413 +        }
   1.414 +
   1.415 +        List<JCTypeAnnotation> annos = typeAnnotationsOpt();
   1.416 +
   1.417          accept(LBRACKET);
   1.418 +
   1.419          if (S.token() == RBRACKET) {
   1.420              accept(RBRACKET);
   1.421 -            elemtype = bracketsOpt(elemtype);
   1.422 +
   1.423 +            elemtype = bracketsOpt(elemtype, annos);
   1.424 +
   1.425              if (S.token() == LBRACE) {
   1.426 -                return arrayInitializer(newpos, elemtype);
   1.427 +                JCNewArray na = (JCNewArray)arrayInitializer(newpos, elemtype);
   1.428 +
   1.429 +                na.annotations = topAnnos;
   1.430 +
   1.431 +                return na;
   1.432              } else {
   1.433                  return syntaxError(S.pos(), "array.dimension.missing");
   1.434              }
   1.435          } else {
   1.436              ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
   1.437 +
   1.438 +            // maintain array dimension type annotations
   1.439 +            ListBuffer<List<JCTypeAnnotation>> dimAnnotations = ListBuffer.lb();
   1.440 +            dimAnnotations.append(annos);
   1.441 +
   1.442              dims.append(parseExpression());
   1.443              accept(RBRACKET);
   1.444 -            while (S.token() == LBRACKET) {
   1.445 +            while (S.token() == LBRACKET
   1.446 +                    || (S.token() == MONKEYS_AT)) {
   1.447 +                List<JCTypeAnnotation> maybeDimAnnos = typeAnnotationsOpt();
   1.448                  int pos = S.pos();
   1.449                  S.nextToken();
   1.450                  if (S.token() == RBRACKET) {
   1.451 -                    elemtype = bracketsOptCont(elemtype, pos);
   1.452 +                    elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
   1.453                  } else {
   1.454 -                    dims.append(parseExpression());
   1.455 -                    accept(RBRACKET);
   1.456 +                    if (S.token() == RBRACKET) { // no dimension
   1.457 +                        elemtype = bracketsOptCont(elemtype, pos, maybeDimAnnos);
   1.458 +                    } else {
   1.459 +                        dimAnnotations.append(maybeDimAnnos);
   1.460 +                        dims.append(parseExpression());
   1.461 +                        accept(RBRACKET);
   1.462 +                    }
   1.463                  }
   1.464              }
   1.465 -            return toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
   1.466 +
   1.467 +            JCNewArray na = toP(F.at(newpos).NewArray(elemtype, dims.toList(), null));
   1.468 +            na.annotations = topAnnos;
   1.469 +            na.dimAnnotations = dimAnnotations.toList();
   1.470 +            return na;
   1.471          }
   1.472      }
   1.473  
   1.474      /** ClassCreatorRest = Arguments [ClassBody]
   1.475       */
   1.476 -    JCExpression classCreatorRest(int newpos,
   1.477 +    JCNewClass classCreatorRest(int newpos,
   1.478                                    JCExpression encl,
   1.479                                    List<JCExpression> typeArgs,
   1.480                                    JCExpression t)
   1.481 @@ -1860,17 +2067,32 @@
   1.482                                          new ListBuffer<JCExpressionStatement>()).toList();
   1.483      }
   1.484  
   1.485 +    enum AnnotationKind { DEFAULT_ANNO, TYPE_ANNO };
   1.486 +
   1.487      /** AnnotationsOpt = { '@' Annotation }
   1.488       */
   1.489 -    List<JCAnnotation> annotationsOpt() {
   1.490 +    List<JCAnnotation> annotationsOpt(AnnotationKind kind) {
   1.491          if (S.token() != MONKEYS_AT) return List.nil(); // optimization
   1.492          ListBuffer<JCAnnotation> buf = new ListBuffer<JCAnnotation>();
   1.493 +        int prevmode = mode;
   1.494          while (S.token() == MONKEYS_AT) {
   1.495              int pos = S.pos();
   1.496              S.nextToken();
   1.497 -            buf.append(annotation(pos));
   1.498 +            buf.append(annotation(pos, kind));
   1.499          }
   1.500 -        return buf.toList();
   1.501 +        lastmode = mode;
   1.502 +        mode = prevmode;
   1.503 +        List<JCAnnotation> annotations = buf.toList();
   1.504 +
   1.505 +        if (debugJSR308 && kind == AnnotationKind.TYPE_ANNO)
   1.506 +            System.out.println("TA: parsing " + annotations
   1.507 +                    + " in " + log.currentSourceFile());
   1.508 +        return annotations;
   1.509 +    }
   1.510 +
   1.511 +    List<JCTypeAnnotation> typeAnnotationsOpt() {
   1.512 +        List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.TYPE_ANNO);
   1.513 +        return List.convert(JCTypeAnnotation.class, annotations);
   1.514      }
   1.515  
   1.516      /** ModifiersOpt = { Modifier }
   1.517 @@ -1915,7 +2137,7 @@
   1.518              if (flag == Flags.ANNOTATION) {
   1.519                  checkAnnotations();
   1.520                  if (S.token() != INTERFACE) {
   1.521 -                JCAnnotation ann = annotation(lastPos);
   1.522 +                JCAnnotation ann = annotation(lastPos, AnnotationKind.DEFAULT_ANNO);
   1.523                  // if first modifier is an annotation, set pos to annotation's.
   1.524                  if (flags == 0 && annotations.isEmpty())
   1.525                      pos = ann.pos;
   1.526 @@ -1946,12 +2168,18 @@
   1.527      /** Annotation              = "@" Qualident [ "(" AnnotationFieldValues ")" ]
   1.528       * @param pos position of "@" token
   1.529       */
   1.530 -    JCAnnotation annotation(int pos) {
   1.531 +    JCAnnotation annotation(int pos, AnnotationKind kind) {
   1.532          // accept(AT); // AT consumed by caller
   1.533          checkAnnotations();
   1.534 +        if (kind == AnnotationKind.TYPE_ANNO)
   1.535 +            checkTypeAnnotations();
   1.536          JCTree ident = qualident();
   1.537          List<JCExpression> fieldValues = annotationFieldValuesOpt();
   1.538 -        JCAnnotation ann = F.at(pos).Annotation(ident, fieldValues);
   1.539 +        JCAnnotation ann;
   1.540 +        if (kind == AnnotationKind.DEFAULT_ANNO)
   1.541 +            ann = F.at(pos).Annotation(ident, fieldValues);
   1.542 +        else
   1.543 +            ann = F.at(pos).TypeAnnotation(ident, fieldValues);
   1.544          storeEnd(ann, S.prevEndPos());
   1.545          return ann;
   1.546      }
   1.547 @@ -2003,7 +2231,7 @@
   1.548          case MONKEYS_AT:
   1.549              pos = S.pos();
   1.550              S.nextToken();
   1.551 -            return annotation(pos);
   1.552 +            return annotation(pos, AnnotationKind.DEFAULT_ANNO);
   1.553          case LBRACE:
   1.554              pos = S.pos();
   1.555              accept(LBRACE);
   1.556 @@ -2357,7 +2585,7 @@
   1.557              S.resetDeprecatedFlag();
   1.558          }
   1.559          int pos = S.pos();
   1.560 -        List<JCAnnotation> annotations = annotationsOpt();
   1.561 +        List<JCAnnotation> annotations = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
   1.562          JCModifiers mods = F.at(annotations.isEmpty() ? Position.NOPOS : pos).Modifiers(flags, annotations);
   1.563          List<JCExpression> typeArgs = typeArgumentsOpt();
   1.564          int identPos = S.pos();
   1.565 @@ -2460,16 +2688,23 @@
   1.566                  if (typarams.length() > 0 && mods.pos == Position.NOPOS) {
   1.567                      mods.pos = pos;
   1.568                  }
   1.569 +
   1.570 +                List<JCAnnotation> annosAfterParams = annotationsOpt(AnnotationKind.DEFAULT_ANNO);
   1.571 +
   1.572                  Token token = S.token();
   1.573                  Name name = S.name();
   1.574                  pos = S.pos();
   1.575                  JCExpression type;
   1.576                  boolean isVoid = S.token() == VOID;
   1.577                  if (isVoid) {
   1.578 +                    if (annosAfterParams.nonEmpty())
   1.579 +                        illegal(annosAfterParams.head.pos);
   1.580                      type = to(F.at(pos).TypeIdent(TypeTags.VOID));
   1.581                      S.nextToken();
   1.582                  } else {
   1.583 -                    type = parseType();
   1.584 +                    mods.annotations = mods.annotations.appendList(annosAfterParams);
   1.585 +                    // method returns types are un-annotated types
   1.586 +                    type = unannotatedType();
   1.587                  }
   1.588                  if (S.token() == LPAREN && !isInterface && type.getTag() == JCTree.IDENT) {
   1.589                      if (isInterface || name != className)
   1.590 @@ -2505,15 +2740,15 @@
   1.591      }
   1.592  
   1.593      /** MethodDeclaratorRest =
   1.594 -     *      FormalParameters BracketsOpt [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
   1.595 +     *      FormalParameters BracketsOpt [Annotations] [Throws TypeList] ( MethodBody | [DEFAULT AnnotationValue] ";")
   1.596       *  VoidMethodDeclaratorRest =
   1.597 -     *      FormalParameters [Throws TypeList] ( MethodBody | ";")
   1.598 +     *      FormalParameters [Annotations] [Throws TypeList] ( MethodBody | ";")
   1.599       *  InterfaceMethodDeclaratorRest =
   1.600 -     *      FormalParameters BracketsOpt [THROWS TypeList] ";"
   1.601 +     *      FormalParameters BracketsOpt [Annotations] [THROWS TypeList] ";"
   1.602       *  VoidInterfaceMethodDeclaratorRest =
   1.603 -     *      FormalParameters [THROWS TypeList] ";"
   1.604 +     *      FormalParameters [Annotations] [THROWS TypeList] ";"
   1.605       *  ConstructorDeclaratorRest =
   1.606 -     *      "(" FormalParameterListOpt ")" [THROWS TypeList] MethodBody
   1.607 +     *      "(" FormalParameterListOpt ")" [Annotations] [THROWS TypeList] MethodBody
   1.608       */
   1.609      JCTree methodDeclaratorRest(int pos,
   1.610                                JCModifiers mods,
   1.611 @@ -2523,7 +2758,22 @@
   1.612                                boolean isInterface, boolean isVoid,
   1.613                                String dc) {
   1.614          List<JCVariableDecl> params = formalParameters();
   1.615 -        if (!isVoid) type = bracketsOpt(type);
   1.616 +
   1.617 +        List<JCTypeAnnotation> receiverAnnotations;
   1.618 +        if (!isVoid) {
   1.619 +            // need to distinguish between receiver anno and array anno
   1.620 +            // look at typeAnnotationsPushedBack comment
   1.621 +            this.permitTypeAnnotationsPushBack = true;
   1.622 +            type = methodReturnArrayRest(type);
   1.623 +            this.permitTypeAnnotationsPushBack = false;
   1.624 +            if (typeAnnotationsPushedBack == null)
   1.625 +                receiverAnnotations = List.nil();
   1.626 +            else
   1.627 +                receiverAnnotations = typeAnnotationsPushedBack;
   1.628 +            typeAnnotationsPushedBack = null;
   1.629 +        } else
   1.630 +            receiverAnnotations = typeAnnotationsOpt();
   1.631 +
   1.632          List<JCExpression> thrown = List.nil();
   1.633          if (S.token() == THROWS) {
   1.634              S.nextToken();
   1.635 @@ -2552,20 +2802,51 @@
   1.636          }
   1.637          JCMethodDecl result =
   1.638              toP(F.at(pos).MethodDef(mods, name, type, typarams,
   1.639 -                                    params, thrown,
   1.640 +                                    params, receiverAnnotations, thrown,
   1.641                                      body, defaultValue));
   1.642          attach(result, dc);
   1.643          return result;
   1.644      }
   1.645  
   1.646 -    /** QualidentList = Qualident {"," Qualident}
   1.647 +    /** Parses the array levels after the format parameters list, and append
   1.648 +     * them to the return type, while preseving the order of type annotations
   1.649 +     */
   1.650 +    private JCExpression methodReturnArrayRest(JCExpression type) {
   1.651 +        if (type.getTag() != JCTree.TYPEARRAY)
   1.652 +            return bracketsOpt(type);
   1.653 +
   1.654 +        JCArrayTypeTree baseArray = (JCArrayTypeTree)type;
   1.655 +        while (TreeInfo.typeIn(baseArray.elemtype) instanceof JCArrayTypeTree)
   1.656 +            baseArray = (JCArrayTypeTree)TreeInfo.typeIn(baseArray.elemtype);
   1.657 +
   1.658 +        if (baseArray.elemtype.getTag() == JCTree.ANNOTATED_TYPE) {
   1.659 +            JCAnnotatedType at = (JCAnnotatedType)baseArray.elemtype;
   1.660 +            at.underlyingType = bracketsOpt(at.underlyingType);
   1.661 +        } else {
   1.662 +            baseArray.elemtype = bracketsOpt(baseArray.elemtype);
   1.663 +        }
   1.664 +
   1.665 +        return type;
   1.666 +    }
   1.667 +
   1.668 +    /** QualidentList = [Annotations] Qualident {"," [Annotations] Qualident}
   1.669       */
   1.670      List<JCExpression> qualidentList() {
   1.671          ListBuffer<JCExpression> ts = new ListBuffer<JCExpression>();
   1.672 -        ts.append(qualident());
   1.673 +
   1.674 +        List<JCTypeAnnotation> typeAnnos = typeAnnotationsOpt();
   1.675 +        if (!typeAnnos.isEmpty())
   1.676 +            ts.append(F.AnnotatedType(typeAnnos, qualident()));
   1.677 +        else
   1.678 +            ts.append(qualident());
   1.679          while (S.token() == COMMA) {
   1.680              S.nextToken();
   1.681 -            ts.append(qualident());
   1.682 +
   1.683 +            typeAnnos = typeAnnotationsOpt();
   1.684 +            if (!typeAnnos.isEmpty())
   1.685 +                ts.append(F.AnnotatedType(typeAnnos, qualident()));
   1.686 +            else
   1.687 +                ts.append(qualident());
   1.688          }
   1.689          return ts.toList();
   1.690      }
   1.691 @@ -2589,12 +2870,13 @@
   1.692          }
   1.693      }
   1.694  
   1.695 -    /** TypeParameter = TypeVariable [TypeParameterBound]
   1.696 +    /** TypeParameter = [Annotations] TypeVariable [TypeParameterBound]
   1.697       *  TypeParameterBound = EXTENDS Type {"&" Type}
   1.698       *  TypeVariable = Ident
   1.699       */
   1.700      JCTypeParameter typeParameter() {
   1.701          int pos = S.pos();
   1.702 +        List<JCTypeAnnotation> annos = typeAnnotationsOpt();
   1.703          Name name = ident();
   1.704          ListBuffer<JCExpression> bounds = new ListBuffer<JCExpression>();
   1.705          if (S.token() == EXTENDS) {
   1.706 @@ -2605,7 +2887,7 @@
   1.707                  bounds.append(parseType());
   1.708              }
   1.709          }
   1.710 -        return toP(F.at(pos).TypeParameter(name, bounds.toList()));
   1.711 +        return toP(F.at(pos).TypeParameter(name, bounds.toList(), annos));
   1.712      }
   1.713  
   1.714      /** FormalParameters = "(" [ FormalParameterList ] ")"
   1.715 @@ -2639,12 +2921,31 @@
   1.716       */
   1.717      JCVariableDecl formalParameter() {
   1.718          JCModifiers mods = optFinal(Flags.PARAMETER);
   1.719 +        // need to distinguish between vararg annos and array annos
   1.720 +        // look at typeAnnotaitonsPushedBack comment
   1.721 +        this.permitTypeAnnotationsPushBack = true;
   1.722          JCExpression type = parseType();
   1.723 +        this.permitTypeAnnotationsPushBack = false;
   1.724 +
   1.725          if (S.token() == ELLIPSIS) {
   1.726 +            List<JCTypeAnnotation> varargsAnnos = typeAnnotationsPushedBack;
   1.727 +            typeAnnotationsPushedBack = null;
   1.728              checkVarargs();
   1.729              mods.flags |= Flags.VARARGS;
   1.730 +            // insert var arg type annotations
   1.731 +            if (varargsAnnos != null && varargsAnnos.nonEmpty())
   1.732 +                type = F.at(S.pos()).AnnotatedType(varargsAnnos, type);
   1.733              type = to(F.at(S.pos()).TypeArray(type));
   1.734 +
   1.735              S.nextToken();
   1.736 +        } else {
   1.737 +            // if not a var arg, then typeAnnotationsPushedBack should be null
   1.738 +            if (typeAnnotationsPushedBack != null
   1.739 +                    && !typeAnnotationsPushedBack.isEmpty()) {
   1.740 +                reportSyntaxError(typeAnnotationsPushedBack.head.pos,
   1.741 +                        "illegal.start.of.type");
   1.742 +            }
   1.743 +            typeAnnotationsPushedBack = null;
   1.744          }
   1.745          return variableDeclaratorId(mods, type);
   1.746      }
   1.747 @@ -2829,4 +3130,10 @@
   1.748              allowAnnotations = true;
   1.749          }
   1.750      }
   1.751 +    void checkTypeAnnotations() {
   1.752 +        if (!allowTypeAnnotations) {
   1.753 +            log.error(S.pos(), "type.annotations.not.supported.in.source", source.name);
   1.754 +            allowTypeAnnotations = true;
   1.755 +        }
   1.756 +    }
   1.757  }

mercurial