7073631: (javac) javac parser improvements for error position reporting

Thu, 01 Sep 2011 09:14:25 -0700

author
ksrini
date
Thu, 01 Sep 2011 09:14:25 -0700
changeset 1074
04f983e3e825
parent 1073
f85d980faaf8
child 1075
a45d78d26450

7073631: (javac) javac parser improvements for error position reporting
Summary: JavacParser improvements for NetBeans, improved by LangTools.
Reviewed-by: mcimadamore, jjg
Contributed-by: jan.lahoda@oracle.com

src/share/classes/com/sun/tools/javac/parser/JavacParser.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/parser/Scanner.java file | annotate | diff | comparison | revisions
src/share/classes/com/sun/tools/javac/util/AbstractLog.java file | annotate | diff | comparison | revisions
test/tools/javac/TryWithResources/BadTwr.out file | annotate | diff | comparison | revisions
test/tools/javac/TryWithResources/DuplicateResourceDecl.out file | annotate | diff | comparison | revisions
test/tools/javac/TryWithResources/ResourceInterface.out file | annotate | diff | comparison | revisions
test/tools/javac/TryWithResources/TwrFlow.out file | annotate | diff | comparison | revisions
test/tools/javac/TryWithResources/TwrLint.out file | annotate | diff | comparison | revisions
test/tools/javac/TryWithResources/TwrOnNonResource.out file | annotate | diff | comparison | revisions
test/tools/javac/diags/examples/EmptyCharLiteral.java file | annotate | diff | comparison | revisions
test/tools/javac/parser/netbeans/JavacParserTest.java file | annotate | diff | comparison | revisions
     1.1 --- a/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Wed Aug 31 15:39:00 2011 -0700
     1.2 +++ b/src/share/classes/com/sun/tools/javac/parser/JavacParser.java	Thu Sep 01 09:14:25 2011 -0700
     1.3 @@ -27,15 +27,15 @@
     1.4  
     1.5  import java.util.*;
     1.6  
     1.7 +import com.sun.tools.javac.code.*;
     1.8  import com.sun.tools.javac.tree.*;
     1.9 -import com.sun.tools.javac.code.*;
    1.10 +import com.sun.tools.javac.tree.JCTree.*;
    1.11  import com.sun.tools.javac.util.*;
    1.12  import com.sun.tools.javac.util.JCDiagnostic.DiagnosticFlag;
    1.13 +import com.sun.tools.javac.util.JCDiagnostic.DiagnosticPosition;
    1.14  import com.sun.tools.javac.util.List;
    1.15 +
    1.16  import static com.sun.tools.javac.util.ListBuffer.lb;
    1.17 -
    1.18 -import com.sun.tools.javac.tree.JCTree.*;
    1.19 -
    1.20  import static com.sun.tools.javac.parser.Token.*;
    1.21  
    1.22  /** The parser maps a token sequence into an abstract syntax
    1.23 @@ -254,26 +254,44 @@
    1.24      }
    1.25  
    1.26      private JCErroneous syntaxError(int pos, String key, Token... args) {
    1.27 -        return syntaxError(pos, null, key, args);
    1.28 +        return syntaxError(pos, List.<JCTree>nil(), key, args);
    1.29      }
    1.30  
    1.31      private JCErroneous syntaxError(int pos, List<JCTree> errs, String key, Token... args) {
    1.32          setErrorEndPos(pos);
    1.33 -        reportSyntaxError(pos, key, (Object[])args);
    1.34 -        return toP(F.at(pos).Erroneous(errs));
    1.35 +        JCErroneous err = F.at(pos).Erroneous(errs);
    1.36 +        reportSyntaxError(err, key, (Object[])args);
    1.37 +        if (errs != null) {
    1.38 +            JCTree last = errs.last();
    1.39 +            if (last != null)
    1.40 +                storeEnd(last, pos);
    1.41 +        }
    1.42 +        return toP(err);
    1.43      }
    1.44  
    1.45      private int errorPos = Position.NOPOS;
    1.46 +
    1.47      /**
    1.48 -     * Report a syntax error at given position using the given
    1.49 -     * argument unless one was already reported at the same position.
    1.50 +     * Report a syntax using the given the position parameter and arguments,
    1.51 +     * unless one was already reported at the same position.
    1.52       */
    1.53      private void reportSyntaxError(int pos, String key, Object... args) {
    1.54 +        JCDiagnostic.DiagnosticPosition diag = new JCDiagnostic.SimpleDiagnosticPosition(pos);
    1.55 +        reportSyntaxError(diag, key, args);
    1.56 +    }
    1.57 +
    1.58 +    /**
    1.59 +     * Report a syntax error using the given DiagnosticPosition object and
    1.60 +     * arguments, unless one was already reported at the same position.
    1.61 +     */
    1.62 +    private void reportSyntaxError(JCDiagnostic.DiagnosticPosition diagPos, String key, Object... args) {
    1.63 +        int pos = diagPos.getPreferredPosition();
    1.64          if (pos > S.errPos() || pos == Position.NOPOS) {
    1.65 -            if (S.token() == EOF)
    1.66 -                error(pos, "premature.eof");
    1.67 -            else
    1.68 -                error(pos, key, args);
    1.69 +            if (S.token() == EOF) {
    1.70 +                error(diagPos, "premature.eof");
    1.71 +            } else {
    1.72 +                error(diagPos, key, args);
    1.73 +            }
    1.74          }
    1.75          S.errPos(pos);
    1.76          if (S.pos() == errorPos)
    1.77 @@ -311,7 +329,7 @@
    1.78      /** Report an illegal start of expression/type error at given position.
    1.79       */
    1.80      JCExpression illegal(int pos) {
    1.81 -        setErrorEndPos(S.pos());
    1.82 +        setErrorEndPos(pos);
    1.83          if ((mode & EXPR) != 0)
    1.84              return syntaxError(pos, "illegal.start.of.expr");
    1.85          else
    1.86 @@ -340,7 +358,7 @@
    1.87       *  indexed by the tree nodes they refer to.
    1.88       *  defined only if option flag keepDocComment is set.
    1.89       */
    1.90 -    Map<JCTree, String> docComments;
    1.91 +    private final Map<JCTree, String> docComments;
    1.92  
    1.93      /** Make an entry into docComments hashtable,
    1.94       *  provided flag keepDocComments is set and given doc comment is non-null.
    1.95 @@ -462,6 +480,10 @@
    1.96          return t;
    1.97      }
    1.98  
    1.99 +    JCExpression literal(Name prefix) {
   1.100 +        return literal(prefix, S.pos());
   1.101 +    }
   1.102 +
   1.103      /**
   1.104       * Literal =
   1.105       *     INTLITERAL
   1.106 @@ -474,8 +496,7 @@
   1.107       *   | FALSE
   1.108       *   | NULL
   1.109       */
   1.110 -    JCExpression literal(Name prefix) {
   1.111 -        int pos = S.pos();
   1.112 +    JCExpression literal(Name prefix, int pos) {
   1.113          JCExpression t = errorTree;
   1.114          switch (S.token()) {
   1.115          case INTLITERAL:
   1.116 @@ -869,7 +890,7 @@
   1.117                      (S.token() == INTLITERAL || S.token() == LONGLITERAL) &&
   1.118                      S.radix() == 10) {
   1.119                      mode = EXPR;
   1.120 -                    t = literal(names.hyphen);
   1.121 +                    t = literal(names.hyphen, pos);
   1.122                  } else {
   1.123                      t = term3();
   1.124                      return F.at(pos).Unary(unoptag(token), t);
   1.125 @@ -1267,15 +1288,17 @@
   1.126                  case GTGT:
   1.127                      S.token(GT);
   1.128                      break;
   1.129 +                case GT:
   1.130 +                    S.nextToken();
   1.131 +                    break;
   1.132                  default:
   1.133 -                    accept(GT);
   1.134 +                    args.append(syntaxError(S.pos(), "expected", GT));
   1.135                      break;
   1.136                  }
   1.137                  return args.toList();
   1.138              }
   1.139          } else {
   1.140 -            syntaxError(S.pos(), "expected", LT);
   1.141 -            return List.nil();
   1.142 +            return List.<JCExpression>of(syntaxError(S.pos(), "expected", LT));
   1.143          }
   1.144      }
   1.145  
   1.146 @@ -1300,12 +1323,12 @@
   1.147              return F.at(pos).Wildcard(t, bound);
   1.148          } else if (S.token() == IDENTIFIER) {
   1.149              //error recovery
   1.150 -            reportSyntaxError(S.prevEndPos(), "expected3",
   1.151 -                    GT, EXTENDS, SUPER);
   1.152              TypeBoundKind t = F.at(Position.NOPOS).TypeBoundKind(BoundKind.UNBOUND);
   1.153              JCExpression wc = toP(F.at(pos).Wildcard(t, null));
   1.154              JCIdent id = toP(F.at(S.pos()).Ident(ident()));
   1.155 -            return F.at(pos).Erroneous(List.<JCTree>of(wc, id));
   1.156 +            JCErroneous err = F.at(pos).Erroneous(List.<JCTree>of(wc, id));
   1.157 +            reportSyntaxError(err, "expected3", GT, EXTENDS, SUPER);
   1.158 +            return err;
   1.159          } else {
   1.160              TypeBoundKind t = toP(F.at(pos).TypeBoundKind(BoundKind.UNBOUND));
   1.161              return toP(F.at(pos).Wildcard(t, null));
   1.162 @@ -1391,7 +1414,7 @@
   1.163          while (S.token() == DOT) {
   1.164              if (diamondFound) {
   1.165                  //cannot select after a diamond
   1.166 -                illegal(S.pos());
   1.167 +                illegal();
   1.168              }
   1.169              int pos = S.pos();
   1.170              S.nextToken();
   1.171 @@ -1419,15 +1442,16 @@
   1.172                      pos = typeArgs.head.pos;
   1.173                  }
   1.174                  setErrorEndPos(S.prevEndPos());
   1.175 -                reportSyntaxError(pos, "cannot.create.array.with.type.arguments");
   1.176 -                return toP(F.at(newpos).Erroneous(typeArgs.prepend(e)));
   1.177 +                JCErroneous err = F.at(pos).Erroneous(typeArgs.prepend(e));
   1.178 +                reportSyntaxError(err, "cannot.create.array.with.type.arguments");
   1.179 +                return toP(err);
   1.180              }
   1.181              return e;
   1.182          } else if (S.token() == LPAREN) {
   1.183              return classCreatorRest(newpos, null, typeArgs, t);
   1.184          } else {
   1.185 -            reportSyntaxError(S.pos(), "expected2",
   1.186 -                               LPAREN, LBRACKET);
   1.187 +            setErrorEndPos(S.pos());
   1.188 +            reportSyntaxError(S.pos(), "expected2", LPAREN, LBRACKET);
   1.189              t = toP(F.at(newpos).NewClass(null, typeArgs, t, List.<JCExpression>nil(), null));
   1.190              return toP(F.at(newpos).Erroneous(List.<JCTree>of(t)));
   1.191          }
   1.192 @@ -1457,7 +1481,8 @@
   1.193              if (S.token() == LBRACE) {
   1.194                  return arrayInitializer(newpos, elemtype);
   1.195              } else {
   1.196 -                return syntaxError(S.pos(), "array.dimension.missing");
   1.197 +                JCExpression t = toP(F.at(newpos).NewArray(elemtype, List.<JCExpression>nil(), null));
   1.198 +                return syntaxError(S.pos(), List.<JCTree>of(t), "array.dimension.missing");
   1.199              }
   1.200          } else {
   1.201              ListBuffer<JCExpression> dims = new ListBuffer<JCExpression>();
   1.202 @@ -1843,7 +1868,7 @@
   1.203  
   1.204      /** CatchClause     = CATCH "(" FormalParameter ")" Block
   1.205       */
   1.206 -    JCCatch catchClause() {
   1.207 +    protected JCCatch catchClause() {
   1.208          int pos = S.pos();
   1.209          accept(CATCH);
   1.210          accept(LPAREN);
   1.211 @@ -1973,7 +1998,7 @@
   1.212      JCModifiers modifiersOpt() {
   1.213          return modifiersOpt(null);
   1.214      }
   1.215 -    JCModifiers modifiersOpt(JCModifiers partial) {
   1.216 +    protected JCModifiers modifiersOpt(JCModifiers partial) {
   1.217          long flags;
   1.218          ListBuffer<JCAnnotation> annotations = new ListBuffer<JCAnnotation>();
   1.219          int pos;
   1.220 @@ -2006,6 +2031,7 @@
   1.221              case SYNCHRONIZED: flag = Flags.SYNCHRONIZED; break;
   1.222              case STRICTFP    : flag = Flags.STRICTFP; break;
   1.223              case MONKEYS_AT  : flag = Flags.ANNOTATION; break;
   1.224 +            case ERROR       : flag = 0; S.nextToken(); break;
   1.225              default: break loop;
   1.226              }
   1.227              if ((flags & flag) != 0) error(S.pos(), "repeated.modifier");
   1.228 @@ -2219,9 +2245,12 @@
   1.229  
   1.230      /** Resource = VariableModifiersOpt Type VariableDeclaratorId = Expression
   1.231       */
   1.232 -    JCTree resource() {
   1.233 -        return variableDeclaratorRest(S.pos(), optFinal(Flags.FINAL),
   1.234 -                                      parseType(), ident(), true, null);
   1.235 +    protected JCTree resource() {
   1.236 +        JCModifiers optFinal = optFinal(Flags.FINAL);
   1.237 +        JCExpression type = parseType();
   1.238 +        int pos = S.pos();
   1.239 +        Name ident = ident();
   1.240 +        return variableDeclaratorRest(pos, optFinal, type, ident, true, null);
   1.241      }
   1.242  
   1.243      /** CompilationUnit = [ { "@" Annotation } PACKAGE Qualident ";"] {ImportDeclaration} {TypeDeclaration}
   1.244 @@ -2568,7 +2597,7 @@
   1.245       *    | ModifiersOpt Type Ident
   1.246       *      ( ConstantDeclaratorsRest | InterfaceMethodDeclaratorRest ";" )
   1.247       */
   1.248 -    List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
   1.249 +    protected List<JCTree> classOrInterfaceBodyDeclaration(Name className, boolean isInterface) {
   1.250          if (S.token() == SEMI) {
   1.251              S.nextToken();
   1.252              return List.<JCTree>nil();
   1.253 @@ -2770,7 +2799,7 @@
   1.254      /** FormalParameter = { FINAL | '@' Annotation } Type VariableDeclaratorId
   1.255       *  LastFormalParameter = { FINAL | '@' Annotation } Type '...' Ident | FormalParameter
   1.256       */
   1.257 -    JCVariableDecl formalParameter() {
   1.258 +    protected JCVariableDecl formalParameter() {
   1.259          JCModifiers mods = optFinal(Flags.PARAMETER);
   1.260          JCExpression type = parseType();
   1.261          if (S.token() == ELLIPSIS) {
   1.262 @@ -2788,6 +2817,10 @@
   1.263          log.error(DiagnosticFlag.SYNTAX, pos, key, args);
   1.264      }
   1.265  
   1.266 +    void error(DiagnosticPosition pos, String key, Object ... args) {
   1.267 +        log.error(DiagnosticFlag.SYNTAX, pos, key, args);
   1.268 +    }
   1.269 +
   1.270      void warning(int pos, String key, Object ... args) {
   1.271          log.warning(pos, key, args);
   1.272      }
   1.273 @@ -2807,8 +2840,9 @@
   1.274          case JCTree.ERRONEOUS:
   1.275              return t;
   1.276          default:
   1.277 -            error(t.pos, "not.stmt");
   1.278 -            return F.at(t.pos).Erroneous(List.<JCTree>of(t));
   1.279 +            JCExpression ret = F.at(t.pos).Erroneous(List.<JCTree>of(t));
   1.280 +            error(ret, "not.stmt");
   1.281 +            return ret;
   1.282          }
   1.283      }
   1.284  
     2.1 --- a/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Wed Aug 31 15:39:00 2011 -0700
     2.2 +++ b/src/share/classes/com/sun/tools/javac/parser/Scanner.java	Thu Sep 01 09:14:25 2011 -0700
     2.3 @@ -982,8 +982,16 @@
     2.4      }
     2.5  
     2.6      /** Sets the current token.
     2.7 +     * This method is primarily used to update the token stream when the
     2.8 +     * parser is handling the end of nested type arguments such as
     2.9 +     * {@code List<List<String>>} and needs to disambiguate between
    2.10 +     * repeated use of ">" and relation operators such as ">>" and ">>>". Noting
    2.11 +     * that this does not handle arbitrary tokens containing Unicode escape
    2.12 +     * sequences.
    2.13       */
    2.14      public void token(Token token) {
    2.15 +        pos += this.token.name.length() - token.name.length();
    2.16 +        prevEndPos = pos;
    2.17          this.token = token;
    2.18      }
    2.19  
     3.1 --- a/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Wed Aug 31 15:39:00 2011 -0700
     3.2 +++ b/src/share/classes/com/sun/tools/javac/util/AbstractLog.java	Thu Sep 01 09:14:25 2011 -0700
     3.3 @@ -1,5 +1,5 @@
     3.4  /*
     3.5 - * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
     3.6 + * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
     3.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.8   *
     3.9   * This code is free software; you can redistribute it and/or modify it
    3.10 @@ -96,6 +96,19 @@
    3.11  
    3.12      /** Report an error, unless another error was already reported at same
    3.13       *  source position.
    3.14 +     *  @param flag   A flag to set on the diagnostic
    3.15 +     *  @param pos    The source position at which to report the error.
    3.16 +     *  @param key    The key for the localized error message.
    3.17 +     *  @param args   Fields of the error message.
    3.18 +     */
    3.19 +    public void error(DiagnosticFlag flag, DiagnosticPosition pos, String key, Object ... args) {
    3.20 +        JCDiagnostic d = diags.error(source, pos, key, args);
    3.21 +        d.setFlag(flag);
    3.22 +        report(d);
    3.23 +    }
    3.24 +
    3.25 +    /** Report an error, unless another error was already reported at same
    3.26 +     *  source position.
    3.27       *  @param pos    The source position at which to report the error.
    3.28       *  @param key    The key for the localized error message.
    3.29       *  @param args   Fields of the error message.
     4.1 --- a/test/tools/javac/TryWithResources/BadTwr.out	Wed Aug 31 15:39:00 2011 -0700
     4.2 +++ b/test/tools/javac/TryWithResources/BadTwr.out	Thu Sep 01 09:14:25 2011 -0700
     4.3 @@ -1,5 +1,5 @@
     4.4 -BadTwr.java:13:39: compiler.err.already.defined: r1, main(java.lang.String...)
     4.5 -BadTwr.java:18:13: compiler.err.already.defined: args, main(java.lang.String...)
     4.6 +BadTwr.java:13:46: compiler.err.already.defined: r1, main(java.lang.String...)
     4.7 +BadTwr.java:18:20: compiler.err.already.defined: args, main(java.lang.String...)
     4.8  BadTwr.java:21:13: compiler.err.cant.assign.val.to.final.var: thatsIt
     4.9 -BadTwr.java:26:17: compiler.err.already.defined: name, main(java.lang.String...)
    4.10 +BadTwr.java:26:24: compiler.err.already.defined: name, main(java.lang.String...)
    4.11  4 errors
     5.1 --- a/test/tools/javac/TryWithResources/DuplicateResourceDecl.out	Wed Aug 31 15:39:00 2011 -0700
     5.2 +++ b/test/tools/javac/TryWithResources/DuplicateResourceDecl.out	Thu Sep 01 09:14:25 2011 -0700
     5.3 @@ -1,2 +1,2 @@
     5.4 -DuplicateResourceDecl.java:12:45: compiler.err.already.defined: c, main(java.lang.String[])
     5.5 +DuplicateResourceDecl.java:12:56: compiler.err.already.defined: c, main(java.lang.String[])
     5.6  1 error
     6.1 --- a/test/tools/javac/TryWithResources/ResourceInterface.out	Wed Aug 31 15:39:00 2011 -0700
     6.2 +++ b/test/tools/javac/TryWithResources/ResourceInterface.out	Thu Sep 01 09:14:25 2011 -0700
     6.3 @@ -1,2 +1,2 @@
     6.4 -ResourceInterface.java:38:13: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2
     6.5 +ResourceInterface.java:38:23: compiler.err.unreported.exception.implicit.close: ResourceInterface.E1, r2
     6.6  1 error
     7.1 --- a/test/tools/javac/TryWithResources/TwrFlow.out	Wed Aug 31 15:39:00 2011 -0700
     7.2 +++ b/test/tools/javac/TryWithResources/TwrFlow.out	Thu Sep 01 09:14:25 2011 -0700
     7.3 @@ -1,3 +1,3 @@
     7.4  TwrFlow.java:14:11: compiler.err.except.never.thrown.in.try: java.io.IOException
     7.5 -TwrFlow.java:12:13: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow
     7.6 +TwrFlow.java:12:21: compiler.err.unreported.exception.implicit.close: CustomCloseException, twrFlow
     7.7  2 errors
     8.1 --- a/test/tools/javac/TryWithResources/TwrLint.out	Wed Aug 31 15:39:00 2011 -0700
     8.2 +++ b/test/tools/javac/TryWithResources/TwrLint.out	Thu Sep 01 09:14:25 2011 -0700
     8.3 @@ -1,3 +1,3 @@
     8.4  TwrLint.java:14:15: compiler.warn.try.explicit.close.call
     8.5 -TwrLint.java:13:13: compiler.warn.try.resource.not.referenced: r3
     8.6 +TwrLint.java:13:21: compiler.warn.try.resource.not.referenced: r3
     8.7  2 warnings
     9.1 --- a/test/tools/javac/TryWithResources/TwrOnNonResource.out	Wed Aug 31 15:39:00 2011 -0700
     9.2 +++ b/test/tools/javac/TryWithResources/TwrOnNonResource.out	Thu Sep 01 09:14:25 2011 -0700
     9.3 @@ -1,4 +1,4 @@
     9.4 -TwrOnNonResource.java:12:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
     9.5 -TwrOnNonResource.java:15:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
     9.6 -TwrOnNonResource.java:18:13: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
     9.7 +TwrOnNonResource.java:12:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
     9.8 +TwrOnNonResource.java:15:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
     9.9 +TwrOnNonResource.java:18:30: compiler.err.prob.found.req: (compiler.misc.try.not.applicable.to.type), TwrOnNonResource, java.lang.AutoCloseable
    9.10  3 errors
    10.1 --- a/test/tools/javac/diags/examples/EmptyCharLiteral.java	Wed Aug 31 15:39:00 2011 -0700
    10.2 +++ b/test/tools/javac/diags/examples/EmptyCharLiteral.java	Thu Sep 01 09:14:25 2011 -0700
    10.3 @@ -1,5 +1,5 @@
    10.4  /*
    10.5 - * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
    10.6 + * Copyright (c) 2010, 2011, Oracle and/or its affiliates. All rights reserved.
    10.7   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    10.8   *
    10.9   * This code is free software; you can redistribute it and/or modify it
   10.10 @@ -23,7 +23,6 @@
   10.11  
   10.12  // key: compiler.err.empty.char.lit
   10.13  // key: compiler.err.unclosed.char.lit
   10.14 -// key: compiler.err.expected
   10.15  // key: compiler.err.premature.eof
   10.16  
   10.17  class X {
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/test/tools/javac/parser/netbeans/JavacParserTest.java	Thu Sep 01 09:14:25 2011 -0700
    11.3 @@ -0,0 +1,716 @@
    11.4 +/*
    11.5 + * Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
    11.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
    11.7 + *
    11.8 + * This code is free software; you can redistribute it and/or modify it
    11.9 + * under the terms of the GNU General Public License version 2 only, as
   11.10 + * published by the Free Software Foundation.
   11.11 + *
   11.12 + * This code is distributed in the hope that it will be useful, but WITHOUT
   11.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   11.14 + * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
   11.15 + * version 2 for more details (a copy is included in the LICENSE file that
   11.16 + * accompanied this code).
   11.17 + *
   11.18 + * You should have received a copy of the GNU General Public License version
   11.19 + * 2 along with this work; if not, write to the Free Software Foundation,
   11.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
   11.21 + *
   11.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
   11.23 + * or visit www.oracle.com if you need additional information or have any
   11.24 + * questions.
   11.25 + */
   11.26 +
   11.27 +/*
   11.28 + * @test
   11.29 + * @bug 7073631
   11.30 + * @summary tests error and diagnostics positions
   11.31 + * @author  jan.lahoda@oracle.com
   11.32 + */
   11.33 +
   11.34 +import com.sun.source.tree.BinaryTree;
   11.35 +import com.sun.source.tree.BlockTree;
   11.36 +import com.sun.source.tree.ClassTree;
   11.37 +import com.sun.source.tree.CompilationUnitTree;
   11.38 +import com.sun.source.tree.ExpressionStatementTree;
   11.39 +import com.sun.source.tree.ExpressionTree;
   11.40 +import com.sun.source.tree.MethodInvocationTree;
   11.41 +import com.sun.source.tree.MethodTree;
   11.42 +import com.sun.source.tree.ModifiersTree;
   11.43 +import com.sun.source.tree.StatementTree;
   11.44 +import com.sun.source.tree.Tree;
   11.45 +import com.sun.source.tree.Tree.Kind;
   11.46 +import com.sun.source.tree.VariableTree;
   11.47 +import com.sun.source.tree.WhileLoopTree;
   11.48 +import com.sun.source.util.SourcePositions;
   11.49 +import com.sun.source.util.TreeScanner;
   11.50 +import com.sun.source.util.Trees;
   11.51 +import com.sun.tools.javac.api.JavacTaskImpl;
   11.52 +import com.sun.tools.javac.tree.JCTree;
   11.53 +import java.io.IOException;
   11.54 +import java.net.URI;
   11.55 +import java.util.Arrays;
   11.56 +import java.util.LinkedList;
   11.57 +import java.util.List;
   11.58 +import javax.tools.Diagnostic;
   11.59 +import javax.tools.DiagnosticCollector;
   11.60 +import javax.tools.DiagnosticListener;
   11.61 +import javax.tools.JavaCompiler;
   11.62 +import javax.tools.JavaFileObject;
   11.63 +import javax.tools.SimpleJavaFileObject;
   11.64 +import javax.tools.ToolProvider;
   11.65 +
   11.66 +public class JavacParserTest extends TestCase {
   11.67 +    final JavaCompiler tool;
   11.68 +    public JavacParserTest(String testName) {
   11.69 +        tool = ToolProvider.getSystemJavaCompiler();
   11.70 +        System.out.println("java.home=" + System.getProperty("java.home"));
   11.71 +    }
   11.72 +
   11.73 +    static class MyFileObject extends SimpleJavaFileObject {
   11.74 +
   11.75 +        private String text;
   11.76 +
   11.77 +        public MyFileObject(String text) {
   11.78 +            super(URI.create("myfo:/Test.java"), JavaFileObject.Kind.SOURCE);
   11.79 +            this.text = text;
   11.80 +        }
   11.81 +
   11.82 +        @Override
   11.83 +        public CharSequence getCharContent(boolean ignoreEncodingErrors) {
   11.84 +            return text;
   11.85 +        }
   11.86 +    }
   11.87 +
   11.88 +    public void testPositionForSuperConstructorCalls() throws IOException {
   11.89 +        assert tool != null;
   11.90 +
   11.91 +        String code = "package test; public class Test {public Test() {super();}}";
   11.92 +
   11.93 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
   11.94 +                null, Arrays.asList(new MyFileObject(code)));
   11.95 +        CompilationUnitTree cut = ct.parse().iterator().next();
   11.96 +        SourcePositions pos = Trees.instance(ct).getSourcePositions();
   11.97 +
   11.98 +        MethodTree method =
   11.99 +                (MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0);
  11.100 +        ExpressionStatementTree es =
  11.101 +                (ExpressionStatementTree) method.getBody().getStatements().get(0);
  11.102 +
  11.103 +        assertEquals("testPositionForSuperConstructorCalls",
  11.104 +                72 - 24, pos.getStartPosition(cut, es));
  11.105 +        assertEquals("testPositionForSuperConstructorCalls",
  11.106 +                80 - 24, pos.getEndPosition(cut, es));
  11.107 +
  11.108 +        MethodInvocationTree mit = (MethodInvocationTree) es.getExpression();
  11.109 +
  11.110 +        assertEquals("testPositionForSuperConstructorCalls",
  11.111 +                72 - 24, pos.getStartPosition(cut, mit));
  11.112 +        assertEquals("testPositionForSuperConstructorCalls",
  11.113 +                79 - 24, pos.getEndPosition(cut, mit));
  11.114 +
  11.115 +        assertEquals("testPositionForSuperConstructorCalls",
  11.116 +                72 - 24, pos.getStartPosition(cut, mit.getMethodSelect()));
  11.117 +        assertEquals("testPositionForSuperConstructorCalls",
  11.118 +                77 - 24, pos.getEndPosition(cut, mit.getMethodSelect()));
  11.119 +
  11.120 +    }
  11.121 +
  11.122 +    public void testPositionForEnumModifiers() throws IOException {
  11.123 +
  11.124 +        String code = "package test; public enum Test {A;}";
  11.125 +
  11.126 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.127 +                null, Arrays.asList(new MyFileObject(code)));
  11.128 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.129 +        SourcePositions pos = Trees.instance(ct).getSourcePositions();
  11.130 +
  11.131 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.132 +        ModifiersTree mt = clazz.getModifiers();
  11.133 +
  11.134 +        assertEquals("testPositionForEnumModifiers",
  11.135 +                38 - 24, pos.getStartPosition(cut, mt));
  11.136 +        assertEquals("testPositionForEnumModifiers",
  11.137 +                44 - 24, pos.getEndPosition(cut, mt));
  11.138 +    }
  11.139 +
  11.140 +    public void testNewClassWithEnclosing() throws IOException {
  11.141 +
  11.142 +
  11.143 +        String code = "package test; class Test { " +
  11.144 +                "class d {} private void method() { " +
  11.145 +                "Object o = Test.this.new d(); } }";
  11.146 +
  11.147 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.148 +                null, Arrays.asList(new MyFileObject(code)));
  11.149 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.150 +        SourcePositions pos = Trees.instance(ct).getSourcePositions();
  11.151 +
  11.152 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.153 +        ExpressionTree est =
  11.154 +                ((VariableTree) ((MethodTree) clazz.getMembers().get(1)).getBody().getStatements().get(0)).getInitializer();
  11.155 +
  11.156 +        assertEquals("testNewClassWithEnclosing",
  11.157 +                97 - 24, pos.getStartPosition(cut, est));
  11.158 +        assertEquals("testNewClassWithEnclosing",
  11.159 +                114 - 24, pos.getEndPosition(cut, est));
  11.160 +    }
  11.161 +
  11.162 +    public void testPreferredPositionForBinaryOp() throws IOException {
  11.163 +
  11.164 +        String code = "package test; public class Test {" +
  11.165 +                "private void test() {" +
  11.166 +                "Object o = null; boolean b = o != null && o instanceof String;" +
  11.167 +                "} private Test() {}}";
  11.168 +
  11.169 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.170 +                null, Arrays.asList(new MyFileObject(code)));
  11.171 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.172 +
  11.173 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.174 +        MethodTree method = (MethodTree) clazz.getMembers().get(0);
  11.175 +        VariableTree condSt = (VariableTree) method.getBody().getStatements().get(1);
  11.176 +        BinaryTree cond = (BinaryTree) condSt.getInitializer();
  11.177 +
  11.178 +        JCTree condJC = (JCTree) cond;
  11.179 +
  11.180 +        assertEquals("testNewClassWithEnclosing",
  11.181 +                117 - 24, condJC.pos);
  11.182 +    }
  11.183 +
  11.184 +    public void testPositionBrokenSource126732a() throws IOException {
  11.185 +        String[] commands = new String[]{
  11.186 +            "return Runnable()",
  11.187 +            "do { } while (true)",
  11.188 +            "throw UnsupportedOperationException()",
  11.189 +            "assert true",
  11.190 +            "1 + 1",};
  11.191 +
  11.192 +        for (String command : commands) {
  11.193 +
  11.194 +            String code = "package test;\n"
  11.195 +                    + "public class Test {\n"
  11.196 +                    + "    public static void test() {\n"
  11.197 +                    + "        " + command + " {\n"
  11.198 +                    + "                new Runnable() {\n"
  11.199 +                    + "        };\n"
  11.200 +                    + "    }\n"
  11.201 +                    + "}";
  11.202 +            JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null,
  11.203 +                    null, null, Arrays.asList(new MyFileObject(code)));
  11.204 +            CompilationUnitTree cut = ct.parse().iterator().next();
  11.205 +
  11.206 +            ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.207 +            MethodTree method = (MethodTree) clazz.getMembers().get(0);
  11.208 +            List<? extends StatementTree> statements =
  11.209 +                    method.getBody().getStatements();
  11.210 +
  11.211 +            StatementTree ret = statements.get(0);
  11.212 +            StatementTree block = statements.get(1);
  11.213 +
  11.214 +            Trees t = Trees.instance(ct);
  11.215 +            int len = code.indexOf(command + " {") + (command + " ").length();
  11.216 +            assertEquals(command, len,
  11.217 +                    t.getSourcePositions().getEndPosition(cut, ret));
  11.218 +            assertEquals(command, len,
  11.219 +                    t.getSourcePositions().getStartPosition(cut, block));
  11.220 +        }
  11.221 +    }
  11.222 +
  11.223 +    public void testPositionBrokenSource126732b() throws IOException {
  11.224 +        String[] commands = new String[]{
  11.225 +            "break",
  11.226 +            "break A",
  11.227 +            "continue ",
  11.228 +            "continue A",};
  11.229 +
  11.230 +        for (String command : commands) {
  11.231 +
  11.232 +            String code = "package test;\n"
  11.233 +                    + "public class Test {\n"
  11.234 +                    + "    public static void test() {\n"
  11.235 +                    + "        while (true) {\n"
  11.236 +                    + "            " + command + " {\n"
  11.237 +                    + "                new Runnable() {\n"
  11.238 +                    + "        };\n"
  11.239 +                    + "        }\n"
  11.240 +                    + "    }\n"
  11.241 +                    + "}";
  11.242 +
  11.243 +            JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null,
  11.244 +                    null, null, Arrays.asList(new MyFileObject(code)));
  11.245 +            CompilationUnitTree cut = ct.parse().iterator().next();
  11.246 +
  11.247 +            ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.248 +            MethodTree method = (MethodTree) clazz.getMembers().get(0);
  11.249 +            List<? extends StatementTree> statements =
  11.250 +                    ((BlockTree) ((WhileLoopTree) method.getBody().getStatements().get(0)).getStatement()).getStatements();
  11.251 +
  11.252 +            StatementTree ret = statements.get(0);
  11.253 +            StatementTree block = statements.get(1);
  11.254 +
  11.255 +            Trees t = Trees.instance(ct);
  11.256 +            int len = code.indexOf(command + " {") + (command + " ").length();
  11.257 +            assertEquals(command, len,
  11.258 +                    t.getSourcePositions().getEndPosition(cut, ret));
  11.259 +            assertEquals(command, len,
  11.260 +                    t.getSourcePositions().getStartPosition(cut, block));
  11.261 +        }
  11.262 +    }
  11.263 +
  11.264 +    public void testErrorRecoveryForEnhancedForLoop142381() throws IOException {
  11.265 +
  11.266 +        String code = "package test; class Test { " +
  11.267 +                "private void method() { " +
  11.268 +                "java.util.Set<String> s = null; for (a : s) {} } }";
  11.269 +
  11.270 +        final List<Diagnostic<? extends JavaFileObject>> errors =
  11.271 +                new LinkedList<Diagnostic<? extends JavaFileObject>>();
  11.272 +
  11.273 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null,
  11.274 +                new DiagnosticListener<JavaFileObject>() {
  11.275 +            public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  11.276 +                errors.add(diagnostic);
  11.277 +            }
  11.278 +        }, null, null, Arrays.asList(new MyFileObject(code)));
  11.279 +
  11.280 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.281 +
  11.282 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.283 +        StatementTree forStatement =
  11.284 +                ((MethodTree) clazz.getMembers().get(0)).getBody().getStatements().get(1);
  11.285 +
  11.286 +        assertEquals("testErrorRecoveryForEnhancedForLoop142381",
  11.287 +                Kind.ENHANCED_FOR_LOOP, forStatement.getKind());
  11.288 +        assertFalse("testErrorRecoveryForEnhancedForLoop142381", errors.isEmpty());
  11.289 +    }
  11.290 +
  11.291 +    public void testPositionAnnotationNoPackage187551() throws IOException {
  11.292 +
  11.293 +        String code = "\n@interface Test {}";
  11.294 +
  11.295 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.296 +                null, Arrays.asList(new MyFileObject(code)));
  11.297 +
  11.298 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.299 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.300 +        Trees t = Trees.instance(ct);
  11.301 +
  11.302 +        assertEquals("testPositionAnnotationNoPackage187551",
  11.303 +                1, t.getSourcePositions().getStartPosition(cut, clazz));
  11.304 +    }
  11.305 +
  11.306 +    public void testPositionsSane() throws IOException {
  11.307 +        performPositionsSanityTest("package test; class Test { " +
  11.308 +                "private void method() { " +
  11.309 +                "java.util.List<? extends java.util.List<? extends String>> l; " +
  11.310 +                "} }");
  11.311 +        performPositionsSanityTest("package test; class Test { " +
  11.312 +                "private void method() { " +
  11.313 +                "java.util.List<? super java.util.List<? super String>> l; " +
  11.314 +                "} }");
  11.315 +        performPositionsSanityTest("package test; class Test { " +
  11.316 +                "private void method() { " +
  11.317 +                "java.util.List<? super java.util.List<?>> l; } }");
  11.318 +    }
  11.319 +
  11.320 +    private void performPositionsSanityTest(String code) throws IOException {
  11.321 +
  11.322 +        final List<Diagnostic<? extends JavaFileObject>> errors =
  11.323 +                new LinkedList<Diagnostic<? extends JavaFileObject>>();
  11.324 +
  11.325 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null,
  11.326 +                new DiagnosticListener<JavaFileObject>() {
  11.327 +
  11.328 +            public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  11.329 +                errors.add(diagnostic);
  11.330 +            }
  11.331 +        }, null, null, Arrays.asList(new MyFileObject(code)));
  11.332 +
  11.333 +        final CompilationUnitTree cut = ct.parse().iterator().next();
  11.334 +        final Trees trees = Trees.instance(ct);
  11.335 +
  11.336 +        new TreeScanner<Void, Void>() {
  11.337 +
  11.338 +            private long parentStart = 0;
  11.339 +            private long parentEnd = Integer.MAX_VALUE;
  11.340 +
  11.341 +            @Override
  11.342 +            public Void scan(Tree node, Void p) {
  11.343 +                if (node == null) {
  11.344 +                    return null;
  11.345 +                }
  11.346 +
  11.347 +                long start = trees.getSourcePositions().getStartPosition(cut, node);
  11.348 +
  11.349 +                if (start == (-1)) {
  11.350 +                    return null; //synthetic tree
  11.351 +                }
  11.352 +                assertTrue(node.toString() + ":" + start + "/" + parentStart,
  11.353 +                        parentStart <= start);
  11.354 +
  11.355 +                long prevParentStart = parentStart;
  11.356 +
  11.357 +                parentStart = start;
  11.358 +
  11.359 +                long end = trees.getSourcePositions().getEndPosition(cut, node);
  11.360 +
  11.361 +                assertTrue(node.toString() + ":" + end + "/" + parentEnd,
  11.362 +                        end <= parentEnd);
  11.363 +
  11.364 +                long prevParentEnd = parentEnd;
  11.365 +
  11.366 +                parentEnd = end;
  11.367 +
  11.368 +                super.scan(node, p);
  11.369 +
  11.370 +                parentStart = prevParentStart;
  11.371 +                parentEnd = prevParentEnd;
  11.372 +
  11.373 +                return null;
  11.374 +            }
  11.375 +
  11.376 +            private void assertTrue(String message, boolean b) {
  11.377 +                if (!b) fail(message);
  11.378 +            }
  11.379 +        }.scan(cut, null);
  11.380 +    }
  11.381 +
  11.382 +    public void testCorrectWilcardPositions() throws IOException {
  11.383 +        performWildcardPositionsTest("package test; import java.util.List; " +
  11.384 +                "class Test { private void method() { List<? extends List<? extends String>> l; } }",
  11.385 +
  11.386 +                Arrays.asList("List<? extends List<? extends String>> l;",
  11.387 +                "List<? extends List<? extends String>>",
  11.388 +                "List",
  11.389 +                "? extends List<? extends String>",
  11.390 +                "List<? extends String>",
  11.391 +                "List",
  11.392 +                "? extends String",
  11.393 +                "String"));
  11.394 +        performWildcardPositionsTest("package test; import java.util.List; " +
  11.395 +                "class Test { private void method() { List<? super List<? super String>> l; } }",
  11.396 +
  11.397 +                Arrays.asList("List<? super List<? super String>> l;",
  11.398 +                "List<? super List<? super String>>",
  11.399 +                "List",
  11.400 +                "? super List<? super String>",
  11.401 +                "List<? super String>",
  11.402 +                "List",
  11.403 +                "? super String",
  11.404 +                "String"));
  11.405 +        performWildcardPositionsTest("package test; import java.util.List; " +
  11.406 +                "class Test { private void method() { List<? super List<?>> l; } }",
  11.407 +
  11.408 +                Arrays.asList("List<? super List<?>> l;",
  11.409 +                "List<? super List<?>>",
  11.410 +                "List",
  11.411 +                "? super List<?>",
  11.412 +                "List<?>",
  11.413 +                "List",
  11.414 +                "?"));
  11.415 +        performWildcardPositionsTest("package test; import java.util.List; " +
  11.416 +                "class Test { private void method() { " +
  11.417 +                "List<? extends List<? extends List<? extends String>>> l; } }",
  11.418 +
  11.419 +                Arrays.asList("List<? extends List<? extends List<? extends String>>> l;",
  11.420 +                "List<? extends List<? extends List<? extends String>>>",
  11.421 +                "List",
  11.422 +                "? extends List<? extends List<? extends String>>",
  11.423 +                "List<? extends List<? extends String>>",
  11.424 +                "List",
  11.425 +                "? extends List<? extends String>",
  11.426 +                "List<? extends String>",
  11.427 +                "List",
  11.428 +                "? extends String",
  11.429 +                "String"));
  11.430 +        performWildcardPositionsTest("package test; import java.util.List; " +
  11.431 +                "class Test { private void method() { " +
  11.432 +                "List<? extends List<? extends List<? extends String   >>> l; } }",
  11.433 +                Arrays.asList("List<? extends List<? extends List<? extends String   >>> l;",
  11.434 +                "List<? extends List<? extends List<? extends String   >>>",
  11.435 +                "List",
  11.436 +                "? extends List<? extends List<? extends String   >>",
  11.437 +                "List<? extends List<? extends String   >>",
  11.438 +                "List",
  11.439 +                "? extends List<? extends String   >",
  11.440 +                "List<? extends String   >",
  11.441 +                "List",
  11.442 +                "? extends String",
  11.443 +                "String"));
  11.444 +    }
  11.445 +
  11.446 +    public void performWildcardPositionsTest(final String code,
  11.447 +            List<String> golden) throws IOException {
  11.448 +
  11.449 +        final List<Diagnostic<? extends JavaFileObject>> errors =
  11.450 +                new LinkedList<Diagnostic<? extends JavaFileObject>>();
  11.451 +
  11.452 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null,
  11.453 +                new DiagnosticListener<JavaFileObject>() {
  11.454 +                    public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
  11.455 +                        errors.add(diagnostic);
  11.456 +                    }
  11.457 +                }, null, null, Arrays.asList(new MyFileObject(code)));
  11.458 +
  11.459 +        final CompilationUnitTree cut = ct.parse().iterator().next();
  11.460 +        final List<String> content = new LinkedList<String>();
  11.461 +        final Trees trees = Trees.instance(ct);
  11.462 +
  11.463 +        new TreeScanner<Void, Void>() {
  11.464 +            @Override
  11.465 +            public Void scan(Tree node, Void p) {
  11.466 +                if (node == null) {
  11.467 +                    return null;
  11.468 +                }
  11.469 +                long start = trees.getSourcePositions().getStartPosition(cut, node);
  11.470 +
  11.471 +                if (start == (-1)) {
  11.472 +                    return null; //synthetic tree
  11.473 +                }
  11.474 +                long end = trees.getSourcePositions().getEndPosition(cut, node);
  11.475 +                String s = code.substring((int) start, (int) end);
  11.476 +                content.add(s);
  11.477 +
  11.478 +                return super.scan(node, p);
  11.479 +            }
  11.480 +        }.scan(((MethodTree) ((ClassTree) cut.getTypeDecls().get(0)).getMembers().get(0)).getBody().getStatements().get(0), null);
  11.481 +
  11.482 +        assertEquals("performWildcardPositionsTest",golden.toString(),
  11.483 +                content.toString());
  11.484 +    }
  11.485 +
  11.486 +    public void testStartPositionForMethodWithoutModifiers() throws IOException {
  11.487 +
  11.488 +        String code = "package t; class Test { <T> void t() {} }";
  11.489 +
  11.490 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.491 +                null, Arrays.asList(new MyFileObject(code)));
  11.492 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.493 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.494 +        MethodTree mt = (MethodTree) clazz.getMembers().get(0);
  11.495 +        Trees t = Trees.instance(ct);
  11.496 +        int start = (int) t.getSourcePositions().getStartPosition(cut, mt);
  11.497 +        int end = (int) t.getSourcePositions().getEndPosition(cut, mt);
  11.498 +
  11.499 +        assertEquals("testStartPositionForMethodWithoutModifiers",
  11.500 +                "<T> void t() {}", code.substring(start, end));
  11.501 +    }
  11.502 +
  11.503 +    public void testStartPositionEnumConstantInit() throws IOException {
  11.504 +
  11.505 +        String code = "package t; enum Test { AAA; }";
  11.506 +
  11.507 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.508 +                null, Arrays.asList(new MyFileObject(code)));
  11.509 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.510 +        ClassTree clazz = (ClassTree) cut.getTypeDecls().get(0);
  11.511 +        VariableTree enumAAA = (VariableTree) clazz.getMembers().get(0);
  11.512 +        Trees t = Trees.instance(ct);
  11.513 +        int start = (int) t.getSourcePositions().getStartPosition(cut,
  11.514 +                enumAAA.getInitializer());
  11.515 +
  11.516 +        assertEquals("testStartPositionEnumConstantInit", -1, start);
  11.517 +    }
  11.518 +
  11.519 +    public void testVariableInIfThen1() throws IOException {
  11.520 +
  11.521 +        String code = "package t; class Test { " +
  11.522 +                "private static void t(String name) { " +
  11.523 +                "if (name != null) String nn = name.trim(); } }";
  11.524 +
  11.525 +        DiagnosticCollector<JavaFileObject> coll =
  11.526 +                new DiagnosticCollector<JavaFileObject>();
  11.527 +
  11.528 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
  11.529 +                null, Arrays.asList(new MyFileObject(code)));
  11.530 +
  11.531 +        ct.parse();
  11.532 +
  11.533 +        List<String> codes = new LinkedList<String>();
  11.534 +
  11.535 +        for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
  11.536 +            codes.add(d.getCode());
  11.537 +        }
  11.538 +
  11.539 +        assertEquals("testVariableInIfThen1",
  11.540 +                Arrays.<String>asList("compiler.err.variable.not.allowed"),
  11.541 +                codes);
  11.542 +    }
  11.543 +
  11.544 +    public void testVariableInIfThen2() throws IOException {
  11.545 +
  11.546 +        String code = "package t; class Test { " +
  11.547 +                "private static void t(String name) { " +
  11.548 +                "if (name != null) class X {} } }";
  11.549 +        DiagnosticCollector<JavaFileObject> coll =
  11.550 +                new DiagnosticCollector<JavaFileObject>();
  11.551 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
  11.552 +                null, Arrays.asList(new MyFileObject(code)));
  11.553 +
  11.554 +        ct.parse();
  11.555 +
  11.556 +        List<String> codes = new LinkedList<String>();
  11.557 +
  11.558 +        for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
  11.559 +            codes.add(d.getCode());
  11.560 +        }
  11.561 +
  11.562 +        assertEquals("testVariableInIfThen2",
  11.563 +                Arrays.<String>asList("compiler.err.class.not.allowed"), codes);
  11.564 +    }
  11.565 +
  11.566 +    public void testVariableInIfThen3() throws IOException {
  11.567 +
  11.568 +        String code = "package t; class Test { "+
  11.569 +                "private static void t(String name) { " +
  11.570 +                "if (name != null) abstract } }";
  11.571 +        DiagnosticCollector<JavaFileObject> coll =
  11.572 +                new DiagnosticCollector<JavaFileObject>();
  11.573 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, coll, null,
  11.574 +                null, Arrays.asList(new MyFileObject(code)));
  11.575 +
  11.576 +        ct.parse();
  11.577 +
  11.578 +        List<String> codes = new LinkedList<String>();
  11.579 +
  11.580 +        for (Diagnostic<? extends JavaFileObject> d : coll.getDiagnostics()) {
  11.581 +            codes.add(d.getCode());
  11.582 +        }
  11.583 +
  11.584 +        assertEquals("testVariableInIfThen3",
  11.585 +                Arrays.<String>asList("compiler.err.illegal.start.of.expr"),
  11.586 +                codes);
  11.587 +    }
  11.588 +
  11.589 +    //see javac bug #6882235, NB bug #98234:
  11.590 +    public void testMissingExponent() throws IOException {
  11.591 +
  11.592 +        String code = "\nclass Test { { System.err.println(0e); } }";
  11.593 +
  11.594 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.595 +                null, Arrays.asList(new MyFileObject(code)));
  11.596 +
  11.597 +        assertNotNull(ct.parse().iterator().next());
  11.598 +    }
  11.599 +
  11.600 +    public void testTryResourcePos() throws IOException {
  11.601 +
  11.602 +        final String code = "package t; class Test { " +
  11.603 +                "{ try (java.io.InputStream in = null) { } } }";
  11.604 +
  11.605 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.606 +                null, Arrays.asList(new MyFileObject(code)));
  11.607 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.608 +
  11.609 +        new TreeScanner<Void, Void>() {
  11.610 +            @Override
  11.611 +            public Void visitVariable(VariableTree node, Void p) {
  11.612 +                if ("in".contentEquals(node.getName())) {
  11.613 +                    JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node;
  11.614 +                    System.out.println(node.getName() + "," + var.pos);
  11.615 +                    assertEquals("testTryResourcePos", "in = null) { } } }",
  11.616 +                            code.substring(var.pos));
  11.617 +                }
  11.618 +                return super.visitVariable(node, p);
  11.619 +            }
  11.620 +        }.scan(cut, null);
  11.621 +    }
  11.622 +
  11.623 +    public void testVarPos() throws IOException {
  11.624 +
  11.625 +        final String code = "package t; class Test { " +
  11.626 +                "{ java.io.InputStream in = null; } }";
  11.627 +
  11.628 +        JavacTaskImpl ct = (JavacTaskImpl) tool.getTask(null, null, null, null,
  11.629 +                null, Arrays.asList(new MyFileObject(code)));
  11.630 +        CompilationUnitTree cut = ct.parse().iterator().next();
  11.631 +
  11.632 +        new TreeScanner<Void, Void>() {
  11.633 +
  11.634 +            @Override
  11.635 +            public Void visitVariable(VariableTree node, Void p) {
  11.636 +                if ("in".contentEquals(node.getName())) {
  11.637 +                    JCTree.JCVariableDecl var = (JCTree.JCVariableDecl) node;
  11.638 +                    assertEquals("testVarPos","in = null; } }",
  11.639 +                            code.substring(var.pos));
  11.640 +                }
  11.641 +                return super.visitVariable(node, p);
  11.642 +            }
  11.643 +        }.scan(cut, null);
  11.644 +    }
  11.645 +
  11.646 +    void testsNotWorking() throws IOException {
  11.647 +
  11.648 +        // Fails with nb-javac, needs further investigation
  11.649 +        testPositionBrokenSource126732a();
  11.650 +        testPositionBrokenSource126732b();
  11.651 +
  11.652 +        // Fails, these tests yet to be addressed
  11.653 +        testVariableInIfThen1();
  11.654 +        testVariableInIfThen2();
  11.655 +        testPositionForEnumModifiers();
  11.656 +        testStartPositionEnumConstantInit();
  11.657 +    }
  11.658 +    void testPositions() throws IOException {
  11.659 +        testPositionsSane();
  11.660 +        testCorrectWilcardPositions();
  11.661 +        testPositionAnnotationNoPackage187551();
  11.662 +        testPositionForSuperConstructorCalls();
  11.663 +        testPreferredPositionForBinaryOp();
  11.664 +        testStartPositionForMethodWithoutModifiers();
  11.665 +        testVarPos();
  11.666 +        testVariableInIfThen3();
  11.667 +        testTryResourcePos();
  11.668 +    }
  11.669 +
  11.670 +    public static void main(String... args) throws IOException {
  11.671 +        JavacParserTest jpt = new JavacParserTest("JavacParserTest");
  11.672 +        jpt.testPositions();
  11.673 +        System.out.println("PASS");
  11.674 +    }
  11.675 +}
  11.676 +
  11.677 +abstract class TestCase {
  11.678 +
  11.679 +    void assertEquals(String message, int i, int pos) {
  11.680 +        if (i != pos) {
  11.681 +            fail(message);
  11.682 +        }
  11.683 +    }
  11.684 +
  11.685 +    void assertFalse(String message, boolean empty) {
  11.686 +        throw new UnsupportedOperationException("Not yet implemented");
  11.687 +    }
  11.688 +
  11.689 +    void assertEquals(String message, int i, long l) {
  11.690 +        if (i != l) {
  11.691 +            fail(message + ":" + i + ":" + l);
  11.692 +        }
  11.693 +    }
  11.694 +
  11.695 +    void assertEquals(String message, Object o1, Object o2) {
  11.696 +        System.out.println(o1);
  11.697 +        System.out.println(o2);
  11.698 +        if (o1 != null && o2 != null && !o1.equals(o2)) {
  11.699 +            fail(message);
  11.700 +        }
  11.701 +        if (o1 == null && o2 != null) {
  11.702 +            fail(message);
  11.703 +        }
  11.704 +    }
  11.705 +
  11.706 +    void assertNotNull(Object o) {
  11.707 +        if (o == null) {
  11.708 +            fail();
  11.709 +        }
  11.710 +    }
  11.711 +
  11.712 +    void fail() {
  11.713 +        fail("test failed");
  11.714 +    }
  11.715 +
  11.716 +    void fail(String message) {
  11.717 +        throw new RuntimeException(message);
  11.718 +    }
  11.719 +}

mercurial